Terraria ModLoader  0.11.5
A framework for 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 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 22 of file Logging.cs.

Member Function Documentation

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

Definition at line 234 of file Logging.cs.

234  {
235  if (Main.gameMenu)
236  return;
237 
238  float soundVolume = Main.soundVolume;
239  Main.soundVolume = 0f;
240  Main.NewText(msg, color);
241  Main.soundVolume = soundVolume;
242  }
static bool Terraria.ModLoader.Logging.CanOpen ( string  fileName)
staticprivate

Definition at line 126 of file Logging.cs.

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

Definition at line 66 of file Logging.cs.

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

Definition at line 298 of file Logging.cs.

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

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

Definition at line 185 of file Logging.cs.

References Terraria.ModLoader.Console.

185  {
186  if (handlerActive.Value)
187  return;
188 
189  try {
190  handlerActive.Value = true;
191 
192  if (args.Exception == previousException ||
193  args.Exception is ThreadAbortException ||
194  ignoreSources.Contains(args.Exception.Source) ||
195  ignoreMessages.Any(str => args.Exception.Message?.Contains(str) ?? false) ||
196  ignoreThrowingMethods.Any(str => args.Exception.StackTrace?.Contains(str) ?? false))
197  return;
198 
199  var stackTrace = new StackTrace(true);
200  PrettifyStackTraceSources(stackTrace.GetFrames());
201  var traceString = stackTrace.ToString();
202 
203  if (ignoreContents.Any(traceString.Contains))
204  return;
205 
206  traceString = traceString.Substring(traceString.IndexOf('\n'));
207  var exString = args.Exception.GetType() + ": " + args.Exception.Message + traceString;
208  lock (pastExceptions) {
209  if (!pastExceptions.Add(exString))
210  return;
211  }
212 
213  previousException = args.Exception;
214  var msg = args.Exception.Message + " " + Language.GetTextValue("tModLoader.RuntimeErrorSeeLogsForFullTrace", Path.GetFileName(LogPath));
215  #if CLIENT
216  if (ModCompile.activelyModding)
217  AddChatMessage(msg, Color.OrangeRed);
218  #else
219  Console.ForegroundColor = ConsoleColor.DarkMagenta;
220  Console.WriteLine(msg);
221  Console.ResetColor();
222  #endif
223  tML.Warn(Language.GetTextValue("tModLoader.RuntimeErrorSilentlyCaughtException") + '\n' + exString);
224  }
225  catch (Exception e) {
226  tML.Warn("FirstChanceExceptionHandler exception", e);
227  }
228  finally {
229  handlerActive.Value = false;
230  }
231  }
static string LogPath
Definition: Logging.cs:25
static List< string > ignoreContents
Definition: Logging.cs:151
static ThreadLocal< bool > handlerActive
Definition: Logging.cs:183
static void PrettifyStackTraceSources(StackFrame[] frames)
Definition: Logging.cs:272
static List< string > ignoreThrowingMethods
Definition: Logging.cs:173
static List< string > ignoreMessages
Definition: Logging.cs:163
Command can be used in server console during MP.
static HashSet< string > ignoreSources
Definition: Logging.cs:146
static HashSet< string > pastExceptions
Definition: Logging.cs:143
static Exception previousException
Definition: Logging.cs:184
static void AddChatMessage(string msg, Color color)
Definition: Logging.cs:234
static string Terraria.ModLoader.Logging.GetNewLogFile ( string  baseName)
staticprivate

Definition at line 97 of file Logging.cs.

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

Definition at line 178 of file Logging.cs.

178  {
179  if (!ignoreContents.Contains(source))
180  ignoreContents.Add(source);
181  }
static List< string > ignoreContents
Definition: Logging.cs:151
static void Terraria.ModLoader.Logging.IgnoreExceptionSource ( string  source)
static
static void Terraria.ModLoader.Logging.LogFirstChanceExceptions ( )
staticprivate

Definition at line 136 of file Logging.cs.

References Terraria.ModLoader.FrameworkVersion.Framework.

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

Definition at line 272 of file Logging.cs.

272  {
273  if (frames == null)
274  return;
275 
276  foreach (var frame in frames) {
277  string filename = frame.GetFileName();
278  var assembly = frame.GetMethod()?.DeclaringType?.Assembly;
279  if (filename == null || assembly == null)
280  continue;
281 
282  string trim;
283  if (AssemblyManager.GetAssemblyOwner(assembly, out var modName))
284  trim = modName;
285  else if (assembly == TerrariaAssembly)
286  trim = "tModLoader";
287  else
288  continue;
289 
290  int idx = filename.LastIndexOf(trim, StringComparison.InvariantCultureIgnoreCase);
291  if (idx > 0) {
292  filename = filename.Substring(idx);
293  f_fileName.SetValue(frame, filename);
294  }
295  }
296  }
static readonly Assembly TerrariaAssembly
Definition: Logging.cs:270

Member Data Documentation

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

Definition at line 183 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",
}

Definition at line 151 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 163 of file Logging.cs.

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

Definition at line 146 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 173 of file Logging.cs.

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

Definition at line 36 of file Logging.cs.

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

Definition at line 24 of file Logging.cs.

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

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

Definition at line 143 of file Logging.cs.

Exception Terraria.ModLoader.Logging.previousException
staticprivate

Definition at line 184 of file Logging.cs.

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

Definition at line 244 of file Logging.cs.

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

Definition at line 270 of file Logging.cs.

Property Documentation

string Terraria.ModLoader.Logging.LogPath
staticgetprivate set

Definition at line 25 of file Logging.cs.