x) Change crlf to lf
This commit is contained in:
parent
d90eaf5954
commit
cf519ce865
982
logging/Log.cs
982
logging/Log.cs
@ -1,487 +1,495 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
static public class log
|
||||
{
|
||||
|
||||
|
||||
[Flags]
|
||||
public enum LogType
|
||||
{
|
||||
Invalid = 0,
|
||||
Trace = 1,
|
||||
Debug = 2,
|
||||
Info = 3,
|
||||
High = 4,
|
||||
Warn = 5,
|
||||
Error = 6,
|
||||
Fatal = 7,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum Endpoints
|
||||
{
|
||||
None = 0,
|
||||
|
||||
File = 1 << 0,
|
||||
Console = 1 << 1,
|
||||
|
||||
All = File | Console,
|
||||
}
|
||||
|
||||
|
||||
public struct LogEvent
|
||||
{
|
||||
public DateTime Time;
|
||||
public LogType LogType;
|
||||
public string Msg;
|
||||
public string Path;
|
||||
public int Line;
|
||||
public string Member;
|
||||
|
||||
public string Cat;
|
||||
public object Obj;
|
||||
|
||||
|
||||
|
||||
static ImmutableDictionary<int, string> s_shortname = ImmutableDictionary<int, string>.Empty;
|
||||
|
||||
|
||||
public LogEvent( LogType logType, string msg, string path, int line, string member, string cat, object obj )
|
||||
{
|
||||
|
||||
//Cache the automatic category names
|
||||
if( string.IsNullOrEmpty( cat ) )
|
||||
{
|
||||
var pathHash = path.GetHashCode();
|
||||
if( s_shortname.TryGetValue( pathHash, out var autoCat ) )
|
||||
{
|
||||
cat = autoCat;
|
||||
}
|
||||
else
|
||||
{
|
||||
var pathPieces = path.Split( '\\' );
|
||||
|
||||
if(pathPieces.Length < 2)
|
||||
{
|
||||
pathPieces = path.Split('/');
|
||||
}
|
||||
|
||||
|
||||
var lastDir = pathPieces[ pathPieces.Length - 2 ];
|
||||
|
||||
ImmutableInterlocked.AddOrUpdate( ref s_shortname, pathHash, lastDir, ( key, value ) => { return lastDir; } );
|
||||
|
||||
cat = lastDir;
|
||||
}
|
||||
}
|
||||
|
||||
Time = DateTime.Now;
|
||||
LogType = logType;
|
||||
Msg = msg;
|
||||
Path = path;
|
||||
Line = line;
|
||||
Member = member;
|
||||
Cat = cat;
|
||||
Obj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void Log_delegate( LogEvent evt );
|
||||
|
||||
|
||||
|
||||
|
||||
static public void create( string filename, Endpoints endpoints )
|
||||
{
|
||||
startup( filename, endpoints );
|
||||
}
|
||||
|
||||
|
||||
static public void destroy()
|
||||
{
|
||||
string msg = "==============================================================================\nLogfile shutdown at " + DateTime.Now.ToString();
|
||||
|
||||
var evt = CreateLogEvent( LogType.Info, msg, "System", null );
|
||||
|
||||
s_events.Enqueue( evt );
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
static LogEvent CreateLogEvent( LogType logType, string msg, string cat, object obj, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
var logEvent = new LogEvent( logType, msg, path, line, member, cat, obj );
|
||||
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
static internal ConcurrentQueue<LogEvent> s_events = new ConcurrentQueue<LogEvent>();
|
||||
|
||||
static private Thread s_thread;
|
||||
|
||||
/*
|
||||
static public Log log
|
||||
{
|
||||
get
|
||||
{
|
||||
return s_log;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
// Forwards.
|
||||
static public void fatal( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Fatal, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void error( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Error, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void warn( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Warn, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void high(string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "")
|
||||
{
|
||||
logBase(msg, LogType.High, path, line, member, cat, obj);
|
||||
}
|
||||
|
||||
static public void info( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Info, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void debug( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Debug, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void trace( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Trace, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static object s_lock = new object();
|
||||
|
||||
static public void logBase_old( string msg, LogType type = LogType.Debug, string path = "", int line = -1, string member = "", string cat = "unk", object obj = null )
|
||||
{
|
||||
// @@@@@ TODO Get rid of this lock.
|
||||
var evt = new LogEvent( type, msg, path, line, member, cat, obj );
|
||||
|
||||
lock( s_lock )
|
||||
{
|
||||
writeToAll( evt );
|
||||
}
|
||||
}
|
||||
|
||||
static public void logBase( string msg, LogType type = LogType.Debug, string path = "", int line = -1, string member = "", string cat = "unk", object obj = null )
|
||||
{
|
||||
var evt = new LogEvent( type, msg, path, line, member, cat, obj );
|
||||
|
||||
s_events.Enqueue( evt );
|
||||
}
|
||||
|
||||
|
||||
static public void logProps( object obj, string header, LogType type = LogType.Debug, string cat = "", string prefix = "", [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
var list = refl.GetAllProperties( obj.GetType() );
|
||||
|
||||
lock( s_lock )
|
||||
{
|
||||
var evt = new LogEvent( type, header, path, line, member, cat, obj );
|
||||
//var evt = CreateLogEvent( type, header, cat, obj );
|
||||
|
||||
//lock( s_log )
|
||||
{
|
||||
//var evt = CreateLogEvent( type, header, cat, obj );
|
||||
|
||||
s_events.Enqueue( evt );
|
||||
|
||||
//s_log.writeToAll( evt );
|
||||
|
||||
foreach( var pi in list )
|
||||
{
|
||||
try
|
||||
{
|
||||
var v = pi.GetValue( obj );
|
||||
|
||||
logBase( $"{prefix}{pi.Name} = {v}", type, path, line, member, cat );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
logBase( $"Exception processing {pi.Name} {ex.Message}", LogType.Error, "log" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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 ) )
|
||||
{
|
||||
|
||||
if( !value.Equals( notExpectedValue ) )
|
||||
{
|
||||
log.info( $"Properly got {value}{trueString}" );
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn( $"Got {notExpectedValue} instead of {value}{falseString}" );
|
||||
}
|
||||
}
|
||||
|
||||
static Endpoints s_endpoints = Endpoints.Console;
|
||||
|
||||
static void startup( string filename, Endpoints endpoints )
|
||||
{
|
||||
var start = new ThreadStart( run );
|
||||
|
||||
s_thread = new Thread( start );
|
||||
s_thread.Start();
|
||||
|
||||
//TODO: Fix this so itll work without a directory.
|
||||
Directory.CreateDirectory( Path.GetDirectoryName( filename ) );
|
||||
|
||||
string dir = Path.GetDirectoryName( filename );
|
||||
|
||||
if( dir.Length > 0 )
|
||||
{
|
||||
Directory.CreateDirectory( dir );
|
||||
}
|
||||
|
||||
s_stream = new FileStream( filename, FileMode.Append, FileAccess.Write );
|
||||
s_writer = new StreamWriter( s_stream );
|
||||
|
||||
s_errorStream = new FileStream( filename + ".error", FileMode.Append, FileAccess.Write );
|
||||
s_errorWriter = new StreamWriter( s_errorStream );
|
||||
|
||||
//Debug.Listeners.Add( this );
|
||||
|
||||
//var evt = CreateLogEvent( LogType.Info, $"startup", "System", null );
|
||||
|
||||
//s_events.Enqueue( evt );
|
||||
|
||||
/*
|
||||
if( (endpoints & Endpoints.Console) == Endpoints.Console )
|
||||
{
|
||||
addDelegate(WriteToConsole);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
info( $"startup" );
|
||||
|
||||
}
|
||||
|
||||
static bool s_running = true;
|
||||
|
||||
static void run()
|
||||
{
|
||||
while( s_running )
|
||||
{
|
||||
while( s_events.TryDequeue( out var evt ) )
|
||||
{
|
||||
writeToAll( evt );
|
||||
}
|
||||
|
||||
// TODO PERF Replace this with a semaphore/mutex
|
||||
Thread.Sleep( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void stop()
|
||||
{
|
||||
s_running = false;
|
||||
|
||||
s_writer.Close();
|
||||
s_stream.Close();
|
||||
|
||||
s_errorWriter.Close();
|
||||
s_errorStream.Close();
|
||||
|
||||
}
|
||||
|
||||
static public void addDelegate( Log_delegate cb )
|
||||
{
|
||||
s_delegates.Add( cb );
|
||||
}
|
||||
|
||||
public static char getSymbol( LogType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case LogType.Trace:
|
||||
return ' ';
|
||||
case LogType.Debug:
|
||||
return ' ';
|
||||
case LogType.Info:
|
||||
return ' ';
|
||||
case LogType.High:
|
||||
return '+';
|
||||
case LogType.Warn:
|
||||
return '+';
|
||||
case LogType.Error:
|
||||
return '*';
|
||||
case LogType.Fatal:
|
||||
return '*';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
private static void setConsoleColor( log.LogEvent evt )
|
||||
{
|
||||
switch( evt.LogType )
|
||||
{
|
||||
case log.LogType.Trace:
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
case log.LogType.Debug:
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
break;
|
||||
case log.LogType.Info:
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
break;
|
||||
case log.LogType.High:
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
break;
|
||||
case log.LogType.Warn:
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
break;
|
||||
case log.LogType.Error:
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
case log.LogType.Fatal:
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static public string msgHeader( LogEvent evt )
|
||||
{
|
||||
char sym = getSymbol( evt.LogType );
|
||||
|
||||
var truncatedCat = evt.Cat.Substring( 0, Math.Min( 8, evt.Cat.Length ) );
|
||||
|
||||
var msgHdr = string.Format( "{0,-8}{1}| ", truncatedCat, sym );
|
||||
|
||||
return msgHdr;
|
||||
}
|
||||
|
||||
static public string msgFrom( LogEvent evt )
|
||||
{
|
||||
var msgHdr = msgHeader( evt );
|
||||
|
||||
string finalLine = $"{msgHdr}{evt.Msg}";
|
||||
|
||||
return finalLine;
|
||||
}
|
||||
|
||||
static private void writeToAll( LogEvent evt )
|
||||
{
|
||||
try
|
||||
{
|
||||
// _SHOULDNT_ need this since we lock at the top.
|
||||
//lock( this )
|
||||
{
|
||||
|
||||
var finalLine = msgFrom( evt );
|
||||
|
||||
//Console.WriteLine( finalMsg );
|
||||
//Console.Out.Write( finalMsg );
|
||||
|
||||
if( (s_endpoints & Endpoints.File) == Endpoints.File )
|
||||
{
|
||||
s_writer.WriteLine( finalLine );
|
||||
}
|
||||
|
||||
if( (s_endpoints & Endpoints.Console) == Endpoints.Console )
|
||||
{
|
||||
setConsoleColor( evt );
|
||||
Console.WriteLine( finalLine );
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
|
||||
//Debug.WriteLine( finalLine );
|
||||
|
||||
s_writer.Flush();
|
||||
|
||||
foreach( Log_delegate cb in s_delegates )
|
||||
{
|
||||
cb( evt );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( $"Exception {ex}" );
|
||||
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( $"Exception {ex}" );
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteToConsole(LogEvent evt)
|
||||
{
|
||||
char sym = getSymbol(evt.LogType);
|
||||
|
||||
var truncatedCat = evt.Cat.Substring(0, Math.Min(8, evt.Cat.Length));
|
||||
|
||||
string finalLine = string.Format("{0,-8}{1}| {2}", truncatedCat, sym, evt.Msg);
|
||||
|
||||
Console.WriteLine(finalLine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static Stream s_stream;
|
||||
private static StreamWriter s_writer;
|
||||
|
||||
private static Stream s_errorStream;
|
||||
private static StreamWriter s_errorWriter;
|
||||
|
||||
private static ArrayList s_delegates = new ArrayList();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
static public class log
|
||||
{
|
||||
|
||||
|
||||
[Flags]
|
||||
public enum LogType
|
||||
{
|
||||
Invalid = 0,
|
||||
Trace = 1,
|
||||
Debug = 2,
|
||||
Info = 3,
|
||||
High = 4,
|
||||
Warn = 5,
|
||||
Error = 6,
|
||||
Fatal = 7,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum Endpoints
|
||||
{
|
||||
None = 0,
|
||||
|
||||
File = 1 << 0,
|
||||
Console = 1 << 1,
|
||||
|
||||
All = File | Console,
|
||||
}
|
||||
|
||||
|
||||
public struct LogEvent
|
||||
{
|
||||
public DateTime Time;
|
||||
public LogType LogType;
|
||||
public string Msg;
|
||||
public string Path;
|
||||
public int Line;
|
||||
public string Member;
|
||||
|
||||
public string Cat;
|
||||
public object Obj;
|
||||
|
||||
|
||||
|
||||
static ImmutableDictionary<int, string> s_shortname = ImmutableDictionary<int, string>.Empty;
|
||||
|
||||
|
||||
public LogEvent( LogType logType, string msg, string path, int line, string member, string cat, object obj )
|
||||
{
|
||||
|
||||
//Cache the automatic category names
|
||||
if( string.IsNullOrEmpty( cat ) )
|
||||
{
|
||||
var pathHash = path.GetHashCode();
|
||||
if( s_shortname.TryGetValue( pathHash, out var autoCat ) )
|
||||
{
|
||||
cat = autoCat;
|
||||
}
|
||||
else
|
||||
{
|
||||
var pathPieces = path.Split( '\\' );
|
||||
|
||||
if(pathPieces.Length < 2)
|
||||
{
|
||||
pathPieces = path.Split('/');
|
||||
}
|
||||
|
||||
|
||||
var lastDir = pathPieces[ pathPieces.Length - 2 ];
|
||||
|
||||
ImmutableInterlocked.AddOrUpdate( ref s_shortname, pathHash, lastDir, ( key, value ) => { return lastDir; } );
|
||||
|
||||
cat = lastDir;
|
||||
}
|
||||
}
|
||||
|
||||
Time = DateTime.Now;
|
||||
LogType = logType;
|
||||
Msg = msg;
|
||||
Path = path;
|
||||
Line = line;
|
||||
Member = member;
|
||||
Cat = cat;
|
||||
Obj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void Log_delegate( LogEvent evt );
|
||||
|
||||
|
||||
|
||||
|
||||
static public void create( string filename, Endpoints endpoints )
|
||||
{
|
||||
startup( filename, endpoints );
|
||||
}
|
||||
|
||||
|
||||
static public void destroy()
|
||||
{
|
||||
string msg = "==============================================================================\nLogfile shutdown at " + DateTime.Now.ToString();
|
||||
|
||||
var evt = CreateLogEvent( LogType.Info, msg, "System", null );
|
||||
|
||||
s_events.Enqueue( evt );
|
||||
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
static LogEvent CreateLogEvent( LogType logType, string msg, string cat, object obj, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
var logEvent = new LogEvent( logType, msg, path, line, member, cat, obj );
|
||||
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
static internal ConcurrentQueue<LogEvent> s_events = new ConcurrentQueue<LogEvent>();
|
||||
|
||||
static private Thread s_thread;
|
||||
|
||||
/*
|
||||
static public Log log
|
||||
{
|
||||
get
|
||||
{
|
||||
return s_log;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static public string relativePath( string fullPath )
|
||||
{
|
||||
var cwd = Directory.GetCurrentDirectory();
|
||||
|
||||
var rel = fullPath.Substring( cwd.Length );
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
// Forwards.
|
||||
static public void fatal( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Fatal, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void error( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Error, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void warn( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Warn, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void high(string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "")
|
||||
{
|
||||
logBase(msg, LogType.High, path, line, member, cat, obj);
|
||||
}
|
||||
|
||||
static public void info( string msg, string cat = "", object obj = null,
|
||||
[CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Info, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void debug( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Debug, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static public void trace( string msg, string cat = "", object obj = null, [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
logBase( msg, LogType.Trace, path, line, member, cat, obj );
|
||||
}
|
||||
|
||||
static object s_lock = new object();
|
||||
|
||||
static public void logBase_old( string msg, LogType type = LogType.Debug, string path = "", int line = -1, string member = "", string cat = "unk", object obj = null )
|
||||
{
|
||||
// @@@@@ TODO Get rid of this lock.
|
||||
var evt = new LogEvent( type, msg, path, line, member, cat, obj );
|
||||
|
||||
lock( s_lock )
|
||||
{
|
||||
writeToAll( evt );
|
||||
}
|
||||
}
|
||||
|
||||
static public void logBase( string msg, LogType type = LogType.Debug, string path = "", int line = -1, string member = "", string cat = "unk", object obj = null )
|
||||
{
|
||||
var evt = new LogEvent( type, msg, path, line, member, cat, obj );
|
||||
|
||||
s_events.Enqueue( evt );
|
||||
}
|
||||
|
||||
|
||||
static public void logProps( object obj, string header, LogType type = LogType.Debug, string cat = "", string prefix = "", [CallerFilePath] string path = "", [CallerLineNumber] int line = -1, [CallerMemberName] string member = "" )
|
||||
{
|
||||
var list = refl.GetAllProperties( obj.GetType() );
|
||||
|
||||
lock( s_lock )
|
||||
{
|
||||
var evt = new LogEvent( type, header, path, line, member, cat, obj );
|
||||
//var evt = CreateLogEvent( type, header, cat, obj );
|
||||
|
||||
//lock( s_log )
|
||||
{
|
||||
//var evt = CreateLogEvent( type, header, cat, obj );
|
||||
|
||||
s_events.Enqueue( evt );
|
||||
|
||||
//s_log.writeToAll( evt );
|
||||
|
||||
foreach( var pi in list )
|
||||
{
|
||||
try
|
||||
{
|
||||
var v = pi.GetValue( obj );
|
||||
|
||||
logBase( $"{prefix}{pi.Name} = {v}", type, path, line, member, cat );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
logBase( $"Exception processing {pi.Name} {ex.Message}", LogType.Error, "log" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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 ) )
|
||||
{
|
||||
|
||||
if( !value.Equals( notExpectedValue ) )
|
||||
{
|
||||
log.info( $"Properly got {value}{trueString}" );
|
||||
}
|
||||
else
|
||||
{
|
||||
log.warn( $"Got {notExpectedValue} instead of {value}{falseString}" );
|
||||
}
|
||||
}
|
||||
|
||||
static Endpoints s_endpoints = Endpoints.Console;
|
||||
|
||||
static void startup( string filename, Endpoints endpoints )
|
||||
{
|
||||
var start = new ThreadStart( run );
|
||||
|
||||
s_thread = new Thread( start );
|
||||
s_thread.Start();
|
||||
|
||||
//TODO: Fix this so itll work without a directory.
|
||||
Directory.CreateDirectory( Path.GetDirectoryName( filename ) );
|
||||
|
||||
string dir = Path.GetDirectoryName( filename );
|
||||
|
||||
if( dir.Length > 0 )
|
||||
{
|
||||
Directory.CreateDirectory( dir );
|
||||
}
|
||||
|
||||
s_stream = new FileStream( filename, FileMode.Append, FileAccess.Write );
|
||||
s_writer = new StreamWriter( s_stream );
|
||||
|
||||
s_errorStream = new FileStream( filename + ".error", FileMode.Append, FileAccess.Write );
|
||||
s_errorWriter = new StreamWriter( s_errorStream );
|
||||
|
||||
//Debug.Listeners.Add( this );
|
||||
|
||||
//var evt = CreateLogEvent( LogType.Info, $"startup", "System", null );
|
||||
|
||||
//s_events.Enqueue( evt );
|
||||
|
||||
/*
|
||||
if( (endpoints & Endpoints.Console) == Endpoints.Console )
|
||||
{
|
||||
addDelegate(WriteToConsole);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
info( $"startup" );
|
||||
|
||||
}
|
||||
|
||||
static bool s_running = true;
|
||||
|
||||
static void run()
|
||||
{
|
||||
while( s_running )
|
||||
{
|
||||
while( s_events.TryDequeue( out var evt ) )
|
||||
{
|
||||
writeToAll( evt );
|
||||
}
|
||||
|
||||
// TODO PERF Replace this with a semaphore/mutex
|
||||
Thread.Sleep( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void stop()
|
||||
{
|
||||
s_running = false;
|
||||
|
||||
s_writer.Close();
|
||||
s_stream.Close();
|
||||
|
||||
s_errorWriter.Close();
|
||||
s_errorStream.Close();
|
||||
|
||||
}
|
||||
|
||||
static public void addDelegate( Log_delegate cb )
|
||||
{
|
||||
s_delegates.Add( cb );
|
||||
}
|
||||
|
||||
public static char getSymbol( LogType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case LogType.Trace:
|
||||
return ' ';
|
||||
case LogType.Debug:
|
||||
return ' ';
|
||||
case LogType.Info:
|
||||
return ' ';
|
||||
case LogType.High:
|
||||
return '+';
|
||||
case LogType.Warn:
|
||||
return '+';
|
||||
case LogType.Error:
|
||||
return '*';
|
||||
case LogType.Fatal:
|
||||
return '*';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
private static void setConsoleColor( log.LogEvent evt )
|
||||
{
|
||||
switch( evt.LogType )
|
||||
{
|
||||
case log.LogType.Trace:
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
case log.LogType.Debug:
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
break;
|
||||
case log.LogType.Info:
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
break;
|
||||
case log.LogType.High:
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
break;
|
||||
case log.LogType.Warn:
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
break;
|
||||
case log.LogType.Error:
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
case log.LogType.Fatal:
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.BackgroundColor = ConsoleColor.DarkGray;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static public string msgHeader( LogEvent evt )
|
||||
{
|
||||
char sym = getSymbol( evt.LogType );
|
||||
|
||||
var truncatedCat = evt.Cat.Substring( 0, Math.Min( 8, evt.Cat.Length ) );
|
||||
|
||||
var msgHdr = string.Format( "{0,-8}{1}| ", truncatedCat, sym );
|
||||
|
||||
return msgHdr;
|
||||
}
|
||||
|
||||
static public string msgFrom( LogEvent evt )
|
||||
{
|
||||
var msgHdr = msgHeader( evt );
|
||||
|
||||
string finalLine = $"{msgHdr}{evt.Msg}";
|
||||
|
||||
return finalLine;
|
||||
}
|
||||
|
||||
static private void writeToAll( LogEvent evt )
|
||||
{
|
||||
try
|
||||
{
|
||||
// _SHOULDNT_ need this since we lock at the top.
|
||||
//lock( this )
|
||||
{
|
||||
|
||||
var finalLine = msgFrom( evt );
|
||||
|
||||
//Console.WriteLine( finalMsg );
|
||||
//Console.Out.Write( finalMsg );
|
||||
|
||||
if( (s_endpoints & Endpoints.File) == Endpoints.File )
|
||||
{
|
||||
s_writer.WriteLine( finalLine );
|
||||
}
|
||||
|
||||
if( (s_endpoints & Endpoints.Console) == Endpoints.Console )
|
||||
{
|
||||
setConsoleColor( evt );
|
||||
Console.WriteLine( finalLine );
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
|
||||
//Debug.WriteLine( finalLine );
|
||||
|
||||
s_writer.Flush();
|
||||
|
||||
foreach( Log_delegate cb in s_delegates )
|
||||
{
|
||||
cb( evt );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Console.WriteLine( $"Exception {ex}" );
|
||||
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( "EXCEPTION DURING LOGGING" );
|
||||
Debug.WriteLine( $"Exception {ex}" );
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteToConsole(LogEvent evt)
|
||||
{
|
||||
char sym = getSymbol(evt.LogType);
|
||||
|
||||
var truncatedCat = evt.Cat.Substring(0, Math.Min(8, evt.Cat.Length));
|
||||
|
||||
string finalLine = string.Format("{0,-8}{1}| {2}", truncatedCat, sym, evt.Msg);
|
||||
|
||||
Console.WriteLine(finalLine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static Stream s_stream;
|
||||
private static StreamWriter s_writer;
|
||||
|
||||
private static Stream s_errorStream;
|
||||
private static StreamWriter s_errorWriter;
|
||||
|
||||
private static ArrayList s_delegates = new ArrayList();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user