|
|
|
|
|
using System;
|
|
|
using System.IO;
|
|
|
using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
using System.Reflection;
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
using JM.LinqFaster;
|
|
|
|
|
|
/* Tiny log library inspired by Python's logging and Glögi.
|
|
|
*/
|
|
|
|
|
|
namespace isometricparkfna
|
|
|
{
|
|
|
public enum LogLevel
|
|
|
{
|
|
|
Critical,
|
|
|
Error,
|
|
|
Warning,
|
|
|
Success,
|
|
|
Info,
|
|
|
Debug,
|
|
|
Trace,
|
|
|
Spy
|
|
|
}
|
|
|
|
|
|
public struct LogEntry
|
|
|
{
|
|
|
public DateTime timestamp;
|
|
|
public string message;
|
|
|
public LogLevel level;
|
|
|
public ITuple data;
|
|
|
}
|
|
|
public class Logging
|
|
|
{
|
|
|
|
|
|
// private
|
|
|
//
|
|
|
|
|
|
#if DEBUG
|
|
|
public static LogLevel minimumConsoleLevel = LogLevel.Debug;
|
|
|
#else
|
|
|
public static LogLevel minimumConsoleLevel = LogLevel.Success;
|
|
|
#endif
|
|
|
|
|
|
public static List<LogEntry> entries = new List<LogEntry>();
|
|
|
public static string logFileName = string.Format("log_{0:yyyyMMdd_HHmm}.txt", DateTime.Now);
|
|
|
|
|
|
public static StreamWriter logFile = File.CreateText(logFileName);
|
|
|
private static Dictionary<LogLevel, (ConsoleColor, ConsoleColor)> mappings = new Dictionary<LogLevel, (ConsoleColor, ConsoleColor)>
|
|
|
{
|
|
|
{LogLevel.Critical, (ConsoleColor.White, ConsoleColor.Red)},
|
|
|
{LogLevel.Error, (ConsoleColor.Red, ConsoleColor.Black)},
|
|
|
{LogLevel.Warning, (ConsoleColor.Yellow, ConsoleColor.Black)},
|
|
|
{LogLevel.Success, (ConsoleColor.Green, ConsoleColor.Black)},
|
|
|
{LogLevel.Info, (ConsoleColor.Blue, ConsoleColor.Black)},
|
|
|
{LogLevel.Debug, (ConsoleColor.White, ConsoleColor.Blue)},
|
|
|
{LogLevel.Trace, (ConsoleColor.White, ConsoleColor.Yellow)},
|
|
|
{LogLevel.Spy, (ConsoleColor.Black, ConsoleColor.White)},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
private static void Log_(LogLevel level, string message,
|
|
|
int lineNumber, string caller, string path)
|
|
|
{
|
|
|
var timestamp = DateTime.Now;
|
|
|
|
|
|
if ((level <= minimumConsoleLevel)
|
|
|
|| level == LogLevel.Spy)
|
|
|
{
|
|
|
var start_foreground = Console.ForegroundColor;
|
|
|
var start_background = Console.BackgroundColor;
|
|
|
|
|
|
var (new_foreground, new_background) = Logging.mappings[level];
|
|
|
|
|
|
Console.ForegroundColor = new_foreground;
|
|
|
Console.BackgroundColor = new_background;
|
|
|
//29/Apr/2021 22:43:30
|
|
|
Console.Out.Write(string.Format("[{0}] {1}", timestamp.ToString("s"), level.ToString()));
|
|
|
|
|
|
Console.ForegroundColor = start_foreground;
|
|
|
Console.BackgroundColor = start_background;
|
|
|
|
|
|
Console.Out.WriteLine(string.Format(" {0} [{1}:{2}]", message, path, lineNumber));
|
|
|
}
|
|
|
|
|
|
logFile.WriteLine(string.Format("[{0}] {1} {2} [{3}:{4}]", timestamp.ToString("s"), level.ToString(), message, path, lineNumber));
|
|
|
|
|
|
|
|
|
Logging.entries.Add(new LogEntry
|
|
|
{
|
|
|
timestamp = timestamp,
|
|
|
level = level,
|
|
|
message = message
|
|
|
});
|
|
|
}
|
|
|
|
|
|
private static void Log_<T>(LogLevel level, string message, T data,
|
|
|
int lineNumber, string caller, string path)
|
|
|
where T : ITuple
|
|
|
{
|
|
|
// Logging.entries.Add(data);
|
|
|
// var d = data.GetType().GetProperties().ToDictionary(Info => Info.Name, Info => Info.GetValue(data));
|
|
|
// var data_strings = data.GetType().GetProperties().Select(Info => Info.Name + "=" + Info.GetValue(data).ToString());
|
|
|
// var data_string = string.Join(", ", data_strings);
|
|
|
// var str = String.Format("{0} {1}", message, data_string);
|
|
|
Logging.Log_(level, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
private static void Log_(LogLevel level, string message,
|
|
|
int lineNumber, string caller, string path, params object[] objects)
|
|
|
{
|
|
|
String.Format(message, objects);
|
|
|
Logging.Log_(level, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Log(LogLevel level, string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(level, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
public static void Log<T>(LogLevel level, string message, T data,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
//Constrain to Tuples and tuple-likes:
|
|
|
where T : ITuple, IStructuralEquatable, IStructuralComparable
|
|
|
{
|
|
|
Logging.Log_(level, message, data, lineNumber, caller, path);
|
|
|
}*/
|
|
|
|
|
|
public static void Log<T>(LogLevel level, string message, T data,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
//Constrain to Tuples and tuple-likes:
|
|
|
where T : class
|
|
|
{
|
|
|
|
|
|
var properties = new List<string>();
|
|
|
|
|
|
foreach (var property in typeof(T).GetProperties())
|
|
|
{
|
|
|
properties.Add(property.ToString() + "=" + property.GetValue(data));
|
|
|
}
|
|
|
|
|
|
var message_data = message + " {" + String.Join(", ", properties) + "}";
|
|
|
|
|
|
Logging.Log_(level, message_data, lineNumber, caller, path);
|
|
|
|
|
|
}
|
|
|
|
|
|
public static void Log(LogLevel level, string message,
|
|
|
object[] format,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(level, message, lineNumber, caller, path, format);
|
|
|
}
|
|
|
|
|
|
public static void Critical(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Critical, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Error(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Error, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Warning(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Warning, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
|
|
|
public static void Success(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Success, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Info(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Info, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Debug(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Debug, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Trace(string message,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = "")
|
|
|
{
|
|
|
|
|
|
Logging.Log_(LogLevel.Trace, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Spy(object value,
|
|
|
string name,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = ""
|
|
|
|
|
|
)
|
|
|
{
|
|
|
string message = string.Format("{0} ({1}) = {2}",
|
|
|
value.GetType().ToString(), name, value.ToString());
|
|
|
Logging.Log_(LogLevel.Spy, message, lineNumber, caller, path);
|
|
|
}
|
|
|
|
|
|
public static void Spy<T>(T value,
|
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
|
[CallerMemberName] string caller = null,
|
|
|
[CallerFilePath] string path = ""
|
|
|
|
|
|
) where T : class
|
|
|
{
|
|
|
// var properties = typeof(T).GetProperties();
|
|
|
// string message = string.Format("{0} = {1}",
|
|
|
// value.ToString(), .ToString() );
|
|
|
// var message = String.Join(", ", (object[])properties);
|
|
|
//
|
|
|
|
|
|
var properties = new List<string>();
|
|
|
|
|
|
foreach (var property in typeof(T).GetProperties())
|
|
|
{
|
|
|
properties.Add(property.ToString() + "=" + property.GetValue(value));
|
|
|
}
|
|
|
|
|
|
var message = "{" + String.Join(", ", properties) + "}";
|
|
|
|
|
|
Logging.Log_(LogLevel.Spy, message, lineNumber, caller, path);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|