Various
This commit is contained in:
parent
3bf3220beb
commit
40dd96d06e
@ -11,6 +11,25 @@ x)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static public class cfg
|
||||
{
|
||||
|
||||
|
||||
static public T load<T>( string filename ) where T : lib.Config
|
||||
{
|
||||
return (T)lib.ConfigBase.load<T>( filename );
|
||||
}
|
||||
|
||||
static public lib.Config load( string filename )
|
||||
{
|
||||
return lib.ConfigBase.load( filename, null );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
@ -184,6 +203,8 @@ namespace lib
|
||||
|
||||
internal static ConfigCfg s_cfg = new();
|
||||
|
||||
public static ConfigCfg Cfg => s_cfg;
|
||||
|
||||
static public void startup( string filename )
|
||||
{
|
||||
res.Mgr.Register( ConfigBase.load );
|
||||
|
||||
345
logging/Log.cs
345
logging/Log.cs
@ -54,36 +54,36 @@ public record struct Value<T>( T _val, string _exp = "" )
|
||||
public struct SourceLoc
|
||||
{
|
||||
readonly string _reason = "";
|
||||
readonly string _dbgName = "";
|
||||
readonly string _dbgMethod = "";
|
||||
readonly string _dbgPath = "";
|
||||
readonly string _dbgFile = "";
|
||||
readonly int _dbgLine = -1;
|
||||
|
||||
public SourceLoc( string reason, string dbgName, string dbgPath, int dbgLine )
|
||||
public SourceLoc( string reason, string dbgMethod, string dbgPath, int dbgLine )
|
||||
{
|
||||
_reason = reason;
|
||||
_dbgName = dbgName;
|
||||
_dbgMethod = dbgMethod;
|
||||
_dbgPath = dbgPath;
|
||||
_dbgLine = dbgLine;
|
||||
|
||||
_dbgFile = log.whatFile( dbgPath );
|
||||
}
|
||||
|
||||
public string ToLogString() => $"{_dbgFile}.{_dbgName}";
|
||||
public string ToLogString() => $"{_dbgFile}.{_dbgMethod}";
|
||||
|
||||
public string Log => ToLogString();
|
||||
|
||||
public string File => _dbgFile;
|
||||
public string Method => _dbgName;
|
||||
public string Method => _dbgMethod;
|
||||
|
||||
static public SourceLoc Record(
|
||||
string reason = "",
|
||||
[CallerMemberName] string dbgName = "",
|
||||
[CallerMemberName] string dbgMethod = "",
|
||||
[CallerFilePath] string dbgPath = "",
|
||||
[CallerLineNumber] int dbgLine = 0
|
||||
)
|
||||
{
|
||||
return new SourceLoc( reason, dbgName, dbgPath, dbgLine );
|
||||
return new SourceLoc( reason, dbgMethod, dbgPath, dbgLine );
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ static public class log
|
||||
#endregion // CLR Logging
|
||||
|
||||
[Flags]
|
||||
public enum LogType
|
||||
public enum Levels
|
||||
{
|
||||
Invalid = 0,
|
||||
Trace = 1,
|
||||
@ -186,7 +186,7 @@ static public class log
|
||||
public struct LogEvent
|
||||
{
|
||||
public DateTime Time;
|
||||
public LogType LogType;
|
||||
public Levels Levels;
|
||||
public string Msg;
|
||||
public string Path;
|
||||
public int Line;
|
||||
@ -199,7 +199,7 @@ static public class log
|
||||
|
||||
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, SourceLoc? loc )
|
||||
public LogEvent( Levels level, string msg, string dbgPath, int dbgLine, string dbgMethod, string cat, string exp, SourceLoc? loc )
|
||||
{
|
||||
|
||||
//Cache the automatic category names
|
||||
@ -229,7 +229,7 @@ static public class log
|
||||
}
|
||||
|
||||
Time = DateTime.Now;
|
||||
LogType = logType;
|
||||
Levels = level;
|
||||
Msg = msg;
|
||||
Path = dbgPath;
|
||||
Line = dbgLine;
|
||||
@ -240,9 +240,9 @@ static public class log
|
||||
}
|
||||
}
|
||||
|
||||
static LogEvent CreateLogEvent( LogType logType, string msg, string cat, SourceLoc? loc, [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", string exp = "" )
|
||||
static LogEvent CreateLogEvent( Levels level, 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, loc );
|
||||
var logEvent = new LogEvent( level, msg, dbgPath, dbgLine, dbgMethod, cat, exp, loc );
|
||||
|
||||
return logEvent;
|
||||
}
|
||||
@ -261,7 +261,7 @@ static public class log
|
||||
static public void shutdown()
|
||||
{
|
||||
string msg = "==============================================================================\nLogfile shutdown at " + DateTime.Now.ToString();
|
||||
var evt = CreateLogEvent( LogType.Info, msg, "System", null );
|
||||
var evt = CreateLogEvent( Levels.Info, msg, "System", null );
|
||||
s_events.Add( evt ); // Use Add instead of Enqueue
|
||||
|
||||
stop();
|
||||
@ -277,8 +277,8 @@ static public class log
|
||||
static ImmutableDictionary<int, string> s_files = ImmutableDictionary<int, string>.Empty;
|
||||
|
||||
#region Util
|
||||
static public SourceLoc loc( [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 )
|
||||
=> new SourceLoc( "", dbgName, dbgPath, dbgLine );
|
||||
static public SourceLoc loc( [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1 )
|
||||
=> new SourceLoc( "", dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
|
||||
static public string whatFile( string path, bool incExtension = false )
|
||||
@ -336,11 +336,11 @@ static public class log
|
||||
|
||||
|
||||
#region Forwards
|
||||
static public T call<T>( Func<T> func, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "func" )] string dbgExp = "" )
|
||||
static public T call<T>( Func<T> func, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "func" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"Fn {dbgExp}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"Fn {dbgExp}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
var val = func();
|
||||
log.info( $"| Got {val}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"| Got {val}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -349,38 +349,38 @@ static public class log
|
||||
[CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "msg" )] string dbgExp = "" )
|
||||
*/
|
||||
|
||||
static public T var<T>( T val, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
static public T var<T>( T val, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"{dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"{dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
return val;
|
||||
}
|
||||
|
||||
static public void operations( Action val, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
static public void operations( Action val, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"{dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"{dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
|
||||
val();
|
||||
}
|
||||
|
||||
static public T operations<T>( Func<T> val, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
static public T operations<T>( Func<T> val, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"{dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"{dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
|
||||
var v = val();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static public void operations( string prefix, Action val, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
static public void operations( string prefix, Action val, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"{prefix} {dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"{prefix} {dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
|
||||
val();
|
||||
}
|
||||
|
||||
static public T operations<T>( string prefix, Func<T> val, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
static public T operations<T>( string prefix, Func<T> val, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "val" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"{prefix} {dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"{prefix} {dbgExp} = {val}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
|
||||
var v = val();
|
||||
|
||||
@ -388,48 +388,48 @@ static public class log
|
||||
}
|
||||
|
||||
[StackTraceHidden]
|
||||
static public void call( Action func, [CallerMemberName] string dbgName = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "func" )] string dbgExp = "" )
|
||||
static public void call( Action func, [CallerMemberName] string dbgMethod = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerArgumentExpression( "func" )] string dbgExp = "" )
|
||||
{
|
||||
log.info( $"{dbgExp}", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"{dbgExp}", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
func();
|
||||
log.info( $"| Done", "", null, dbgPath, dbgLine, dbgName, dbgExp );
|
||||
log.info( $"| Done", "", null, dbgPath, dbgLine, dbgMethod, dbgExp );
|
||||
}
|
||||
|
||||
[StackTraceHidden]
|
||||
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, loc );
|
||||
logBase( msg, Levels.Info, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
}
|
||||
|
||||
[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, loc );
|
||||
logBase( msg, Levels.Debug, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
}
|
||||
|
||||
[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, loc );
|
||||
logBase( msg, Levels.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 );
|
||||
logBase( msg, Levels.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 );
|
||||
logBase( msg, Levels.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 );
|
||||
logBase( $"{dbgMethod}: {msg}", Levels.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
}
|
||||
|
||||
|
||||
@ -437,7 +437,7 @@ static public class log
|
||||
// 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 );
|
||||
logBase( msg, Levels.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
}
|
||||
|
||||
|
||||
@ -446,10 +446,10 @@ static public class log
|
||||
{
|
||||
|
||||
logBase( $"*******************************************************************************",
|
||||
LogType.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
logBase( $"{dbgMethod}: {msg} | Caught At:", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
Levels.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
logBase( $"{dbgMethod}: {msg} | Caught At:", Levels.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
logBase( $"{dbgPath}({dbgLine}): {dbgMethod}: ---------------",
|
||||
LogType.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
Levels.Raw, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
LogStackTrace( ex );
|
||||
}
|
||||
|
||||
@ -458,15 +458,50 @@ static public class log
|
||||
[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 );
|
||||
logBase( msg, Levels.Fatal, dbgPath, dbgLine, dbgMethod, cat, dbgExp, loc );
|
||||
}
|
||||
|
||||
//new LogEvent( LogType.Raw, $"", "", 0, "", "lib.time", "", null )
|
||||
//new LogEvent( Levels.Raw, $"", "", 0, "", "lib.time", "", null )
|
||||
|
||||
#endregion
|
||||
|
||||
static private bool hasMethod( string name, Type t )
|
||||
{
|
||||
var mi = t.GetMethod( name );
|
||||
|
||||
return mi != null;
|
||||
}
|
||||
|
||||
static private bool hasMethod<T>( string name ) => hasMethod( name, typeof( T ) );
|
||||
|
||||
|
||||
#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 = "", SourceLoc? loc = null )
|
||||
|
||||
static public void environment( string header = "", string footer = "", Levels level = Levels.Info, string cat = "", string prefix = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "obj" )] string dbgExpObj = "", SourceLoc? loc = null )
|
||||
{
|
||||
log.var( System.Environment.ProcessId, dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
log.var( System.Environment.CommandLine, dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
log.var( System.Environment.CurrentDirectory, dbgMethod, dbgPath, dbgLine );
|
||||
log.var( System.Environment.SystemDirectory, dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
log.var( System.Environment.GetEnvironmentVariable( "PATH" ), dbgMethod, dbgPath, dbgLine );
|
||||
log.var( System.Environment.GetEnvironmentVariable( "USER" ), dbgMethod, dbgPath, dbgLine );
|
||||
log.var( System.Environment.GetEnvironmentVariable( "HOME" ), dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
log.var( System.Environment.ProcessorCount, dbgMethod, dbgPath, dbgLine );
|
||||
log.var( System.Environment.Is64BitOperatingSystem, dbgMethod, dbgPath, dbgLine );
|
||||
log.var( System.Environment.Is64BitProcess, dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
log.var( System.Environment.MachineName, dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
log.var( System.Environment.Version, dbgMethod, dbgPath, dbgLine );
|
||||
log.var( System.Environment.OSVersion, dbgMethod, dbgPath, dbgLine );
|
||||
|
||||
}
|
||||
|
||||
static public void props_orig( object obj, string header, int depth = 0, Levels type = Levels.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() );
|
||||
|
||||
@ -482,12 +517,23 @@ static public class log
|
||||
try
|
||||
{
|
||||
var v = pi.GetValue( obj );
|
||||
var isNull = v != null;
|
||||
|
||||
if( isNull )
|
||||
{
|
||||
logBase( $"{prefix}{pi.Name} = null", type, dbgPath, dbgLine, dbgMethod, dbgExpObj, cat );
|
||||
continue;
|
||||
}
|
||||
|
||||
//var isPOD =
|
||||
|
||||
|
||||
logBase( $"{prefix}{pi.Name} = {v}", type, dbgPath, dbgLine, dbgMethod, dbgExpObj, cat );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
logBase( $"Exception processing {pi.Name} {ex.Message}", LogType.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj, loc );
|
||||
logBase( $"{prefix}{pi.Name} = {ex.Message}", type, dbgPath, dbgLine, dbgMethod, dbgExpObj, cat );
|
||||
//logBase( $"Exception processing {pi.Name} {ex.Message}", Levels.Error, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj, loc );
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,6 +541,120 @@ static public class log
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static readonly HashSet<Type> s_podTypes = new()
|
||||
{
|
||||
typeof(string), typeof(bool), typeof(byte), typeof(sbyte),
|
||||
typeof(char), typeof(decimal), typeof(double), typeof(float),
|
||||
typeof(int), typeof(uint), typeof(long), typeof(ulong),
|
||||
typeof(short), typeof(ushort), typeof(DateTime), typeof(DateTimeOffset),
|
||||
typeof(TimeSpan), typeof(Guid)
|
||||
};
|
||||
|
||||
static public void props( object obj, string header, int maxDepth = 0, Levels level = Levels.Debug, string cat = "", string prefix = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "obj" )] string dbgExpObj = "", SourceLoc? loc = null )
|
||||
{
|
||||
// May not need this
|
||||
//var visited = new HashSet<object>( ReferenceEqualityComparer.Instance );
|
||||
|
||||
props_r( obj, header, maxDepth, level, cat, prefix, dbgPath, dbgLine, dbgMethod, dbgExpObj, loc );
|
||||
}
|
||||
|
||||
static private void props_r( object obj, string header, int maxDepth = 0, Levels level = Levels.Debug, string cat = "", string prefix = "", [CallerFilePath] string dbgPath = "", [CallerLineNumber] int dbgLine = -1, [CallerMemberName] string dbgMethod = "", [CallerArgumentExpression( "obj" )] string dbgExpObj = "", SourceLoc? loc = null )
|
||||
{
|
||||
// 1. Handle Null
|
||||
if( obj is null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type type = obj.GetType();
|
||||
|
||||
var tc = Type.GetTypeCode( type );
|
||||
|
||||
|
||||
//logBase( string msg, Levels type = Levels.Debug, string dbgPath = "", int dbgLine = -1, string dbgMethod = "", string cat = "unk", string exp = "", SourceLoc? loc = null )
|
||||
|
||||
|
||||
// 2. Handle POD (Plain Old Data) & Strings
|
||||
if( tc != TypeCode.Object )
|
||||
{
|
||||
logBase( $"{header}{dbgExpObj} = {obj}", level, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj );
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Handle Overridden ToString() (User Rule)
|
||||
// Check if the type overrides ToString() directly (not just inheriting object.ToString)
|
||||
var toStringMethod = type.GetMethod( "ToString", Type.EmptyTypes );
|
||||
if( toStringMethod != null && toStringMethod.DeclaringType != typeof( object ) )
|
||||
{
|
||||
logBase( $"{header}{dbgExpObj} = {obj.ToString()}", level, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj );
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Cycle Detection
|
||||
/*
|
||||
if( !visited.Add( obj ) )
|
||||
{
|
||||
sb.Append( $"{{$Cyclic:{type.Name}}}" );
|
||||
return;
|
||||
}
|
||||
//*/
|
||||
|
||||
// 5. Handle Collections (IEnumerable)
|
||||
if( obj is IEnumerable collection )
|
||||
{
|
||||
logBase( $"{header}{dbgExpObj}[{type.Name}] [[[", level, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj );
|
||||
|
||||
if( maxDepth == 0 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
var collectionHader = $"{header}{header}";
|
||||
var count = 0;
|
||||
foreach( var item in collection )
|
||||
{
|
||||
//if( count != 0 )
|
||||
props_r( item, collectionHader, --maxDepth, level, cat, prefix, dbgPath, dbgLine, dbgMethod, $"{count}" );
|
||||
}
|
||||
}
|
||||
logBase( $"{header}{dbgExpObj}[{type.Name}] ]]]", level, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
logBase( $"{header}{dbgExpObj}[{type.Name}] ->", level, dbgPath, dbgLine, dbgMethod, cat, dbgExpObj );
|
||||
|
||||
// 6. Handle Complex Objects (Properties)
|
||||
if( maxDepth == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all readable properties
|
||||
var props = type.GetProperties( BindingFlags.Public | BindingFlags.Instance )
|
||||
.Where( p => p.CanRead && p.GetIndexParameters().Length == 0 );
|
||||
|
||||
var nextHeader = $"{header}{header}";
|
||||
|
||||
//bool firstProp = true;
|
||||
foreach( var pi in props )
|
||||
{
|
||||
var name = pi.Name;
|
||||
var piType = pi.PropertyType;
|
||||
try
|
||||
{
|
||||
var value = pi.GetValue( obj );
|
||||
props_r( value, nextHeader, --maxDepth, level, cat, prefix, dbgPath, dbgLine, dbgMethod, name );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
logBase( $"{nextHeader}{name}[{piType.Name}] ex {ex.Message}", level, dbgPath, dbgLine, dbgMethod, cat, name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This might seem a little odd, but the intent is that usually you wont need to set notExpectedValue.
|
||||
static public void expected<T>( T value, string falseString, string trueString = "", T? notExpectedValue = default( T ) )
|
||||
{
|
||||
@ -523,7 +683,7 @@ static public class log
|
||||
|
||||
foreach( var fr in stackTrace.GetFrames() )
|
||||
{
|
||||
logBase( $"{fr.Log}", LogType.Raw );
|
||||
logBase( $"{fr.Log}", Levels.Raw );
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,43 +695,44 @@ static public class log
|
||||
|
||||
static object s_lock = new object();
|
||||
static object s_lockTypeCallback = new object();
|
||||
static ImmutableDictionary<LogType, Action<LogEvent>> s_callbacks = ImmutableDictionary<LogType, Action<LogEvent>>.Empty;
|
||||
static ImmutableDictionary<Levels, Action<LogEvent>> s_callbacks = ImmutableDictionary<Levels, Action<LogEvent>>.Empty;
|
||||
|
||||
//static ConcurrentDictionary<string, List<FilterFn>> s_filters = new();
|
||||
static ConcurrentDictionary<string, List<FilterFn>> s_filters = new();
|
||||
|
||||
static public void addFilter( string name, FilterFn filter )
|
||||
{
|
||||
/*
|
||||
//*
|
||||
s_filters.AddOrUpdate( name,
|
||||
( k ) => new List<FilterFn> { filter },
|
||||
( k, v ) => {
|
||||
( k, v ) =>
|
||||
{
|
||||
v.Add( filter );
|
||||
return v;
|
||||
} );
|
||||
*/
|
||||
//*/
|
||||
}
|
||||
|
||||
|
||||
[StackTraceHidden]
|
||||
static public void addDirectCallback( LogType logType, Action<LogEvent> callback )
|
||||
static public void addDirectCallback( Levels level, Action<LogEvent> callback )
|
||||
{
|
||||
//ImmutableInterlocked.Add( ref s_callbacks, logType, callback );
|
||||
var added = II.TryAdd( ref s_callbacks, logType, callback );
|
||||
//ImmutableInterlocked.Add( ref s_callbacks, level, callback );
|
||||
var added = II.TryAdd( ref s_callbacks, level, callback );
|
||||
if( !added )
|
||||
{
|
||||
log.warn( $"Failed to add callback for {logType}" );
|
||||
log.warn( $"Failed to add callback for {level}" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
static public LogEvent logCreateEvent( string msg, Levels type = Levels.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, 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 = "", SourceLoc? loc = null )
|
||||
static public void logBase( string msg, Levels type = Levels.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 );
|
||||
|
||||
@ -639,9 +800,9 @@ static public class log
|
||||
{
|
||||
var time = DateTime.Now;
|
||||
// Header for this run
|
||||
var blankLine = new LogEvent( LogType.Raw, $"", "", 0, "", "lib.time", "", null );
|
||||
var beginLine = new LogEvent( LogType.Raw, $"Begin B E G I N ******************************************************************************************************************", "", 0, "", "lib.time", "", null );
|
||||
var timeLine = new LogEvent( LogType.Raw, $"D A T E {time.Year}/{time.Month.ToString( "00" )}/{time.Day.ToString( "00" )} T I M E {time.Hour.ToString( "00" )}:{time.Minute.ToString( "00" )}:{time.Second.ToString( "00" )}.{time.Millisecond.ToString( "000" )}{time.Microsecond.ToString( "000" )}", "", 0, "", "lib.time", "", null );
|
||||
var blankLine = new LogEvent( Levels.Raw, $"", "", 0, "", "lib.time", "", null );
|
||||
var beginLine = new LogEvent( Levels.Raw, $"Begin B E G I N ******************************************************************************************************************", "", 0, "", "lib.time", "", null );
|
||||
var timeLine = new LogEvent( Levels.Raw, $"D A T E {time.Year}/{time.Month.ToString( "00" )}/{time.Day.ToString( "00" )} T I M E {time.Hour.ToString( "00" )}:{time.Minute.ToString( "00" )}:{time.Second.ToString( "00" )}.{time.Millisecond.ToString( "000" )}{time.Microsecond.ToString( "000" )}", "", 0, "", "lib.time", "", null );
|
||||
|
||||
// MODIFIED: All writes are now safely enqueued to be processed by the logger thread.
|
||||
// This prevents the StreamWriter buffer corruption that caused null bytes.
|
||||
@ -653,13 +814,13 @@ static public class log
|
||||
s_events.Add( blankLine );
|
||||
}
|
||||
|
||||
LogEvent msgStartupBegin = new LogEvent( LogType.Info, $"startup BEGIN", "", 0, "", "log.startup", "", null );
|
||||
LogEvent msgStartupBegin = new LogEvent( Levels.Info, $"startup BEGIN", "", 0, "", "log.startup", "", null );
|
||||
s_events.Add( msgStartupBegin );
|
||||
|
||||
LogEvent msgFilename = new LogEvent( LogType.Info, $"Logging in {filename}", "", 0, "", "log.startup", "", null );
|
||||
LogEvent msgFilename = new LogEvent( Levels.Info, $"Logging in {filename}", "", 0, "", "log.startup", "", null );
|
||||
s_events.Add( msgFilename );
|
||||
|
||||
var optionsLine = new LogEvent( LogType.Info, $"Endpoints: {endpoints}", "", 0, "", "log.startup", "", null );
|
||||
var optionsLine = new LogEvent( Levels.Info, $"Endpoints: {endpoints}", "", 0, "", "log.startup", "", null );
|
||||
s_events.Add( optionsLine );
|
||||
|
||||
StartThread();
|
||||
@ -699,7 +860,7 @@ static public class log
|
||||
// automatically finish when s_events.CompleteAdding() is called from another thread.
|
||||
foreach( var evt in s_events.GetConsumingEnumerable() )
|
||||
{
|
||||
/*
|
||||
//*
|
||||
// Apply filters
|
||||
var cat = evt.Cat;
|
||||
var blocked = false;
|
||||
@ -762,23 +923,23 @@ static public class log
|
||||
s_delegates.Add( cb );
|
||||
}
|
||||
|
||||
public static char getSymbol( LogType type )
|
||||
public static char getSymbol( Levels type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case LogType.Trace:
|
||||
case Levels.Trace:
|
||||
return ' ';
|
||||
case LogType.Debug:
|
||||
case Levels.Debug:
|
||||
return ' ';
|
||||
case LogType.Info:
|
||||
case Levels.Info:
|
||||
return ' ';
|
||||
case LogType.High:
|
||||
case Levels.High:
|
||||
return '+';
|
||||
case LogType.Warn:
|
||||
case Levels.Warn:
|
||||
return '+';
|
||||
case LogType.Error:
|
||||
case Levels.Error:
|
||||
return '*';
|
||||
case LogType.Fatal:
|
||||
case Levels.Fatal:
|
||||
return '*';
|
||||
default:
|
||||
return '?';
|
||||
@ -787,35 +948,35 @@ static public class log
|
||||
|
||||
private static void setConsoleColor( log.LogEvent evt )
|
||||
{
|
||||
switch( evt.LogType )
|
||||
switch( evt.Levels )
|
||||
{
|
||||
case log.LogType.Trace:
|
||||
case log.Levels.Trace:
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
case log.LogType.Debug:
|
||||
case log.Levels.Debug:
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
break;
|
||||
case log.LogType.Info:
|
||||
case log.Levels.Info:
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
break;
|
||||
case log.LogType.High:
|
||||
case log.Levels.High:
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
break;
|
||||
case log.LogType.Warn:
|
||||
case log.Levels.Warn:
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
break;
|
||||
case log.LogType.Error:
|
||||
case log.Levels.Error:
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
case log.LogType.Fatal:
|
||||
case log.Levels.Fatal:
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
|
||||
case log.LogType.Invalid:
|
||||
case log.LogType.Time:
|
||||
case log.LogType.Raw:
|
||||
case log.Levels.Invalid:
|
||||
case log.Levels.Time:
|
||||
case log.Levels.Raw:
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
break;
|
||||
|
||||
@ -831,11 +992,11 @@ static public class log
|
||||
|
||||
static public string headerPrint( LogEvent evt )
|
||||
{
|
||||
if( evt.LogType != LogType.Raw )
|
||||
if( evt.Levels != Levels.Raw )
|
||||
{
|
||||
var span = evt.Time - s_startTime;
|
||||
|
||||
char sym = getSymbol( evt.LogType );
|
||||
char sym = getSymbol( evt.Levels );
|
||||
|
||||
var truncatedCat = evt.Cat.Substring( 0, Math.Min( s_catWidth, evt.Cat.Length ) );
|
||||
|
||||
@ -854,13 +1015,13 @@ static public class log
|
||||
|
||||
static public string headerFile( LogEvent evt )
|
||||
{
|
||||
if( evt.LogType != LogType.Raw )
|
||||
if( evt.Levels != Levels.Raw )
|
||||
{
|
||||
try
|
||||
{
|
||||
var span = evt.Time - s_startTime;
|
||||
|
||||
char sym = getSymbol( evt.LogType );
|
||||
char sym = getSymbol( evt.Levels );
|
||||
|
||||
var truncatedCat = evt.Cat.Substring( 0, Math.Min( s_catWidth, evt.Cat.Length ) );
|
||||
|
||||
@ -910,7 +1071,7 @@ static public class log
|
||||
|
||||
var msg = evt.Msg;
|
||||
|
||||
if( ( string.IsNullOrWhiteSpace( msg ) && evt.LogType != LogType.Raw ) || msg.Contains( (char)0 ) )
|
||||
if( ( string.IsNullOrWhiteSpace( msg ) && evt.Levels != Levels.Raw ) || msg.Contains( (char)0 ) )
|
||||
{
|
||||
msg = "B R O K E N msg";
|
||||
}
|
||||
@ -948,12 +1109,12 @@ static public class log
|
||||
{
|
||||
s_lastDisplaySeconds = curSeconds;
|
||||
|
||||
var minuteEvt = new LogEvent( LogType.Raw, $"T I M E ==> {evt.Time.Hour.ToString( "00" )}:{evt.Time.Minute.ToString( "00" )}:{evt.Time.Second.ToString( "00" )}.{evt.Time.Millisecond.ToString( "000" )} : {evt.Time.ToShortDateString()}", "", 0, "", "lib.time", "", null );
|
||||
var minuteEvt = new LogEvent( Levels.Raw, $"T I M E ==> {evt.Time.Hour.ToString( "00" )}:{evt.Time.Minute.ToString( "00" )}:{evt.Time.Second.ToString( "00" )}.{evt.Time.Millisecond.ToString( "000" )} : {evt.Time.ToShortDateString()}", "", 0, "", "lib.time", "", null );
|
||||
minuteEvt.Time = evt.Time;
|
||||
writeSpecialEvent( minuteEvt );
|
||||
}
|
||||
|
||||
if( evt.LogType != LogType.Raw )
|
||||
if( evt.Levels != Levels.Raw )
|
||||
{
|
||||
var curSecond = (int)span.TotalSeconds;
|
||||
|
||||
@ -1034,7 +1195,7 @@ static public class log
|
||||
|
||||
public static void WriteToConsole( LogEvent evt )
|
||||
{
|
||||
char sym = getSymbol( evt.LogType );
|
||||
char sym = getSymbol( evt.Levels );
|
||||
|
||||
var truncatedCat = evt.Cat.Substring( 0, Math.Min( 8, evt.Cat.Length ) );
|
||||
|
||||
|
||||
52
time/Time.cs
Normal file
52
time/Time.cs
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace time;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// This class should be static. It will then only run occasionally, based on passed in TimeSpan
|
||||
public class EveryState
|
||||
{
|
||||
public DateTime Last { get; private set; }
|
||||
public TimeSpan Interval { get; private set; }
|
||||
public bool Latch { get; private set; }
|
||||
|
||||
public EveryState( TimeSpan interval )
|
||||
{
|
||||
Last = DateTime.Now;
|
||||
Interval = interval;
|
||||
}
|
||||
|
||||
//For first active call, Latch will be true. It will remain true until the next first call to Every
|
||||
// This allows cohesive between different functions
|
||||
public void Every( Action fn )
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
|
||||
if( now - Last >= Interval )
|
||||
{
|
||||
Latch = true;
|
||||
fn();
|
||||
Last = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
Latch = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Contingent( Action fn )
|
||||
{
|
||||
if( Latch )
|
||||
{
|
||||
fn();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user