Files
Voile/DaggerFramework/Source/Utils/Logger.cs
2024-01-21 18:12:42 +01:00

153 lines
4.7 KiB
C#

#pragma warning disable CA2211
using System.Runtime.CompilerServices;
namespace DaggerFramework.Utils
{
public class Logger
{
public static Action<string, LogLevel>? OnLog;
public static string LogPath { get; set; } = "Logs/";
/// <summary>
/// Maximum amount of log files in a log folder. If it reaches the limit, all logs will be written to <c>dagger-latest.log</c> instead of creating a new one.
/// </summary>
public static int MaxLogFiles { get; set; } = 5;
/// <summary>
/// Specifies the logging level. In release builds, the log level is <c>Error</c>. In debug, the log level is <c>Echo</c>.
/// </summary>
public static LogLevel LogLevel = LogLevel.Error;
/// <summary>
/// Specifies if the logger should write to file.
/// </summary>
public static bool WriteToFile = true;
public Logger(string className)
{
_className = className;
if (WriteToFile && !_logCreated)
{
var dirInfo = Directory.CreateDirectory(LogPath);
var files = dirInfo.GetFiles();
string logName = $"dagger-{DateFormat}-{TimeFormat}.log".Replace(':', '.');
if (files.Length >= MaxLogFiles)
{
logName = "dagger-latest.log";
}
var path = Path.Combine(LogPath, logName);
if (File.Exists(path))
{
File.Delete(path);
}
_fileStream = File.Create(path);
_fileWriter = new StreamWriter(_fileStream);
_logCreated = true;
}
#if DEBUG
LogLevel = LogLevel.Echo;
#endif
}
public void Echo(string what)
{
string message = string.Format(EchoFormat, TimeFormat, what);
LogFile(message);
LogConsole(what, LogLevel.Echo);
OnLog?.Invoke(what, LogLevel.Echo);
}
public void Info(string what, [CallerMemberName] string method = "")
{
LogLevel logType = LogLevel.Info;
string message = string.Format(LogFormat, TimeFormat, logType.ToString(), _className, method, what);
LogFile(message);
LogConsole(message, logType);
OnLog?.Invoke(message, logType);
}
public void Warn(string what, [CallerMemberName] string method = "")
{
LogLevel logType = LogLevel.Warn;
string message = string.Format(LogFormat, TimeFormat, logType.ToString(), _className, method, what);
LogFile(message);
LogConsole(message, logType);
OnLog?.Invoke(message, logType);
}
public void Error(string what, [CallerMemberName] string method = "")
{
LogLevel logType = LogLevel.Error;
string message = string.Format(LogFormat, TimeFormat, logType.ToString(), _className, method, what);
LogFile(message);
LogConsole(message, logType);
OnLog?.Invoke(message, logType);
}
private static string TimeFormat => $"{DateTime.Now:HH:mm:ffff}";
private static string DateFormat => $"{DateTime.Now:d:M:yyyy:}";
private static string LogFormat => "({0}) [{1}/{2}/{3}] {4}";
private static string EchoFormat => "({0}) {1}";
private static void LogConsole(string what, LogLevel logType)
{
if (LogLevel < logType) return;
Console.ForegroundColor = ConsoleColorForLog(logType);
Console.WriteLine(what);
Console.ForegroundColor = ConsoleColor.White;
}
private static ConsoleColor ConsoleColorForLog(LogLevel logType)
{
ConsoleColor color = ConsoleColor.White;
switch (logType)
{
case LogLevel.Info:
color = ConsoleColor.Cyan;
break;
case LogLevel.Warn:
color = ConsoleColor.Yellow;
break;
case LogLevel.Error:
color = ConsoleColor.Red;
break;
}
return color;
}
private void LogFile(string message)
{
if (!WriteToFile || _fileWriter is null) return;
_fileWriter.WriteLine(message);
_fileWriter.Flush();
}
private readonly string _className;
private static bool _logCreated;
private static FileStream? _fileStream;
private static StreamWriter? _fileWriter;
}
public enum LogLevel
{
Error,
Warn,
Info,
Echo,
}
}