Files
sbox-public/engine/Sandbox.System/Logging/GameLog.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

139 lines
3.3 KiB
C#

using NLog;
using NLog.Targets;
namespace Sandbox
{
[Target( "GameLog" )]
internal sealed class GameLog : Target
{
private readonly object syncRoot = new object();
protected override void Write( LogEventInfo logEvent )
{
lock ( syncRoot )
{
ProtectedWrite( logEvent );
}
}
void ProtectedWrite( LogEventInfo logEvent )
{
string stacktrace = null;
if ( logEvent.Exception != null )
{
stacktrace = WriteExceptionDetails( logEvent.Exception );
}
if ( stacktrace == null && logEvent.StackTrace != null )
{
stacktrace = logEvent.StackTrace.ToString();
}
var l = Sandbox.LogLevel.Trace;
if ( logEvent.Level == NLog.LogLevel.Info ) l = LogLevel.Info;
if ( logEvent.Level == NLog.LogLevel.Warn ) l = LogLevel.Warn;
if ( logEvent.Level == NLog.LogLevel.Error ) l = LogLevel.Error;
var e = new LogEvent
{
Level = l,
Logger = logEvent.LoggerName,
Message = logEvent.FormattedMessage,
Stack = stacktrace,
Time = DateTime.Now
};
if ( logEvent.Exception != null && logEvent.Level >= NLog.LogLevel.Error )
{
Diagnostics.Logging.OnException?.Invoke( logEvent.Exception );
}
if ( Diagnostics.Logging.PrintToConsole )
{
var now = DateTime.Now;
var stream = e.Level == LogLevel.Error ? Console.Error : Console.Out;
Console.ForegroundColor = ConsoleColor.Cyan;
stream.Write( now.ToString( "hh:mm:ss " ) );
var logger = e.Logger ?? " ";
if ( logger.Length > 8 ) logger = logger.Substring( 0, 8 );
if ( logger.Length < 8 ) logger += new string( ' ', 8 - logger.Length );
Console.ForegroundColor = ConsoleColor.Green;
stream.Write( logger );
Console.ForegroundColor = GetConsoleColor( e );
var lines = logEvent.FormattedMessage.Split( '\n', '\r' );
stream.WriteLine( $" {lines[0]}" );
for ( int i = 1; i < lines.Length; i++ )
{
stream.WriteLine( $" {lines[i]}" );
}
}
}
private ConsoleColor GetConsoleColor( LogEvent e )
{
if ( e.Level == LogLevel.Trace ) return ConsoleColor.DarkGray;
if ( e.Level == LogLevel.Error ) return ConsoleColor.Red;
if ( e.Level == LogLevel.Warn ) return ConsoleColor.Yellow;
return ConsoleColor.White;
}
internal static string WriteExceptionDetails( Exception exception )
{
if ( exception == null )
return null;
var sb = new StringBuilder();
UnwrapException( exception, sb );
return sb.ToString();
}
private static void UnwrapException( Exception exception, StringBuilder sb )
{
var baseException = exception.GetBaseException();
if ( baseException is AggregateException aggregate )
{
var innerExceptions = aggregate.InnerExceptions;
if ( innerExceptions.Count == 0 )
{
PrintException( aggregate, sb );
return;
}
if ( innerExceptions.Count == 1 )
{
UnwrapException( innerExceptions[0], sb );
return;
}
sb.AppendLine( $"Aggregate of {innerExceptions.Count} exceptions:" );
for ( var i = 0; i < innerExceptions.Count; i++ )
{
sb.AppendLine( $">>> Exception {i}:" );
UnwrapException( innerExceptions[i], sb );
}
return;
}
PrintException( baseException, sb );
}
private static void PrintException( Exception exception, StringBuilder sb )
{
sb.AppendLine( exception?.ToString() ?? "<null>" );
}
}
}