Terraria ModLoader  0.10.1.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(Main.SavePath, "Logs")
 

Properties

static string LogPath [get, private set]
 

Private Member Functions

delegate Encoding hook_GetEncoding (orig_GetEncoding orig, string name)
 
delegate string hook_GetStackTrace (orig_GetStackTrace orig, Exception self, bool fNeedFileInfo)
 
delegate Encoding orig_GetEncoding (string name)
 
delegate string orig_GetStackTrace (Exception self, bool fNeedFileInfo)
 

Static Private Member Functions

static void Archive (string logPath)
 
static bool CanOpen (string fileName)
 
static void ConfigureAppenders ()
 
static void DeleteOldArchives ()
 
static void FirstChanceExceptionHandler (object sender, FirstChanceExceptionEventArgs args)
 
static Encoding HookGetEncoding (orig_GetEncoding orig, string name)
 
static string HookGetStackTrace (orig_GetStackTrace orig, Exception self, bool fNeedFileInfo)
 
static void HookModuleLoad ()
 
static void PrettifyStackTraceSources ()
 
static string RollLogs (string baseName)
 

Private Attributes

const int MAX_LOGS = 20
 

Static Private Attributes

static readonly Regex dropGenericTicks = new Regex(@"`\d+", RegexOptions.Compiled)
 
static readonly Regex dropOffset = new Regex(@" \[.+?\](?![^:]+:-1)", RegexOptions.Compiled)
 
static List< string > ignoreContents
 
static HashSet< string > ignoreSources
 
static HashSet< string > pastExceptions = new HashSet<string>()
 
static Exception previousException
 
static Regex statusRegex = new Regex(@"(.+?)[: \d]*%$")
 
static readonly Assembly TerrariaAssembly = Assembly.GetExecutingAssembly()
 
static readonly Regex trimParamTypes = new Regex(@"([([,] ?)(?:[\w.+]+[.+])", RegexOptions.Compiled)
 

Detailed Description

Definition at line 25 of file Logging.cs.

Member Function Documentation

static void Terraria.ModLoader.Logging.Archive ( string  logPath)
staticprivate

Definition at line 131 of file Logging.cs.

131  {
132  var time = File.GetCreationTime(logPath);
133  int n = 1;
134 
135  var pattern = new Regex($"{time:yyyy-MM-dd}-(\\d+)\\.zip");
136  var existingLogs = Directory.GetFiles(LogDir).Where(s => pattern.IsMatch(Path.GetFileName(s))).ToList();
137  if (existingLogs.Count > 0)
138  n = existingLogs.Select(s => int.Parse(pattern.Match(Path.GetFileName(s)).Groups[1].Value)).Max() + 1;
139 
140  using (var zip = new ZipFile(Path.Combine(LogDir, $"{time:yyyy-MM-dd}-{n}.zip"), Encoding.UTF8)) {
141  zip.AddFile(logPath, "");
142  zip.Save();
143  }
144 
145  File.Delete(logPath);
146  }
static readonly string LogDir
Definition: Logging.cs:27
static bool Terraria.ModLoader.Logging.CanOpen ( string  fileName)
staticprivate

Definition at line 121 of file Logging.cs.

121  {
122  try {
123  using (new FileStream(fileName, FileMode.Append)) ;
124  return true;
125  }
126  catch (IOException) {
127  return false;
128  }
129  }
static void Terraria.ModLoader.Logging.ConfigureAppenders ( )
staticprivate

Definition at line 69 of file Logging.cs.

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

Definition at line 149 of file Logging.cs.

149  {
150  var pattern = new Regex(".*\\.zip");
151  var existingLogs = Directory.GetFiles(LogDir).Where(s => pattern.IsMatch(Path.GetFileName(s))).OrderBy(File.GetCreationTime).ToList();
152  foreach (var f in existingLogs.Take(existingLogs.Count - MAX_LOGS)) {
153  try {
154  File.Delete(f);
155  }
156  catch (IOException) { }
157  }
158  }
static readonly string LogDir
Definition: Logging.cs:27
static void Terraria.ModLoader.Logging.FirstChanceExceptionHandler ( object  sender,
FirstChanceExceptionEventArgs  args 
)
staticprivate

Definition at line 196 of file Logging.cs.

References Terraria.ModLoader.Console.

196  {
197  if (args.Exception == previousException ||
198  args.Exception is ThreadAbortException ||
199  ignoreSources.Contains(args.Exception.Source))
200  return;
201 
202  var stackTrace = new StackTrace(true);
203  PrettifyStackTraceSources(stackTrace.GetFrames());
204  var traceString = stackTrace.ToString();
205 
206  if (ignoreContents.Any(traceString.Contains))
207  return;
208 
209  traceString = traceString.Substring(traceString.IndexOf('\n'));
210  var exString = args.Exception.GetType() + ": " + args.Exception.Message + traceString;
211  lock (pastExceptions) {
212  if (!pastExceptions.Add(exString))
213  return;
214  }
215 
216  previousException = args.Exception;
217  var msg = args.Exception.Message + " " + Language.GetTextValue("tModLoader.RuntimeErrorSeeLogsForFullTrace", Path.GetFileName(LogPath));
218 #if CLIENT
219  if (!Main.gameMenu && ModCompile.activelyModding) {
220  float soundVolume = Main.soundVolume;
221  Main.soundVolume = 0f;
222  Main.NewText(msg, Microsoft.Xna.Framework.Color.OrangeRed);
223  Main.soundVolume = soundVolume;
224  }
225 #else
226  Console.ForegroundColor = ConsoleColor.DarkMagenta;
227  Console.WriteLine(msg);
228  Console.ResetColor();
229 #endif
230  tML.Warn(Language.GetTextValue("tModLoader.RuntimeErrorSilentlyCaughtException") + '\n' + exString);
231  }
static string LogPath
Definition: Logging.cs:28
static List< string > ignoreContents
Definition: Logging.cs:182
Command can be used in server console during MP.
static HashSet< string > ignoreSources
Definition: Logging.cs:177
static HashSet< string > pastExceptions
Definition: Logging.cs:174
static Exception previousException
Definition: Logging.cs:195
static void PrettifyStackTraceSources()
Definition: Logging.cs:324
delegate Encoding Terraria.ModLoader.Logging.hook_GetEncoding ( orig_GetEncoding  orig,
string  name 
)
private
delegate string Terraria.ModLoader.Logging.hook_GetStackTrace ( orig_GetStackTrace  orig,
Exception  self,
bool  fNeedFileInfo 
)
private
static Encoding Terraria.ModLoader.Logging.HookGetEncoding ( orig_GetEncoding  orig,
string  name 
)
staticprivate

Definition at line 257 of file Logging.cs.

257  {
258  if (name == "IBM437")
259  return null;
260 
261  return orig(name);
262  }
static string Terraria.ModLoader.Logging.HookGetStackTrace ( orig_GetStackTrace  orig,
Exception  self,
bool  fNeedFileInfo 
)
staticprivate

Definition at line 285 of file Logging.cs.

286  {
287  var stackTrace = new StackTrace(self, true);
288  MdbManager.Symbolize(stackTrace.GetFrames());
289  PrettifyStackTraceSources(stackTrace.GetFrames());
290  var s = stackTrace.ToString();
291  s = trimParamTypes.Replace(s, "$1");
292  s = dropGenericTicks.Replace(s, "");
293  s = dropOffset.Replace(s, "");
294  s = s.Replace(":-1", "");
295  return s;
296  }
static readonly Regex dropOffset
Definition: Logging.cs:280
static readonly Regex trimParamTypes
Definition: Logging.cs:279
static readonly Regex dropGenericTicks
Definition: Logging.cs:281
static void PrettifyStackTraceSources()
Definition: Logging.cs:324
static void Terraria.ModLoader.Logging.HookModuleLoad ( )
staticprivate

Definition at line 160 of file Logging.cs.

References Framework.

160  {
161  AssemblyManager.AssemblyResolveEarly((sender, args) => {
162  tML.DebugFormat("Assembly Resolve: {0} -> {1}", args.RequestingAssembly, args.Name);
163  return null;
164  });
165  }
static void Terraria.ModLoader.Logging.IgnoreExceptionContents ( string  source)
static

Definition at line 190 of file Logging.cs.

190  {
191  if (!ignoreContents.Contains(source))
192  ignoreContents.Add(source);
193  }
static List< string > ignoreContents
Definition: Logging.cs:182
static void Terraria.ModLoader.Logging.IgnoreExceptionSource ( string  source)
static
delegate Encoding Terraria.ModLoader.Logging.orig_GetEncoding ( string  name)
private
delegate string Terraria.ModLoader.Logging.orig_GetStackTrace ( Exception  self,
bool  fNeedFileInfo 
)
private
static void Terraria.ModLoader.Logging.PrettifyStackTraceSources ( StackFrame[]  frames)
static

Definition at line 298 of file Logging.cs.

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

Definition at line 324 of file Logging.cs.

324  {
325 #if WINDOWS
326  if (f_fileName == null)
327  return;
328 
329  new Hook(typeof(StackTrace).GetConstructor(new[] { typeof(Exception), typeof(bool) }), new hook_StackTrace(HookStackTraceEx));
330 #else
331  new Hook(typeof(Exception).FindMethod("GetStackTrace"), new hook_GetStackTrace(HookGetStackTrace));
332 #endif
333  }
static string HookGetStackTrace(orig_GetStackTrace orig, Exception self, bool fNeedFileInfo)
Definition: Logging.cs:285
delegate string hook_GetStackTrace(orig_GetStackTrace orig, Exception self, bool fNeedFileInfo)
static string Terraria.ModLoader.Logging.RollLogs ( string  baseName)
staticprivate

Definition at line 101 of file Logging.cs.

101  {
102  var pattern = new Regex($"{baseName}(\\d*)\\.log");
103  var existingLogs = Directory.GetFiles(LogDir).Where(s => pattern.IsMatch(Path.GetFileName(s))).ToList();
104 
105  if (!existingLogs.All(CanOpen)) {
106  int n = existingLogs.Select(s => {
107  var tok = pattern.Match(Path.GetFileName(s)).Groups[1].Value;
108  return tok.Length == 0 ? 1 : int.Parse(tok);
109  }).Max();
110  return $"{baseName}{n + 1}.log";
111  }
112 
113  foreach (var existingLog in existingLogs.OrderBy(File.GetCreationTime))
114  Archive(existingLog);
115 
117 
118  return $"{baseName}.log";
119  }
static void DeleteOldArchives()
Definition: Logging.cs:149
static readonly string LogDir
Definition: Logging.cs:27
static bool CanOpen(string fileName)
Definition: Logging.cs:121
static void Archive(string logPath)
Definition: Logging.cs:131

Member Data Documentation

readonly Regex Terraria.ModLoader.Logging.dropGenericTicks = new Regex(@"`\d+", RegexOptions.Compiled)
staticprivate

Definition at line 281 of file Logging.cs.

readonly Regex Terraria.ModLoader.Logging.dropOffset = new Regex(@" \[.+?\](?![^:]+:-1)", RegexOptions.Compiled)
staticprivate

Definition at line 280 of file Logging.cs.

List<string> Terraria.ModLoader.Logging.ignoreContents
staticprivate
Initial value:
= new List<string> {
"Terraria.ModLoader.ModCompile",
"Delegate.CreateDelegateNoSecurityCheck",
"MethodBase.GetMethodBody",
"Terraria.Net.Sockets.TcpSocket.Terraria.Net.Sockets.ISocket.AsyncSend",
"System.Diagnostics.Process.Kill",
}

Definition at line 182 of file Logging.cs.

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

Definition at line 177 of file Logging.cs.

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

Definition at line 27 of file Logging.cs.

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

const int Terraria.ModLoader.Logging.MAX_LOGS = 20
private

Definition at line 148 of file Logging.cs.

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

Definition at line 174 of file Logging.cs.

Exception Terraria.ModLoader.Logging.previousException
staticprivate

Definition at line 195 of file Logging.cs.

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

Definition at line 233 of file Logging.cs.

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

Definition at line 268 of file Logging.cs.

readonly Regex Terraria.ModLoader.Logging.trimParamTypes = new Regex(@"([([,] ?)(?:[\w.+]+[.+])", RegexOptions.Compiled)
staticprivate

Definition at line 279 of file Logging.cs.

Property Documentation

string Terraria.ModLoader.Logging.LogPath
staticgetprivate set

Definition at line 28 of file Logging.cs.