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 void ctor_StackTrace (StackTrace self, Exception e, bool fNeedFileInfo)
 
delegate Encoding hook_GetEncoding (orig_GetEncoding orig, string name)
 
delegate void hook_StackTrace (ctor_StackTrace orig, StackTrace self, Exception e, bool fNeedFileInfo)
 
delegate Encoding orig_GetEncoding (string name)
 

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 void HookModuleLoad ()
 
static void HookStackTraceEx (ctor_StackTrace orig, StackTrace self, Exception e, bool fNeedFileInfo)
 
static void PrettifyStackTraceSources ()
 
static string RollLogs (string baseName)
 

Private Attributes

const int MAX_LOGS = 20
 

Static Private Attributes

static readonly FieldInfo f_strFileName
 
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()
 

Detailed Description

Definition at line 22 of file Logging.cs.

Member Function Documentation

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

Definition at line 127 of file Logging.cs.

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

Definition at line 117 of file Logging.cs.

117  {
118  try {
119  using (new FileStream(fileName, FileMode.Append)) ;
120  return true;
121  }
122  catch (IOException) {
123  return false;
124  }
125  }
static void Terraria.ModLoader.Logging.ConfigureAppenders ( )
staticprivate

Definition at line 65 of file Logging.cs.

65  {
66  var layout = new PatternLayout {
67  ConversionPattern = "[%d{HH:mm:ss}] [%t/%level] [%logger]: %m%n"
68  };
69  layout.ActivateOptions();
70 
71  var appenders = new List<IAppender>();
72 #if CLIENT
73  appenders.Add(new ConsoleAppender {
74  Name = "ConsoleAppender",
75  Layout = layout
76  });
77 #else
78  appenders.Add(new DebugAppender {
79  Name = "DebugAppender",
80  Layout = layout
81  });
82 #endif
83 
84  var fileAppender = new FileAppender {
85  Name = "FileAppender",
86  File = LogPath = Path.Combine(LogDir, RollLogs(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 string RollLogs(string baseName)
Definition: Logging.cs:97
static readonly string LogDir
Definition: Logging.cs:24
delegate void Terraria.ModLoader.Logging.ctor_StackTrace ( StackTrace  self,
Exception  e,
bool  fNeedFileInfo 
)
private
static void Terraria.ModLoader.Logging.DeleteOldArchives ( )
staticprivate

Definition at line 145 of file Logging.cs.

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

Definition at line 197 of file Logging.cs.

References Terraria.ModLoader.Console.

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

Definition at line 256 of file Logging.cs.

256  {
257  if (name == "IBM437")
258  return null;
259 
260  return orig(name);
261  }
static void Terraria.ModLoader.Logging.HookModuleLoad ( )
staticprivate

Definition at line 156 of file Logging.cs.

156  {
157  AssemblyManager.AssemblyResolveEarly((sender, args) => {
158  tML.DebugFormat("Assembly Resolve: {0} -> {1}", args.RequestingAssembly, args.Name);
159  return null;
160  });
161  }
static void Terraria.ModLoader.Logging.HookStackTraceEx ( ctor_StackTrace  orig,
StackTrace  self,
Exception  e,
bool  fNeedFileInfo 
)
staticprivate

Definition at line 270 of file Logging.cs.

270  {
271  orig(self, e, fNeedFileInfo);
272  if (fNeedFileInfo)
273  PrettifyStackTraceSources(self.GetFrames());
274  }
static void PrettifyStackTraceSources()
Definition: Logging.cs:302
static void Terraria.ModLoader.Logging.IgnoreExceptionContents ( string  source)
static

Definition at line 191 of file Logging.cs.

191  {
192  if (!ignoreContents.Contains(source))
193  ignoreContents.Add(source);
194  }
static List< string > ignoreContents
Definition: Logging.cs:183
static void Terraria.ModLoader.Logging.IgnoreExceptionSource ( string  source)
static
delegate Encoding Terraria.ModLoader.Logging.orig_GetEncoding ( string  name)
private
static void Terraria.ModLoader.Logging.PrettifyStackTraceSources ( StackFrame[]  frames)
static

Definition at line 276 of file Logging.cs.

276  {
277  if (frames == null)
278  return;
279 
280  foreach (var frame in frames) {
281  string filename = frame.GetFileName();
282  var assembly = frame.GetMethod()?.DeclaringType?.Assembly;
283  if (filename == null || assembly == null)
284  continue;
285 
286  string trim;
287  if (AssemblyManager.GetAssemblyOwner(assembly, out var modName))
288  trim = modName;
289  else if (assembly == TerrariaAssembly)
290  trim = "tModLoader";
291  else
292  continue;
293 
294  int idx = filename.LastIndexOf(trim, StringComparison.InvariantCultureIgnoreCase);
295  if (idx > 0) {
296  filename = filename.Substring(idx);
297  f_strFileName.SetValue(frame, filename);
298  }
299  }
300  }
static readonly Assembly TerrariaAssembly
Definition: Logging.cs:266
static readonly FieldInfo f_strFileName
Definition: Logging.cs:263
static void Terraria.ModLoader.Logging.PrettifyStackTraceSources ( )
staticprivate

Definition at line 302 of file Logging.cs.

302  {
303  if (f_strFileName == null)
304  return;
305 
306  new Hook(typeof(StackTrace).GetConstructor(new[] { typeof(Exception), typeof(bool) }), new hook_StackTrace(HookStackTraceEx));
307  }
delegate void hook_StackTrace(ctor_StackTrace orig, StackTrace self, Exception e, bool fNeedFileInfo)
static void HookStackTraceEx(ctor_StackTrace orig, StackTrace self, Exception e, bool fNeedFileInfo)
Definition: Logging.cs:270
static readonly FieldInfo f_strFileName
Definition: Logging.cs:263
static string Terraria.ModLoader.Logging.RollLogs ( 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  Archive(existingLog);
111 
113 
114  return $"{baseName}.log";
115  }
static void DeleteOldArchives()
Definition: Logging.cs:145
static readonly string LogDir
Definition: Logging.cs:24
static bool CanOpen(string fileName)
Definition: Logging.cs:117
static void Archive(string logPath)
Definition: Logging.cs:127

Member Data Documentation

readonly FieldInfo Terraria.ModLoader.Logging.f_strFileName
staticprivate
Initial value:
=
typeof(StackFrame).GetField("strFileName", BindingFlags.Instance | BindingFlags.NonPublic)

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

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

Definition at line 178 of file Logging.cs.

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

Definition at line 24 of file Logging.cs.

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

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

Definition at line 144 of file Logging.cs.

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

Definition at line 175 of file Logging.cs.

Exception Terraria.ModLoader.Logging.previousException
staticprivate

Definition at line 196 of file Logging.cs.

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

Definition at line 232 of file Logging.cs.

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

Definition at line 266 of file Logging.cs.

Property Documentation

string Terraria.ModLoader.Logging.LogPath
staticgetprivate set

Definition at line 25 of file Logging.cs.