x) Change crlf to lf

This commit is contained in:
Marc Hernandez 2024-04-07 19:21:33 -07:00
parent d90eaf5954
commit cf519ce865

View File

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