Files
QuartZ-dump/GlobalShared/Logging/LogFormatter.cs
2024-12-29 21:15:58 +01:00

90 lines
2.5 KiB
C#

using System;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
namespace Global.Shared.Logging
{
public class LogFormatter
{
private const int MaxExceptionDepth = 100;
private readonly string _prefix;
private readonly ThreadLocal<StringBuilder> _stringBuilder = new ThreadLocal<StringBuilder>();
public LogFormatter(string prefix)
{
_prefix = prefix;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected string Format(Exception ex, string message, object[] data)
{
// Allocate a single StringBuilder object per thread
var sb = _stringBuilder.Value;
if (sb == null)
{
sb = new StringBuilder();
_stringBuilder.Value = sb;
}
if (message == null)
message = "";
sb.Append(_prefix);
sb.Append(data == null || data.Length == 0 ? message : string.Format(message, data));
FormatException(sb, ex);
var text = sb.ToString();
sb.Clear();
return text;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void FormatException(StringBuilder sb, Exception ex)
{
if (ex == null)
return;
for (var i = 0; i < MaxExceptionDepth; i++)
{
sb.Append("\r\n[");
sb.Append(ex.GetType().Name);
sb.Append("] ");
sb.Append(ex.Message);
if (ex.TargetSite != null)
{
sb.Append("\r\nMethod: ");
sb.Append(ex.TargetSite);
}
if (ex.Data.Count > 0)
{
sb.Append("\r\nData:");
foreach (var key in ex.Data.Keys)
{
sb.Append("\r\n");
sb.Append(key);
sb.Append(" = ");
sb.Append(ex.Data[key]);
}
}
sb.Append("\r\nTraceback:\r\n");
sb.Append(ex.StackTrace);
ex = ex.InnerException;
if (ex == null)
return;
sb.Append("\r\nInner exception:\r\n");
}
sb.Append($"WARNING: Not logging more than {MaxExceptionDepth} inner exceptions");
}
}
}