Terraria ModLoader  0.11.7.7
A mod to make and play Terraria mods
Terraria.ModLoader.Logging Class Reference
+ Collaboration diagram for Terraria.ModLoader.Logging:

Static Public Member Functions

static void IgnoreExceptionContents (string source)
 
static void IgnoreExceptionSource (string source)
 
static void PrettifyStackTraceSources (StackFrame[] frames)
 

Static Public Attributes

static readonly string LogArchiveDir = Path.Combine(LogDir, "Old")
 
static readonly string LogDir = Path.Combine(Program.SavePath, "Logs")
 

Properties

static string LogPath [get, private set]
 

Static Private Member Functions

static void AddChatMessage (string msg, Color color)
 
static bool CanOpen (string fileName)
 
static void ConfigureAppenders ()
 
static void EnablePortablePDBTraces ()
 
static void FirstChanceExceptionHandler (object sender, FirstChanceExceptionEventArgs args)
 
static string GetNewLogFile (string baseName)
 
static void LogFirstChanceExceptions ()
 

Static Private Attributes

static ThreadLocal< bool > handlerActive = new ThreadLocal<bool>(() => false)
 
static List< string > ignoreContents
 
static List< string > ignoreMessages
 
static HashSet< string > ignoreSources
 
static List< string > ignoreThrowingMethods
 
static List< string > initWarnings = new List<string>()
 
static HashSet< string > pastExceptions = new HashSet<string>()
 
static Exception previousException
 
static Regex statusRegex = new Regex(@"(.+?)[: \d]*%$")
 
static readonly Assembly TerrariaAssembly = Assembly.GetExecutingAssembly()
 

Detailed Description

Definition at line 23 of file Logging.cs.

Member Function Documentation

static void Terraria.ModLoader.Logging.AddChatMessage ( string  msg,
Color  color 
)
staticprivate

Definition at line 256 of file Logging.cs.

256  {
257  if (Main.gameMenu)
258  return;
259 
260  float soundVolume = Main.soundVolume;
261  Main.soundVolume = 0f;
262  Main.NewText(msg, color);
263  Main.soundVolume = soundVolume;
264  }
static bool Terraria.ModLoader.Logging.CanOpen ( string  fileName)
staticprivate

Definition at line 128 of file Logging.cs.

128  {
129  try {
130  using (new FileStream(fileName, FileMode.Append)) ;
131  return true;
132  }
133  catch (IOException) {
134  return false;
135  }
136  }
static void Terraria.ModLoader.Logging.ConfigureAppenders ( )
staticprivate

Definition at line 68 of file Logging.cs.

68  {
69  var layout = new PatternLayout {
70  ConversionPattern = "[%d{HH:mm:ss}] [%t/%level] [%logger]: %m%n"
71  };
72  layout.ActivateOptions();
73 
74  var appenders = new List<IAppender>();
75 #if CLIENT
76  appenders.Add(new ConsoleAppender {
77  Name = "ConsoleAppender",
78  Layout = layout
79  });
80 #endif
81  appenders.Add(new DebugAppender {
82  Name = "DebugAppender",
83  Layout = layout
84  });
85 
86  var fileAppender = new FileAppender {
87  Name = "FileAppender",
88  File = LogPath = Path.Combine(LogDir, GetNewLogFile(side)),
89  AppendToFile = false,
90  Encoding = Encoding.UTF8,
91  Layout = layout
92  };
93  fileAppender.ActivateOptions();
94  appenders.Add(fileAppender);
95 
96  BasicConfigurator.Configure(appenders.ToArray());
97  }
static string LogPath
Definition: Logging.cs:27
static readonly string LogDir
Definition: Logging.cs:25
static string GetNewLogFile(string baseName)
Definition: Logging.cs:99
static void Terraria.ModLoader.Logging.EnablePortablePDBTraces ( )
staticprivate

Definition at line 320 of file Logging.cs.

References Terraria.ModLoader.FrameworkVersion.Framework, and Terraria.ModLoader.FrameworkVersion.Version.

320  {
321  if (FrameworkVersion.Framework == Framework.NetFramework && FrameworkVersion.Version >= new Version(4, 7, 2))
322  Type.GetType("System.AppContextSwitches").GetField("_ignorePortablePDBsInStackTraces", BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, -1);
323  }
static void Terraria.ModLoader.Logging.FirstChanceExceptionHandler ( object  sender,
FirstChanceExceptionEventArgs  args 
)
staticprivate

Definition at line 188 of file Logging.cs.

References Terraria.ModLoader.Console, and Terraria.ModLoader.Environment.

188  {
189  if (handlerActive.Value)
190  return;
191 
192  bool oom = args.Exception is OutOfMemoryException;
193 
194  //In case of OOM, unload the Main.tile array and do immediate garbage collection.
195  //If we don't do this, there will be a big chance that this method will fail to even quit the game, due to another OOM exception being thrown.
196  if (oom) {
197  Main.tile = null;
198 
199  GC.Collect();
200  }
201 
202  try {
203  handlerActive.Value = true;
204 
205  if (!oom) {
206  if (args.Exception == previousException ||
207  args.Exception is ThreadAbortException ||
208  ignoreSources.Contains(args.Exception.Source) ||
209  ignoreMessages.Any(str => args.Exception.Message?.Contains(str) ?? false) ||
210  ignoreThrowingMethods.Any(str => args.Exception.StackTrace?.Contains(str) ?? false))
211  return;
212  }
213 
214  var stackTrace = new StackTrace(true);
215  PrettifyStackTraceSources(stackTrace.GetFrames());
216  var traceString = stackTrace.ToString();
217 
218  if (!oom && ignoreContents.Any(traceString.Contains))
219  return;
220 
221  traceString = traceString.Substring(traceString.IndexOf('\n'));
222  var exString = args.Exception.GetType() + ": " + args.Exception.Message + traceString;
223  lock (pastExceptions) {
224  if (!pastExceptions.Add(exString))
225  return;
226  }
227 
228  previousException = args.Exception;
229  var msg = args.Exception.Message + " " + Language.GetTextValue("tModLoader.RuntimeErrorSeeLogsForFullTrace", Path.GetFileName(LogPath));
230  #if CLIENT
231  if (ModCompile.activelyModding)
232  AddChatMessage(msg, Color.OrangeRed);
233  #else
234  Console.ForegroundColor = ConsoleColor.DarkMagenta;
235  Console.WriteLine(msg);
236  Console.ResetColor();
237  #endif
238  tML.Warn(Language.GetTextValue("tModLoader.RuntimeErrorSilentlyCaughtException") + '\n' + exString);
239 
240  if (oom) {
241  string error = Language.GetTextValue("tModLoader.OutOfMemory");
242  Logging.tML.Fatal(error);
243  Interface.MessageBoxShow(error);
244  Environment.Exit(1);
245  }
246  }
247  catch (Exception e) {
248  tML.Warn("FirstChanceExceptionHandler exception", e);
249  }
250  finally {
251  handlerActive.Value = false;
252  }
253  }
static string LogPath
Definition: Logging.cs:27
static List< string > ignoreContents
Definition: Logging.cs:153
static ThreadLocal< bool > handlerActive
Definition: Logging.cs:186
static void PrettifyStackTraceSources(StackFrame[] frames)
Definition: Logging.cs:294
static List< string > ignoreThrowingMethods
Definition: Logging.cs:176
static List< string > ignoreMessages
Definition: Logging.cs:166
Command can be used in server console during MP.
static HashSet< string > ignoreSources
Definition: Logging.cs:148
static HashSet< string > pastExceptions
Definition: Logging.cs:145
static Exception previousException
Definition: Logging.cs:187
static void AddChatMessage(string msg, Color color)
Definition: Logging.cs:256
Sandstorm, Hell, Above surface during Eclipse, Space
static string Terraria.ModLoader.Logging.GetNewLogFile ( string  baseName)
staticprivate

Definition at line 99 of file Logging.cs.

99  {
100  var pattern = new Regex($"{baseName}(\\d*)\\.log$");
101  var existingLogs = Directory.GetFiles(LogDir).Where(s => pattern.IsMatch(Path.GetFileName(s))).ToList();
102 
103  if (!existingLogs.All(CanOpen)) {
104  int n = existingLogs.Select(s => {
105  var tok = pattern.Match(Path.GetFileName(s)).Groups[1].Value;
106  return tok.Length == 0 ? 1 : int.Parse(tok);
107  }).Max();
108  return $"{baseName}{n + 1}.log";
109  }
110 
111  foreach (var existingLog in existingLogs.OrderBy(File.GetCreationTime)) {
112  var oldExt = ".old";
113  int n = 0;
114  while (File.Exists(existingLog + oldExt))
115  oldExt = $".old{++n}";
116 
117  try {
118  File.Move(existingLog, existingLog + oldExt);
119  }
120  catch (IOException e) {
121  initWarnings.Add($"Move failed during log initialization: {existingLog} -> {Path.GetFileName(existingLog)}{oldExt}\n{e}");
122  }
123  }
124 
125  return $"{baseName}.log";
126  }
static readonly string LogDir
Definition: Logging.cs:25
static bool CanOpen(string fileName)
Definition: Logging.cs:128
static List< string > initWarnings
Definition: Logging.cs:38
static void Terraria.ModLoader.Logging.IgnoreExceptionContents ( string  source)
static

Definition at line 181 of file Logging.cs.

181  {
182  if (!ignoreContents.Contains(source))
183  ignoreContents.Add(source);
184  }
static List< string > ignoreContents
Definition: Logging.cs:153
static void Terraria.ModLoader.Logging.IgnoreExceptionSource ( string  source)
static
static void Terraria.ModLoader.Logging.LogFirstChanceExceptions ( )
staticprivate

Definition at line 138 of file Logging.cs.

References Terraria.ModLoader.FrameworkVersion.Framework.

138  {
139  if (FrameworkVersion.Framework == Framework.Mono)
140  tML.Warn("First-chance exception reporting is not implemented on Mono");
141 
142  AppDomain.CurrentDomain.FirstChanceException += FirstChanceExceptionHandler;
143  }
static void FirstChanceExceptionHandler(object sender, FirstChanceExceptionEventArgs args)
Definition: Logging.cs:188
static void Terraria.ModLoader.Logging.PrettifyStackTraceSources ( StackFrame[]  frames)
static

Definition at line 294 of file Logging.cs.

294  {
295  if (frames == null)
296  return;
297 
298  foreach (var frame in frames) {
299  string filename = frame.GetFileName();
300  var assembly = frame.GetMethod()?.DeclaringType?.Assembly;
301  if (filename == null || assembly == null)
302  continue;
303 
304  string trim;
305  if (AssemblyManager.GetAssemblyOwner(assembly, out var modName))
306  trim = modName;
307  else if (assembly == TerrariaAssembly)
308  trim = "tModLoader";
309  else
310  continue;
311 
312  int idx = filename.LastIndexOf(trim, StringComparison.InvariantCultureIgnoreCase);
313  if (idx > 0) {
314  filename = filename.Substring(idx);
315  f_fileName.SetValue(frame, filename);
316  }
317  }
318  }
static readonly Assembly TerrariaAssembly
Definition: Logging.cs:292

Member Data Documentation

ThreadLocal<bool> Terraria.ModLoader.Logging.handlerActive = new ThreadLocal<bool>(() => false)
staticprivate

Definition at line 186 of file Logging.cs.

List<string> Terraria.ModLoader.Logging.ignoreContents
staticprivate
Initial value:
= new List<string> {
"System.Console.set_OutputEncoding",
"Terraria.ModLoader.Core.ModCompile",
"Delegate.CreateDelegateNoSecurityCheck",
"MethodBase.GetMethodBody",
"Terraria.Net.Sockets.TcpSocket.Terraria.Net.Sockets.ISocket.AsyncSend",
"System.Diagnostics.Process.Kill",
"Terraria.ModLoader.Core.AssemblyManager.CecilAssemblyResolver.Resolve",
"Terraria.ModLoader.Engine.TMLContentManager.OpenStream"
}

Definition at line 153 of file Logging.cs.

List<string> Terraria.ModLoader.Logging.ignoreMessages
staticprivate
Initial value:
= new List<string> {
"A blocking operation was interrupted by a call to WSACancelBlockingCall",
"The request was aborted: The request was canceled.",
"Object name: 'System.Net.Sockets.Socket'.",
"Object name: 'System.Net.Sockets.NetworkStream'",
"This operation cannot be performed on a completed asynchronous result object.",
"Object name: 'SslStream'.",
"Unable to load DLL 'Microsoft.DiaSymReader.Native.x86.dll'"
}

Definition at line 166 of file Logging.cs.

HashSet<string> Terraria.ModLoader.Logging.ignoreSources
staticprivate
Initial value:
= new HashSet<string> {
"MP3Sharp"
}

Definition at line 148 of file Logging.cs.

List<string> Terraria.ModLoader.Logging.ignoreThrowingMethods
staticprivate
Initial value:
= new List<string> {
"at Terraria.Lighting.doColors_Mode",
"System.Threading.CancellationToken.Throw",
}

Definition at line 176 of file Logging.cs.

List<string> Terraria.ModLoader.Logging.initWarnings = new List<string>()
staticprivate

Definition at line 38 of file Logging.cs.

readonly string Terraria.ModLoader.Logging.LogArchiveDir = Path.Combine(LogDir, "Old")
static

Definition at line 26 of file Logging.cs.

readonly string Terraria.ModLoader.Logging.LogDir = Path.Combine(Program.SavePath, "Logs")
static

Definition at line 25 of file Logging.cs.

Referenced by Terraria.ModLoader.ErrorLogger.ClearLogs().

HashSet<string> Terraria.ModLoader.Logging.pastExceptions = new HashSet<string>()
staticprivate

Definition at line 145 of file Logging.cs.

Exception Terraria.ModLoader.Logging.previousException
staticprivate

Definition at line 187 of file Logging.cs.

Regex Terraria.ModLoader.Logging.statusRegex = new Regex(@"(.+?)[: \d]*%$")
staticprivate

Definition at line 266 of file Logging.cs.

readonly Assembly Terraria.ModLoader.Logging.TerrariaAssembly = Assembly.GetExecutingAssembly()
staticprivate

Definition at line 292 of file Logging.cs.

Property Documentation

string Terraria.ModLoader.Logging.LogPath
staticgetprivate set

Definition at line 27 of file Logging.cs.