mirror of
https://git.lewd.wtf/PGR/ascnet
synced 2025-12-13 03:14:34 +01:00
add proper logger, saves to file as well
This commit is contained in:
9
AscNet.Logging/AscNet.Logging.csproj
Normal file
9
AscNet.Logging/AscNet.Logging.csproj
Normal file
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
18
AscNet.Logging/ILogger.cs
Normal file
18
AscNet.Logging/ILogger.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace AscNet.Logging
|
||||
{
|
||||
public interface ILogger
|
||||
{
|
||||
void Debug(string message, string memberName = "");
|
||||
|
||||
void Error(string message, Exception ex = null, string memberName = "");
|
||||
|
||||
void Fatal(string message, Exception ex = null, string memberName = "");
|
||||
|
||||
void Info(string message, string memberName = "");
|
||||
|
||||
void Dispose();
|
||||
|
||||
void Warn(string message, Exception ex = null, string memberName = "");
|
||||
}
|
||||
|
||||
}
|
||||
13
AscNet.Logging/LogLevel.cs
Normal file
13
AscNet.Logging/LogLevel.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace AscNet.Logging
|
||||
{
|
||||
public enum LogLevel : byte
|
||||
{
|
||||
OFF = 0,
|
||||
FATAL = 8,
|
||||
ERROR = 16,
|
||||
WARN = 32,
|
||||
INFO = 64,
|
||||
DEBUG = 128,
|
||||
ALL = 255
|
||||
}
|
||||
}
|
||||
201
AscNet.Logging/Logger.cs
Normal file
201
AscNet.Logging/Logger.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
namespace AscNet.Logging
|
||||
{
|
||||
public class Logger : ILogger
|
||||
{
|
||||
#region Members
|
||||
|
||||
private readonly string _logFilePath = "log.log";
|
||||
private readonly string _loggerName = "DefaultLogger";
|
||||
private readonly LogLevel _logLevel = LogLevel.ALL;
|
||||
private readonly LogLevel _fileLogLevel = LogLevel.ALL;
|
||||
private bool _disposed;
|
||||
private Type _loggerType;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Instantiation
|
||||
|
||||
public Logger(string logFilePath)
|
||||
{
|
||||
_logFilePath = logFilePath;
|
||||
}
|
||||
|
||||
public Logger(string logFilePath, LogLevel logLevel) : this(logFilePath) => _logLevel = logLevel;
|
||||
|
||||
public Logger(Type loggerType, string logFilePath, LogLevel logLevel) : this(logFilePath, logLevel)
|
||||
{
|
||||
_loggerType = loggerType;
|
||||
_loggerName = loggerType.Namespace.RemoveBefore('.');
|
||||
}
|
||||
|
||||
public Logger(Type loggerType, LogLevel logLevel, LogLevel fileLogLevel)
|
||||
{
|
||||
_logLevel = logLevel;
|
||||
_fileLogLevel = fileLogLevel;
|
||||
_loggerType = loggerType;
|
||||
_loggerName = loggerType.Name;
|
||||
}
|
||||
|
||||
public Logger(Type loggerType, string loggerName, LogLevel logLevel, LogLevel fileLogLevel)
|
||||
{
|
||||
_logLevel = logLevel;
|
||||
_fileLogLevel = fileLogLevel;
|
||||
_loggerType = loggerType;
|
||||
_loggerName = loggerName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Debug(string message, string memberName = "")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
Append(message, memberName, LogLevel.DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public void Error(string message, Exception ex = null, string memberName = "")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
if (ex == null)
|
||||
{
|
||||
Append(message, memberName, LogLevel.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
Append(message + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace, memberName,
|
||||
LogLevel.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fatal(string message, Exception ex = null, string memberName = "")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
if (ex == null)
|
||||
{
|
||||
Append(message, memberName, LogLevel.FATAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Append(message + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace, memberName,
|
||||
LogLevel.FATAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Info(string message, string memberName = "")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
Append(message, memberName, LogLevel.INFO);
|
||||
}
|
||||
}
|
||||
|
||||
public void Trace(string message, Exception ex)
|
||||
{
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Warn(string message, Exception ex = null, string memberName = "")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
if (ex == null)
|
||||
{
|
||||
Append(message, memberName, LogLevel.WARN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Append(message + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace, memberName,
|
||||
LogLevel.WARN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
ThreadSafeStreamWriter.Instance.Dispose();
|
||||
}
|
||||
|
||||
_loggerType = null;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Append(string message, string memberName, LogLevel logLevel)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(memberName))
|
||||
{
|
||||
AppendToConsole($"[{memberName}][{_loggerName}]: {message}", logLevel);
|
||||
AppendToFile($"[{memberName}][{_loggerName}]: {message}", logLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendToConsole($"[{_loggerName}]: {message}", logLevel);
|
||||
AppendToFile($"[{_loggerName}]: {message}", logLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendToConsole(string message, LogLevel logLevel)
|
||||
{
|
||||
if (logLevel <= _logLevel)
|
||||
{
|
||||
switch (logLevel)
|
||||
{
|
||||
case LogLevel.DEBUG:
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
break;
|
||||
|
||||
case LogLevel.INFO:
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
break;
|
||||
|
||||
case LogLevel.WARN:
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
break;
|
||||
|
||||
case LogLevel.ERROR:
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
break;
|
||||
|
||||
case LogLevel.FATAL:
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null);
|
||||
}
|
||||
|
||||
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}][{logLevel}]{message}");
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendToFile(string message, LogLevel logLevel)
|
||||
{
|
||||
if (logLevel <= _fileLogLevel)
|
||||
{
|
||||
ThreadSafeStreamWriter.Instance.AppendLine($"[{DateTime.Now:dd.MM.yyyy HH:mm:ss.fff}][{_loggerType.Namespace}][{_loggerName}][{logLevel}]{message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
23
AscNet.Logging/LoggerFactory.cs
Normal file
23
AscNet.Logging/LoggerFactory.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace AscNet.Logging
|
||||
{
|
||||
public static class LoggerFactory
|
||||
{
|
||||
public static ILogger Logger { get; set; }
|
||||
|
||||
public static void Debug(string message, [CallerMemberName] string memberName = "") => Logger.Debug(message, memberName);
|
||||
|
||||
public static void Error(string message, Exception ex = null, [CallerMemberName] string memberName = "") => Logger.Error(message, ex, memberName);
|
||||
|
||||
public static void Fatal(string message, Exception ex = null, [CallerMemberName] string memberName = "") => Logger.Fatal(message, ex, memberName);
|
||||
|
||||
public static void Info(string message, [CallerMemberName] string memberName = "") => Logger.Info(message, memberName);
|
||||
|
||||
public static void Warn(string message, Exception ex = null, [CallerMemberName] string memberName = "") => Logger.Warn(message, ex, memberName);
|
||||
|
||||
public static void Dispose() => Logger.Dispose();
|
||||
|
||||
public static void InitializeLogger(ILogger log) => Logger = log;
|
||||
}
|
||||
}
|
||||
16
AscNet.Logging/LoggingExtensions.cs
Normal file
16
AscNet.Logging/LoggingExtensions.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace AscNet.Logging
|
||||
{
|
||||
public static class LoggingExtensions
|
||||
{
|
||||
public static string RemoveBefore(this string value, char character)
|
||||
{
|
||||
int index = value.LastIndexOf(character);
|
||||
if (index > 0)
|
||||
{
|
||||
value = value[(index + 1)..];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
AscNet.Logging/ThreadSafeStreamWriter.cs
Normal file
60
AscNet.Logging/ThreadSafeStreamWriter.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
namespace AscNet.Logging
|
||||
{
|
||||
public class ThreadSafeStreamWriter : IDisposable
|
||||
{
|
||||
private static ThreadSafeStreamWriter? _instance;
|
||||
|
||||
private static StreamWriter _writer;
|
||||
|
||||
private bool disposedValue;
|
||||
|
||||
// TODO: add support for configuring
|
||||
private string _logFilePath = "log.log";
|
||||
|
||||
private object _lock = new object();
|
||||
|
||||
public ThreadSafeStreamWriter()
|
||||
{
|
||||
_writer = new StreamWriter(_logFilePath, true);
|
||||
#if !RELEASE
|
||||
_writer.AutoFlush = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static ThreadSafeStreamWriter Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return _instance ??= new ThreadSafeStreamWriter();
|
||||
}
|
||||
}
|
||||
|
||||
public void AppendLine(string line)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_writer.WriteLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_writer.Flush();
|
||||
_writer.Close();
|
||||
_writer.Dispose();
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user