Better exception logging

This commit is contained in:
Marc Hernandez 2025-11-07 15:23:28 -08:00
parent cb2b79be86
commit baa65531a2
5 changed files with 171 additions and 52 deletions

View File

@ -11,15 +11,14 @@
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>14.0</LangVersion>
<Copyright>Copyright 2003..2025 Marc Hernandez</Copyright>
<Description>A base set of </Description>
<!--
I Want to turn this on, but cant yet. Implementing nullability 1 file at a gime
<Nullable>enable</Nullable>
-->
</PropertyGroup>
<PropertyGroup>
<NoWarn>$(NoWarn);SYSLIB0050;CS8981; CS8632</NoWarn>
</PropertyGroup>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
@ -30,16 +29,13 @@
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.621003" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.24" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
<Folder Include="reflect\" />
<Folder Include="fsm\" />
</ItemGroup>
<ItemGroup>
<None Remove="fsm\" />
</ItemGroup>
</Project>

View File

@ -72,6 +72,9 @@ public struct SourceLoc
public string Log => ToLogString();
public string File => _dbgFile;
public string Method => _dbgName;
static public SourceLoc Record(
string reason = "",
[CallerMemberName] string dbgName = "",
@ -199,12 +202,12 @@ static public class log
public string Exp;
public string Cat;
public object? Obj;
public SourceLoc? Loc;
static ImmutableDictionary<int, string> s_shortname = ImmutableDictionary<int, string>.Empty;
public LogEvent( LogType logType, string msg, string dbgPath, int dbgLine, string dbgMethod, string cat, string exp, object? obj )
public LogEvent( LogType logType, string msg, string dbgPath, int dbgLine, string dbgMethod, string cat, string exp, SourceLoc? loc )
{
//Cache the automatic category names
@ -241,13 +244,13 @@ static public class log
Member = dbgMethod;
Cat = cat;
Exp = exp;
Obj = obj;
Loc = loc;
}
}
static LogEvent CreateLogEvent( LogType logType, string msg, string cat, object? obj, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", string exp = "" )
static LogEvent CreateLogEvent( LogType logType, string msg, string cat, SourceLoc? loc, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", string exp = "" )
{
var logEvent = new LogEvent( logType, msg, dbgPath, dbgLine, dbgMethod, cat, exp, obj );
var logEvent = new LogEvent( logType, msg, dbgPath, dbgLine, dbgMethod, cat, exp, loc );
return logEvent;
}
@ -286,7 +289,7 @@ static public class log
=> new SourceLoc( "", dbgName, dbgPath, dbgLine );
static public string whatFile( string path )
static public string whatFile( string path, bool incExtension = false )
{
var file = "";
@ -304,11 +307,20 @@ static public class log
pathPieces = path.Split( '/' );
}
var lastDir = pathPieces[pathPieces.Length - 1];
var lastPathPiece = pathPieces[pathPieces.Length - 1];
ImmutableInterlocked.AddOrUpdate( ref s_files, pathHash, lastDir, ( key, value ) => { return lastDir; } );
ImmutableInterlocked.AddOrUpdate( ref s_files, pathHash, lastPathPiece, ( key, value ) => { return lastPathPiece; } );
file = lastDir;
if( !incExtension )
{
var periodIndex = lastPathPiece.IndexOf( '.' );
if( periodIndex > 0 )
{
lastPathPiece = lastPathPiece.Substring( 0, periodIndex );
}
}
file = lastPathPiece;
}
return file;
@ -341,7 +353,7 @@ static public class log
}
/*
static public void info( string msg, string cat = "", object? obj = null,
static public void info( string msg, string cat = "",SourceLoc? loc = null,
[CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
*/
@ -383,6 +395,7 @@ static public class log
return v;
}
[StackTraceHidden]
static public void call( Action func, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "func" )] string dbgExp = "" )
{
log.info( $"{dbgExp}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
@ -390,57 +403,84 @@ static public class log
log.info( $"| Done", "", null, dbgPath, dbgLine, dbgName, dbgExp );
}
static public void fatal( string msg, string cat = "", object? obj = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Fatal, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
}
[StackTraceHidden]
static public void error( string msg, string cat = "", object? obj = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( $"{dbgMethod}: {msg}", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
}
[StackTraceHidden]
static public void warn( string msg, string cat = "", object? obj = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Warn, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
}
static public void high( string msg, string cat = "", object? obj = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.High, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
}
static public void info( string msg, string cat = "", object? obj = null,
static public void info( string msg, string cat = "",SourceLoc? loc = null,
[CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Info, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
logBase( msg, LogType.Info, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
static public void debug( string msg, string cat = "", object? obj = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
[StackTraceHidden]
static public void debug( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Debug, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
logBase( msg, LogType.Debug, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
static public void trace( string msg, string cat = "", object? obj = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
[StackTraceHidden]
static public void trace( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Trace, dbgPath, dbgLine, dbgMethod, cat, dbgExp, obj );
logBase( msg, LogType.Trace, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
[StackTraceHidden]
static public void warn( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Warn, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
[StackTraceHidden]
static public void high( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.High, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
[StackTraceHidden]
static public void error( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( $"{dbgMethod}: {msg}", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
[StackTraceHidden]
// VERY SPECIALIZED ONLY USE IF YOU KNOW WHAT YOU ARE DOING
static public void row_internal( string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
[StackTraceHidden]
static public void exception( Exception ex, string msg, string cat = "", SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( $"*******************************************************************************",
LogType.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
logBase( $"{dbgMethod}: {msg} | Caught At:", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
logBase( $"{dbgPath}({dbgLine}): {dbgMethod}: ---------------",
LogType.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
LogStackTrace( ex );
}
[StackTraceHidden]
static public void fatal( string msg, string cat = "",SourceLoc? loc = null, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
{
logBase( msg, LogType.Fatal, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
}
//new LogEvent( LogType.Raw, $"", "", 0, "", "lib.time", "", null )
#endregion
#region Helpers
static public void logProps( object obj, string header, LogType type = LogType.Debug, string cat = "", string prefix = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "obj" )] string dbgExpObj = "" )
static public void logProps( object obj, string header, LogType type = LogType.Debug, string cat = "", string prefix = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "obj" )] string dbgExpObj = "", SourceLoc? loc = null )
{
var list = refl.GetAllProperties( obj.GetType() );
lock( s_lock )
{
var evt = new LogEvent( type, header, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj, obj );
var evt = new LogEvent( type, header, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj, loc );
{
// Use Add instead of Enqueue
s_events.Add( evt );
@ -455,7 +495,7 @@ static public class log
}
catch( Exception ex )
{
logBase( $"Exception processing {pi.Name} {ex.Message}", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj, obj );
logBase( $"Exception processing {pi.Name} {ex.Message}", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj, loc );
}
}
@ -475,6 +515,26 @@ static public class log
log.warn( $"Got {notExpectedValue} instead of {value}{falseString}" );
}
}
static void LogStackTrace( Exception ex, string prefixMsg = "" )
{
var stackTrace = new StackTrace( ex, true );
var formattedTrace = "Stack Trace:\n";
if( ex.InnerException != null )
{
var prefix = $"{prefixMsg}Inner->";
LogStackTrace( ex.InnerException, prefix );
}
log.error( $"{prefixMsg} Exception: {ex.Message}" );
foreach( var fr in stackTrace.GetFrames() )
{
logBase( $"{fr.Log}", LogType.Raw );
}
}
#endregion
@ -494,14 +554,14 @@ static public class log
}
static public LogEvent logCreateEvent( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "", object? obj = null )
static public LogEvent logCreateEvent( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "",SourceLoc? loc = null )
{
LogEvent evt = new LogEvent( type, msg, dbgPath, dbgLine, dbgMethod, cat, exp, obj );
LogEvent evt = new LogEvent( type, msg, dbgPath, dbgLine, dbgMethod, cat, exp, loc );
return evt;
}
[StackTraceHidden]
static public void logBase( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "", object? obj = null )
static public void logBase( string msg, LogType type = LogType.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "",SourceLoc? loc = null )
{
var evt = logCreateEvent( msg, type, dbgPath, dbgLine, dbgMethod, cat, exp );

16
task/Task.cs Normal file
View File

@ -0,0 +1,16 @@
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
namespace lib;
static public class Task
{
}

28
util/Debug.cs Normal file
View File

@ -0,0 +1,28 @@
using System.Diagnostics;
static public class DebugEx
{
extension(StackFrame sf)
{
public string Method => sf.GetMethod().Name;
public string File => sf.GetFileName();
public int Line => sf.GetFileLineNumber();
public int Column => sf.GetFileColumnNumber();
public string Log => $"{sf.File}({sf.Line}, {sf.Column}): {sf.Method}";
}
}

19
util/RandomEx.cs Normal file
View File

@ -0,0 +1,19 @@
public static class RandomEx
{
/*
// NextBytes work fine
public static void FillBytes( this Random rnd, ref byte[] buffer )
{
rnd.NextBytes()
for( int i = 0; i < buffer.Length; ++i )
{
}
*/
}