This commit is contained in:
2024-05-27 20:11:11 +02:00
parent c997b6c1a2
commit 005d91c199
19 changed files with 717 additions and 435 deletions

View File

@@ -3,7 +3,7 @@
<TargetFrameworks>.netstandard2.1; net6.0; net7.0; net8.0; net4.8;</TargetFrameworks> <TargetFrameworks>.netstandard2.1; net6.0; net7.0; net8.0; net4.8;</TargetFrameworks>
<ApplicationIcon>icon.ico</ApplicationIcon> <ApplicationIcon>icon.ico</ApplicationIcon>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<FileVersion>1.2.9</FileVersion> <FileVersion>1.3.0</FileVersion>
<Authors>EonaCat (Jeroen Saey)</Authors> <Authors>EonaCat (Jeroen Saey)</Authors>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Company>EonaCat (Jeroen Saey)</Company> <Company>EonaCat (Jeroen Saey)</Company>
@@ -24,7 +24,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<EVRevisionFormat>1.2.9+{chash:10}.{c:ymd}</EVRevisionFormat> <EVRevisionFormat>1.3.0+{chash:10}.{c:ymd}</EVRevisionFormat>
<EVDefault>true</EVDefault> <EVDefault>true</EVDefault>
<EVInfo>true</EVInfo> <EVInfo>true</EVInfo>
<EVTagMatch>v[0-9]*</EVTagMatch> <EVTagMatch>v[0-9]*</EVTagMatch>

View File

@@ -26,9 +26,16 @@ public static class FileLoggerFactoryExtensions
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder, string filenamePrefix = null, public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder, string filenamePrefix = null,
FileLoggerOptions fileLoggerOptions = null) FileLoggerOptions fileLoggerOptions = null)
{ {
if (fileLoggerOptions == null) fileLoggerOptions = new FileLoggerOptions(); if (fileLoggerOptions == null)
{
fileLoggerOptions = new FileLoggerOptions();
}
if (!string.IsNullOrWhiteSpace(filenamePrefix))
{
fileLoggerOptions.FileNamePrefix = filenamePrefix;
}
if (!string.IsNullOrWhiteSpace(filenamePrefix)) fileLoggerOptions.FileNamePrefix = filenamePrefix;
builder.AddEonaCatFileLogger(options => builder.AddEonaCatFileLogger(options =>
{ {
options.FileNamePrefix = fileLoggerOptions.FileNamePrefix; options.FileNamePrefix = fileLoggerOptions.FileNamePrefix;
@@ -55,7 +62,11 @@ public static class FileLoggerFactoryExtensions
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder, public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder,
Action<FileLoggerOptions> configure) Action<FileLoggerOptions> configure)
{ {
if (configure == null) throw new ArgumentNullException(nameof(configure)); if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
builder.AddEonaCatFileLogger(); builder.AddEonaCatFileLogger();
builder.Services.Configure(configure); builder.Services.Configure(configure);

View File

@@ -30,7 +30,10 @@ public class FileLoggerOptions : BatchingLoggerOptions
set set
{ {
if (value <= 0) if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FileSizeLimit)} must be positive."); throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FileSizeLimit)} must be positive.");
}
_fileSizeLimit = value; _fileSizeLimit = value;
} }
} }
@@ -46,8 +49,11 @@ public class FileLoggerOptions : BatchingLoggerOptions
set set
{ {
if (value <= 0) if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), throw new ArgumentOutOfRangeException(nameof(value),
$"{nameof(RetainedFileCountLimit)} must be positive."); $"{nameof(RetainedFileCountLimit)} must be positive.");
}
_retainedFileCountLimit = value; _retainedFileCountLimit = value;
} }
} }
@@ -74,7 +80,10 @@ public class FileLoggerOptions : BatchingLoggerOptions
set set
{ {
if (value <= 0) if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(MaxRolloverFiles)} must be positive."); throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(MaxRolloverFiles)} must be positive.");
}
_maxRolloverFiles = value; _maxRolloverFiles = value;
} }
} }

View File

@@ -63,8 +63,12 @@ public class FileLoggerProvider : BatchingLoggerProvider
{ {
var dir = Path.GetDirectoryName(_logFile); var dir = Path.GetDirectoryName(_logFile);
if (!string.IsNullOrEmpty(dir)) if (!string.IsNullOrEmpty(dir))
{
if (!Directory.Exists(dir)) if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir); Directory.CreateDirectory(dir);
}
}
} }
} }
} }
@@ -128,7 +132,10 @@ public class FileLoggerProvider : BatchingLoggerProvider
private async Task<bool> TryWriteToFileAsync(CancellationToken cancellationToken) private async Task<bool> TryWriteToFileAsync(CancellationToken cancellationToken)
{ {
if (!_buffer.ContainsKey(LogFile)) return true; if (!_buffer.ContainsKey(LogFile))
{
return true;
}
var tries = 0; var tries = 0;
var completed = false; var completed = false;
@@ -193,7 +200,10 @@ public class FileLoggerProvider : BatchingLoggerProvider
{ {
var hasPrefix = !string.IsNullOrWhiteSpace(_fileNamePrefix); var hasPrefix = !string.IsNullOrWhiteSpace(_fileNamePrefix);
if (hasPrefix) if (hasPrefix)
{
return Path.Combine(_path, $"{_fileNamePrefix}_{group.Year:0000}{group.Month:00}{group.Day:00}.log"); return Path.Combine(_path, $"{_fileNamePrefix}_{group.Year:0000}{group.Month:00}{group.Day:00}.log");
}
return Path.Combine(_path, $"{group.Year:0000}{group.Month:00}{group.Day:00}.log"); return Path.Combine(_path, $"{group.Year:0000}{group.Month:00}{group.Day:00}.log");
} }
@@ -260,7 +270,7 @@ public class FileLoggerProvider : BatchingLoggerProvider
private async Task WriteEndMessageAsync(string logFilePath) private async Task WriteEndMessageAsync(string logFilePath)
{ {
var stopMessage = LogHelper.GetStopMessage(); var stopMessage = LogHelper.GetStopMessage();
stopMessage = LogHelper.FormatMessageWithHeader(LoggerSettings, ELogType.INFO, stopMessage, CurrentDateTme); stopMessage = LogHelper.FormatMessageWithHeader(LoggerSettings, ELogType.INFO, stopMessage, CurrentDateTme, Category);
using (var file = new StreamWriter(logFilePath, true)) using (var file = new StreamWriter(logFilePath, true))
{ {
@@ -292,13 +302,20 @@ public class FileLoggerProvider : BatchingLoggerProvider
IEnumerable<FileInfo> files = null; IEnumerable<FileInfo> files = null;
if (hasPrefix) if (hasPrefix)
{
files = new DirectoryInfo(_path).GetFiles(_fileNamePrefix + "*"); files = new DirectoryInfo(_path).GetFiles(_fileNamePrefix + "*");
}
else else
{
files = new DirectoryInfo(_path).GetFiles("*"); files = new DirectoryInfo(_path).GetFiles("*");
}
files = files.OrderByDescending(file => file.Name).Skip(_maxRetainedFiles); files = files.OrderByDescending(file => file.Name).Skip(_maxRetainedFiles);
foreach (var item in files) item.Delete(); foreach (var item in files)
{
item.Delete();
}
} }
} }
} }

View File

@@ -4,67 +4,70 @@ using EonaCat.Logger.Extensions;
using EonaCat.Logger.Managers; using EonaCat.Logger.Managers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace EonaCat.Logger.EonaCatCoreLogger.Internal; namespace EonaCat.Logger.EonaCatCoreLogger.Internal
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
public class BatchingLogger : ILogger
{ {
private readonly string _category; // This file is part of the EonaCat project(s) which is released under the Apache License.
private readonly BatchingLoggerProvider _provider; // See the LICENSE file or go to https://EonaCat.com/License for full license details.
private LoggerSettings _loggerSettings;
public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings) public class BatchingLogger : ILogger
{ {
_loggerSettings = loggerSettings; private readonly string _category;
_provider = loggerProvider; private readonly BatchingLoggerProvider _provider;
_category = categoryName; private readonly LoggerSettings _loggerSettings;
}
private DateTimeOffset CurrentDateTimeOffset => public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings)
_loggerSettings.UseLocalTime ? DateTimeOffset.Now : DateTimeOffset.UtcNow;
private DateTime CurrentDateTme => _loggerSettings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel != LogLevel.None;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
Func<TState, Exception, string> formatter)
{
Log(CurrentDateTimeOffset, logLevel, eventId, state, exception, formatter);
}
public void Log<TState>(DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel)) return;
if (_loggerSettings == null) _loggerSettings = new LoggerSettings();
var message = LogHelper.FormatMessageWithHeader(_loggerSettings, logLevel.FromLogLevel(),
formatter(state, exception), timestamp.DateTime) + Environment.NewLine;
if (exception != null) message = exception.FormatExceptionToMessage() + Environment.NewLine;
_provider.AddMessage(timestamp, message);
var currentMessage = new EonaCatLogMessage
{ {
DateTime = timestamp.DateTime, _provider = loggerProvider ?? throw new ArgumentNullException(nameof(loggerProvider));
Message = message, _category = categoryName ?? throw new ArgumentNullException(nameof(categoryName));
LogType = logLevel.FromLogLevel() _loggerSettings = loggerSettings ?? throw new ArgumentNullException(nameof(loggerSettings));
}; }
currentMessage.Origin = string.IsNullOrWhiteSpace(_loggerSettings.LogOrigin) private DateTimeOffset CurrentDateTimeOffset => CurrentDateTime;
? "BatchingLogger"
: _loggerSettings.LogOrigin; private DateTime CurrentDateTime => _loggerSettings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;
_loggerSettings?.OnLogEvent(currentMessage);
public IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
var timestamp = CurrentDateTimeOffset;
Log(timestamp, logLevel, eventId, state, exception, formatter, _category);
}
public void Log<TState>(DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter, string category)
{
if (!IsEnabled(logLevel))
{
return;
}
string message = exception != null
? exception.FormatExceptionToMessage() + Environment.NewLine
: formatter(state, exception);
message = LogHelper.FormatMessageWithHeader(_loggerSettings, logLevel.FromLogLevel(), message, timestamp.DateTime, category)
+ Environment.NewLine;
_provider.AddMessage(timestamp, message);
var currentMessage = new EonaCatLogMessage
{
DateTime = timestamp.DateTime,
Message = message,
LogType = logLevel.FromLogLevel(),
Origin = string.IsNullOrWhiteSpace(_loggerSettings.LogOrigin) ? "BatchingLogger" : _loggerSettings.LogOrigin
};
_loggerSettings.OnLogEvent(currentMessage);
}
} }
} }

View File

@@ -18,7 +18,10 @@ public class BatchingLoggerOptions
set set
{ {
if (value <= TimeSpan.Zero) if (value <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FlushPeriod)} must be positive."); throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FlushPeriod)} must be positive.");
}
_flushPeriod = value; _flushPeriod = value;
} }
} }

View File

@@ -23,16 +23,23 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
private Task _outputTask; private Task _outputTask;
private object _writeLock = new object(); private object _writeLock = new object();
private bool _isDisposing; private bool _isDisposing;
protected string Category;
protected BatchingLoggerProvider(IOptions<BatchingLoggerOptions> options) protected BatchingLoggerProvider(IOptions<BatchingLoggerOptions> options)
{ {
var loggerOptions = options.Value; var loggerOptions = options.Value;
if (loggerOptions.FlushPeriod <= TimeSpan.Zero) if (loggerOptions.FlushPeriod <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(loggerOptions.FlushPeriod), throw new ArgumentOutOfRangeException(nameof(loggerOptions.FlushPeriod),
$"{nameof(loggerOptions.FlushPeriod)} must be longer than zero."); $"{nameof(loggerOptions.FlushPeriod)} must be longer than zero.");
}
if (options.Value is FileLoggerOptions fileLoggerOptions)
{
UseLocalTime = fileLoggerOptions.UseLocalTime;
}
if (options.Value is FileLoggerOptions fileLoggerOptions) UseLocalTime = fileLoggerOptions.UseLocalTime;
_batchSize = loggerOptions.BatchSize; _batchSize = loggerOptions.BatchSize;
StartAsync().ConfigureAwait(false); StartAsync().ConfigureAwait(false);
@@ -47,7 +54,10 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
{ {
get get
{ {
if (_loggerSettings != null) return _loggerSettings; if (_loggerSettings != null)
{
return _loggerSettings;
}
_loggerSettings = new LoggerSettings(); _loggerSettings = new LoggerSettings();
_loggerSettings.UseLocalTime = UseLocalTime; _loggerSettings.UseLocalTime = UseLocalTime;
@@ -73,6 +83,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
public ILogger CreateLogger(string categoryName) public ILogger CreateLogger(string categoryName)
{ {
Category = categoryName;
return new BatchingLogger(this, categoryName, LoggerSettings); return new BatchingLogger(this, categoryName, LoggerSettings);
} }

View File

@@ -10,7 +10,9 @@ public static class ExceptionExtensions
public static string FormatExceptionToMessage(this Exception exception, string module = null, string method = null) public static string FormatExceptionToMessage(this Exception exception, string module = null, string method = null)
{ {
if (exception == null) if (exception == null)
{
return string.Empty; return string.Empty;
}
var st = new StackTrace(exception, true); var st = new StackTrace(exception, true);
var frame = st.GetFrame(0); var frame = st.GetFrame(0);
@@ -28,9 +30,15 @@ public static class ExceptionExtensions
sb.AppendLine(); sb.AppendLine();
sb.AppendLine("--- Exception details provided by EonaCatLogger ---"); sb.AppendLine("--- Exception details provided by EonaCatLogger ---");
if (!string.IsNullOrEmpty(module)) if (!string.IsNullOrEmpty(module))
{
sb.AppendLine(" Module : " + module); sb.AppendLine(" Module : " + module);
}
if (!string.IsNullOrEmpty(method)) if (!string.IsNullOrEmpty(method))
{
sb.AppendLine(" Method : " + method); sb.AppendLine(" Method : " + method);
}
sb.Append(" Type : ").AppendLine(exception.GetType().ToString()); sb.Append(" Type : ").AppendLine(exception.GetType().ToString());
sb.Append(" Data : ").AppendLine(exception.Data != null && exception.Data.Count > 0 sb.Append(" Data : ").AppendLine(exception.Data != null && exception.Data.Count > 0
? FormatExceptionData(exception.Data) ? FormatExceptionData(exception.Data)
@@ -54,10 +62,12 @@ public static class ExceptionExtensions
var sb = new StringBuilder(); var sb = new StringBuilder();
foreach (DictionaryEntry entry in data) foreach (DictionaryEntry entry in data)
{
sb.Append(" | ") sb.Append(" | ")
.Append(entry.Key) .Append(entry.Key)
.Append(": ") .Append(": ")
.AppendLine(entry.Value.ToString()); .AppendLine(entry.Value.ToString());
}
return sb.ToString(); return sb.ToString();
} }

View File

@@ -13,16 +13,26 @@ public class OffsetStream : Stream
{ {
if (stream.CanSeek) if (stream.CanSeek)
{ {
if (offset > stream.Length) throw new EndOfStreamException(); if (offset > stream.Length)
{
throw new EndOfStreamException();
}
BaseStreamOffset = offset; BaseStreamOffset = offset;
if (length > stream.Length - offset) throw new EndOfStreamException(); if (length > stream.Length - offset)
{
throw new EndOfStreamException();
}
if (length == 0) if (length == 0)
{
Length1 = stream.Length - offset; Length1 = stream.Length - offset;
}
else else
{
Length1 = length; Length1 = length;
}
} }
else else
{ {
@@ -49,9 +59,15 @@ public class OffsetStream : Stream
set set
{ {
if (value > Length1) throw new EndOfStreamException(); if (value > Length1)
{
throw new EndOfStreamException();
}
if (!BaseStream.CanSeek) throw new NotSupportedException("Cannot seek stream."); if (!BaseStream.CanSeek)
{
throw new NotSupportedException("Cannot seek stream.");
}
Position1 = value; Position1 = value;
} }
@@ -71,11 +87,18 @@ public class OffsetStream : Stream
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (Disposed) return; if (Disposed)
{
return;
}
if (disposing) if (disposing)
{
if (OwnStream & (BaseStream != null)) if (OwnStream & (BaseStream != null))
{
BaseStream.Dispose(); BaseStream.Dispose();
}
}
Disposed = true; Disposed = true;
@@ -84,20 +107,35 @@ public class OffsetStream : Stream
public override void Flush() public override void Flush()
{ {
if (ReadOnly) throw new IOException("OffsetStream is read only."); if (ReadOnly)
{
throw new IOException("OffsetStream is read only.");
}
BaseStream.Flush(); BaseStream.Flush();
} }
public override int Read(byte[] buffer, int offset, int count) public override int Read(byte[] buffer, int offset, int count)
{ {
if (count < 1) throw new ArgumentOutOfRangeException("Count cannot be less than 1."); if (count < 1)
{
throw new ArgumentOutOfRangeException("Count cannot be less than 1.");
}
if (Position1 >= Length1) return 0; if (Position1 >= Length1)
{
return 0;
}
if (count > Length1 - Position1) count = Convert.ToInt32(Length1 - Position1); if (count > Length1 - Position1)
{
count = Convert.ToInt32(Length1 - Position1);
}
if (BaseStream.CanSeek) BaseStream.Position = BaseStreamOffset + Position1; if (BaseStream.CanSeek)
{
BaseStream.Position = BaseStreamOffset + Position1;
}
var bytesRead = BaseStream.Read(buffer, offset, count); var bytesRead = BaseStream.Read(buffer, offset, count);
Position1 += bytesRead; Position1 += bytesRead;
@@ -107,7 +145,10 @@ public class OffsetStream : Stream
public override long Seek(long offset, SeekOrigin origin) public override long Seek(long offset, SeekOrigin origin)
{ {
if (!BaseStream.CanSeek) throw new IOException("Stream is not seekable."); if (!BaseStream.CanSeek)
{
throw new IOException("Stream is not seekable.");
}
long pos; long pos;
@@ -130,7 +171,10 @@ public class OffsetStream : Stream
break; break;
} }
if (pos < 0 || pos >= Length1) throw new EndOfStreamException("OffsetStream reached begining/end of stream."); if (pos < 0 || pos >= Length1)
{
throw new EndOfStreamException("OffsetStream reached begining/end of stream.");
}
Position1 = pos; Position1 = pos;
@@ -139,7 +183,10 @@ public class OffsetStream : Stream
public override void SetLength(long value) public override void SetLength(long value)
{ {
if (ReadOnly) throw new IOException("OffsetStream is read only."); if (ReadOnly)
{
throw new IOException("OffsetStream is read only.");
}
BaseStream.SetLength(BaseStreamOffset + value); BaseStream.SetLength(BaseStreamOffset + value);
Length1 = value; Length1 = value;
@@ -147,15 +194,27 @@ public class OffsetStream : Stream
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
if (ReadOnly) throw new IOException("OffsetStream is read only."); if (ReadOnly)
{
throw new IOException("OffsetStream is read only.");
}
if (count < 1) return; if (count < 1)
{
return;
}
var pos = Position1 + count; var pos = Position1 + count;
if (pos > Length1) throw new EndOfStreamException("OffsetStream reached end of stream."); if (pos > Length1)
{
throw new EndOfStreamException("OffsetStream reached end of stream.");
}
if (BaseStream.CanSeek) BaseStream.Position = BaseStreamOffset + Position1; if (BaseStream.CanSeek)
{
BaseStream.Position = BaseStreamOffset + Position1;
}
BaseStream.Write(buffer, offset, count); BaseStream.Write(buffer, offset, count);
Position1 = pos; Position1 = pos;
@@ -175,9 +234,15 @@ public class OffsetStream : Stream
public void WriteTo(Stream stream, int bufferSize) public void WriteTo(Stream stream, int bufferSize)
{ {
if (!BaseStream.CanSeek) throw new IOException("Stream is not seekable."); if (!BaseStream.CanSeek)
{
throw new IOException("Stream is not seekable.");
}
if (Length1 < bufferSize) bufferSize = Convert.ToInt32(Length1); if (Length1 < bufferSize)
{
bufferSize = Convert.ToInt32(Length1);
}
var previousPosition = Position1; var previousPosition = Position1;
Position1 = 0; Position1 = 0;

View File

@@ -42,7 +42,11 @@ public class GrayLogServer
set set
{ {
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Hostname)); if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException(nameof(Hostname));
}
_Hostname = value; _Hostname = value;
SetUdp(); SetUdp();
@@ -57,7 +61,11 @@ public class GrayLogServer
get => _Port; get => _Port;
set set
{ {
if (value < 0) throw new ArgumentException("Port must be zero or greater."); if (value < 0)
{
throw new ArgumentException("Port must be zero or greater.");
}
_Port = value; _Port = value;
SetUdp(); SetUdp();

View File

@@ -80,10 +80,15 @@ public static class ColorHelper
public static int HexColorToArgb(string htmlColor, bool requireHexSpecified = false, int defaultAlpha = 0xFF) public static int HexColorToArgb(string htmlColor, bool requireHexSpecified = false, int defaultAlpha = 0xFF)
{ {
if (string.IsNullOrEmpty(htmlColor)) throw new ArgumentNullException(nameof(htmlColor)); if (string.IsNullOrEmpty(htmlColor))
{
throw new ArgumentNullException(nameof(htmlColor));
}
if (!htmlColor.StartsWith("#") && requireHexSpecified) if (!htmlColor.StartsWith("#") && requireHexSpecified)
{
throw new ArgumentException($"Provided parameter '{htmlColor}' is not valid"); throw new ArgumentException($"Provided parameter '{htmlColor}' is not valid");
}
htmlColor = htmlColor.TrimStart('#'); htmlColor = htmlColor.TrimStart('#');

View File

@@ -26,10 +26,17 @@ internal static class LogHelper
internal static event EventHandler<ErrorMessage> OnException; internal static event EventHandler<ErrorMessage> OnException;
internal static string FormatMessageWithHeader(LoggerSettings settings, ELogType logType, string currentMessage, internal static string FormatMessageWithHeader(LoggerSettings settings, ELogType logType, string currentMessage,
DateTime dateTime) DateTime dateTime, string category = null)
{ {
if (string.IsNullOrWhiteSpace(currentMessage)) if (string.IsNullOrWhiteSpace(currentMessage))
{
return currentMessage; return currentMessage;
}
if (string.IsNullOrWhiteSpace(category))
{
category = "General";
}
var sb = new StringBuilder(settings?.HeaderFormat ?? "[EonaCatLogger]"); var sb = new StringBuilder(settings?.HeaderFormat ?? "[EonaCatLogger]");
@@ -37,11 +44,14 @@ internal static class LogHelper
dateTime.ToString(settings?.TimestampFormat ?? "yyyy-MM-dd HH:mm:ss") + " " + dateTime.ToString(settings?.TimestampFormat ?? "yyyy-MM-dd HH:mm:ss") + " " +
(settings?.UseLocalTime ?? false ? "[LOCAL]" : "[UTC]")) (settings?.UseLocalTime ?? false ? "[LOCAL]" : "[UTC]"))
.Replace("{host}", $"[Host:{Dns.GetHostName()}]") .Replace("{host}", $"[Host:{Dns.GetHostName()}]")
.Replace("{category}", $"[Category:{category}]")
.Replace("{thread}", $"[ThreadId:{Environment.CurrentManagedThreadId}]") .Replace("{thread}", $"[ThreadId:{Environment.CurrentManagedThreadId}]")
.Replace("{sev}", $"[{logType}]"); .Replace("{sev}", $"[{logType}]");
if (!settings?.RemoveMessagePrefix ?? (false && !currentMessage.Contains("[EonaCatLogger]"))) if (!settings?.RemoveMessagePrefix ?? (false && !currentMessage.Contains("[EonaCatLogger]")))
{
sb.Insert(0, "[EonaCatLogger] "); sb.Insert(0, "[EonaCatLogger] ");
}
sb.Append(" ").Append(currentMessage); sb.Append(" ").Append(currentMessage);
@@ -51,7 +61,9 @@ internal static class LogHelper
internal static void SendToConsole(LoggerSettings settings, ELogType logType, string message, bool writeToConsole) internal static void SendToConsole(LoggerSettings settings, ELogType logType, string message, bool writeToConsole)
{ {
if (settings == null || !writeToConsole || string.IsNullOrWhiteSpace(message)) if (settings == null || !writeToConsole || string.IsNullOrWhiteSpace(message))
{
return; return;
}
if (settings.EnableColors && settings.Colors != null) if (settings.EnableColors && settings.Colors != null)
{ {
@@ -109,7 +121,10 @@ internal static class LogHelper
internal static void SendToFile(ILogger logger, LoggerSettings settings, ELogType logType, string message) internal static void SendToFile(ILogger logger, LoggerSettings settings, ELogType logType, string message)
{ {
if (logger == null || settings == null || !settings.EnableFileLogging || if (logger == null || settings == null || !settings.EnableFileLogging ||
string.IsNullOrWhiteSpace(message)) return; string.IsNullOrWhiteSpace(message))
{
return;
}
var logLevel = logType.ToLogLevel(); var logLevel = logType.ToLogLevel();
if (IsLogLevelEnabled(settings, logType)) if (IsLogLevelEnabled(settings, logType))
@@ -132,9 +147,14 @@ internal static class LogHelper
bool sendToSplunkServer) bool sendToSplunkServer)
{ {
if (settings == null || !sendToSplunkServer || splunkPayload == null) if (settings == null || !sendToSplunkServer || splunkPayload == null)
{
return; return;
}
if (settings.SplunkServers == null) settings.SplunkServers = new List<SplunkServer.SplunkServer>(); if (settings.SplunkServers == null)
{
settings.SplunkServers = new List<SplunkServer.SplunkServer>();
}
foreach (var splunkServer in settings.SplunkServers) foreach (var splunkServer in settings.SplunkServers)
{ {
@@ -154,12 +174,14 @@ internal static class LogHelper
var response = await splunkServer.SendAsync(splunkPayload); var response = await splunkServer.SendAsync(splunkPayload);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{
OnException?.Invoke(null, OnException?.Invoke(null,
new ErrorMessage new ErrorMessage
{ {
Message = Message =
$"Failed to send log to Splunk '{splunkServer.SplunkHecUrl}'. Status code: {response.StatusCode}" $"Failed to send log to Splunk '{splunkServer.SplunkHecUrl}'. Status code: {response.StatusCode}"
}); });
}
} }
catch (Exception exception) catch (Exception exception)
{ {
@@ -178,7 +200,9 @@ internal static class LogHelper
bool sendToSplunkServer) bool sendToSplunkServer)
{ {
if (settings == null || !sendToSplunkServer || string.IsNullOrWhiteSpace(message)) if (settings == null || !sendToSplunkServer || string.IsNullOrWhiteSpace(message))
{
return; return;
}
var splunkPayload = new SplunkPayload var splunkPayload = new SplunkPayload
{ {
@@ -194,9 +218,12 @@ internal static class LogHelper
string facility, string source, bool sendToGrayLogServer, string version = "1.1") string facility, string source, bool sendToGrayLogServer, string version = "1.1")
{ {
if (settings == null || !sendToGrayLogServer || string.IsNullOrWhiteSpace(message)) if (settings == null || !sendToGrayLogServer || string.IsNullOrWhiteSpace(message))
{
return; return;
}
foreach (var grayLogServer in settings.GrayLogServers ?? new List<GrayLogServer> { new("127.0.0.1") }) foreach (var grayLogServer in settings.GrayLogServers ?? new List<GrayLogServer> { new("127.0.0.1") })
{
try try
{ {
var gelfMessage = new var gelfMessage = new
@@ -223,15 +250,19 @@ internal static class LogHelper
$"Error while logging to GrayLog Server '{grayLogServer.Hostname}': {exception.Message}" $"Error while logging to GrayLog Server '{grayLogServer.Hostname}': {exception.Message}"
}); });
} }
}
} }
internal static async Task SendToSysLogServersAsync(LoggerSettings settings, string message, internal static async Task SendToSysLogServersAsync(LoggerSettings settings, string message,
bool sendToSyslogServers) bool sendToSyslogServers)
{ {
if (settings == null || !sendToSyslogServers || string.IsNullOrWhiteSpace(message)) if (settings == null || !sendToSyslogServers || string.IsNullOrWhiteSpace(message))
{
return; return;
}
foreach (var server in settings.SysLogServers ?? new List<SyslogServer> { new("127.0.0.1") }) foreach (var server in settings.SysLogServers ?? new List<SyslogServer> { new("127.0.0.1") })
{
try try
{ {
if (string.IsNullOrWhiteSpace(server.Hostname)) if (string.IsNullOrWhiteSpace(server.Hostname))
@@ -260,6 +291,7 @@ internal static class LogHelper
Message = $"Error while logging to SysLog Server '{server.Hostname}': {exception.Message}" Message = $"Error while logging to SysLog Server '{server.Hostname}': {exception.Message}"
}); });
} }
}
} }
internal static string GetStartupMessage() internal static string GetStartupMessage()

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -11,274 +12,309 @@ using EonaCat.Logger.Syslog;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace EonaCat.Logger.Managers; namespace EonaCat.Logger.Managers
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
public class LogManager : ILogManager, IDisposable
{ {
private static LogManager _instance; // This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
private readonly CancellationTokenSource _tokenSource = new(); public class LogManager : ILogManager, IDisposable
private DateTime _logDate;
private bool _isDisposing;
public LogManager(LoggerSettings settings, string serverIp, int serverPort)
{ {
if (string.IsNullOrEmpty(serverIp)) private static readonly Lazy<LogManager> _instance = new(() => new LogManager(CreateDefaultSettings()));
throw new ArgumentNullException(nameof(serverIp)); private readonly CancellationTokenSource _tokenSource = new();
private DateTime _logDate;
private bool _isDisposing;
private string _category;
if (serverPort < 0) public LogManager(LoggerSettings settings, string serverIp, int serverPort)
throw new ArgumentException("Server port must be zero or greater.");
settings.SysLogServers = new List<SyslogServer>
{ {
new(serverIp, serverPort) if (string.IsNullOrEmpty(serverIp))
};
Settings = settings;
SetupLogManager();
}
public LogManager(LoggerSettings settings)
{
Settings = settings;
SetupFileLogger(settings);
SetupLogManager();
LogHelper.OnException += LogHelper_OnException;
}
private DateTime CurrentDateTme => Settings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;
public ILoggerProvider LoggerProvider { get; private set; }
public ILoggerFactory LoggerFactory { get; private set; }
public ILogger Logger { get; private set; }
public string CurrentLogFile => LoggerProvider is FileLoggerProvider fileLoggerProvider
? fileLoggerProvider.LogFile
: string.Empty;
public bool IsRunning { get; private set; }
public static LogManager Instance => InstanceInit();
public LoggerSettings Settings { get; set; } = CreateDefaultSettings();
public void Dispose()
{
DisposeAsync(true).GetAwaiter().GetResult();
GC.SuppressFinalize(this);
}
public async Task WriteAsync(Exception exception, string module = null, string method = null,
bool criticalException = false,
bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null,
string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1")
{
if (exception == null)
{
return;
}
await WriteAsync(exception.FormatExceptionToMessage(module, method),
criticalException ? ELogType.CRITICAL : ELogType.ERROR, writeToConsole, sendToSysLogServers,
sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogFacility, grayLogSource,
grayLogVersion);
}
public async Task WriteAsync(string message, ELogType logType = ELogType.INFO, bool? writeToConsole = null,
bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string customSplunkSourceType = null,
bool? sendToGrayLogServers = null, string grayLogFacility = null, string grayLogSource = null,
string grayLogVersion = "1.1")
{
if (logType == ELogType.NONE)
return;
await InternalWriteAsync(CurrentDateTme, message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers,
customSplunkSourceType, sendToGrayLogServers, grayLogFacility, grayLogSource, grayLogVersion).ConfigureAwait(false);
}
public event EventHandler<ErrorMessage> OnException;
private static LogManager InstanceInit()
{
if (_instance == null) _instance = new LogManager(CreateDefaultSettings());
return _instance;
}
private static LoggerSettings CreateDefaultSettings()
{
var settings = new LoggerSettings();
settings.Id = "EonaCatLogger";
settings.MaxLogType = ELogType.INFO;
return settings;
}
protected virtual async Task DisposeAsync(bool disposing)
{
if (disposing)
{
_isDisposing = true;
await StopLoggingAsync().ConfigureAwait(false);
await Task.Delay(100).ConfigureAwait(false);
}
}
public async Task StartNewLogAsync()
{
if (_tokenSource.IsCancellationRequested) return;
if (IsRunning && CurrentDateTme.Date > _logDate.Date)
{
await StopLoggingAsync().ConfigureAwait(false);
}
IsRunning = true;
CreateLogger();
Directory.CreateDirectory(Settings.FileLoggerOptions.LogDirectory);
_logDate = CurrentDateTme;
}
private void CreateLogger()
{
// Dispose of previous ServiceProvider if it exists
LoggerProvider?.Dispose();
LoggerFactory?.Dispose();
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(Settings.MaxLogType.ToLogLevel())
.AddEonaCatFileLogger(configuration =>
{ {
var fileLoggerOptions = Settings.FileLoggerOptions; throw new ArgumentNullException(nameof(serverIp));
configuration.MaxWriteTries = fileLoggerOptions.MaxWriteTries; }
configuration.RetainedFileCountLimit = fileLoggerOptions.RetainedFileCountLimit;
configuration.FlushPeriod = fileLoggerOptions.FlushPeriod;
configuration.IsEnabled = fileLoggerOptions.IsEnabled;
configuration.BatchSize = fileLoggerOptions.BatchSize;
configuration.FileSizeLimit = fileLoggerOptions.FileSizeLimit;
configuration.LogDirectory = fileLoggerOptions.LogDirectory;
configuration.FileNamePrefix = fileLoggerOptions.FileNamePrefix;
configuration.MaxRolloverFiles = fileLoggerOptions.MaxRolloverFiles;
configuration.UseLocalTime = Settings.UseLocalTime;
}));
var serviceProvider = serviceCollection.BuildServiceProvider(); if (serverPort < 0)
LoggerProvider = serviceProvider.GetService<ILoggerProvider>(); {
LoggerFactory = serviceProvider.GetService<ILoggerFactory>(); throw new ArgumentException("Server port must be zero or greater.");
Logger = LoggerFactory.CreateLogger(Settings.Id); }
LogHelper.SendToFile(Logger, Settings, ELogType.INFO, LogHelper.GetStartupMessage());
}
settings.SysLogServers = new List<SyslogServer>
{
new(serverIp, serverPort)
};
private async Task InternalWriteAsync(DateTime dateTime, string message, ELogType logType = ELogType.INFO, Settings = settings;
bool? writeToConsole = null, bool? sendToSyslogServers = null, bool? sendToSplunkServers = null, SetupLogManager();
string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1")
{
if (string.IsNullOrEmpty(message) || logType == ELogType.NONE ||
(int)logType > (int)Settings.MaxLogType) return;
if (_isDisposing)
{
return;
} }
if (!IsRunning) public LogManager(LoggerSettings settings, string category = null)
{ {
await StartNewLogAsync().ConfigureAwait(false); _category = category;
if (string.IsNullOrWhiteSpace(category))
{
_category = "General";
}
Settings = settings;
SetupFileLogger(settings);
SetupLogManager();
LogHelper.OnException += LogHelper_OnException;
} }
var messageWithHeader = LogHelper.FormatMessageWithHeader(Settings, logType, message, dateTime); private DateTime CurrentDateTime => Settings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;
var writeToConsoleValue = writeToConsole ?? Settings.EnableConsole; public ILoggerProvider LoggerProvider { get; private set; }
var sendToSyslogServersValue = sendToSyslogServers ?? Settings.SendToSyslogServers; public ILoggerFactory LoggerFactory { get; private set; }
var sendToSplunkServersValue = sendToSplunkServers ?? Settings.SendToSplunkServers; public ILogger Logger { get; private set; }
var sendToGrayLogServersValue = sendToGrayLogServers ?? Settings.SendToGrayLogServers;
LogHelper.SendToFile(Logger, Settings, logType, message); public string CurrentLogFile => LoggerProvider is FileLoggerProvider fileLoggerProvider
? fileLoggerProvider.LogFile
: string.Empty;
if (writeToConsoleValue) LogHelper.SendToConsole(Settings, logType, messageWithHeader, true); public bool IsRunning { get; private set; }
if (sendToSyslogServersValue || sendToSplunkServersValue || sendToGrayLogServersValue) public static LogManager Instance => _instance.Value;
await Task.Run(async () =>
public LoggerSettings Settings { get; set; } = CreateDefaultSettings();
public void Dispose()
{
DisposeAsync(true).GetAwaiter().GetResult();
GC.SuppressFinalize(this);
}
public async Task WriteAsync(Exception exception, string module = null, string method = null,
bool criticalException = false,
bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null,
string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1")
{
if (exception == null)
{
return;
}
await WriteAsync(exception.FormatExceptionToMessage(module, method),
criticalException ? ELogType.CRITICAL : ELogType.ERROR, writeToConsole, sendToSysLogServers,
sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogFacility, grayLogSource,
grayLogVersion);
}
public async Task WriteAsync(string message, ELogType logType = ELogType.INFO, bool? writeToConsole = null,
bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string customSplunkSourceType = null,
bool? sendToGrayLogServers = null, string grayLogFacility = null, string grayLogSource = null,
string grayLogVersion = "1.1")
{
if (logType == ELogType.NONE)
{
return;
}
await InternalWriteAsync(CurrentDateTime, message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers,
customSplunkSourceType, sendToGrayLogServers, grayLogFacility, grayLogSource, grayLogVersion);
}
public event EventHandler<ErrorMessage> OnException;
private static LoggerSettings CreateDefaultSettings()
{
var settings = new LoggerSettings
{
Id = "EonaCatLogger",
MaxLogType = ELogType.INFO
};
return settings;
}
protected virtual async Task DisposeAsync(bool disposing)
{
if (disposing)
{
_isDisposing = true;
await StopLoggingAsync();
await Task.Delay(100);
}
}
public async Task StartNewLogAsync()
{
if (_tokenSource.IsCancellationRequested)
{
return;
}
if (IsRunning && CurrentDateTime.Date > _logDate.Date)
{
await StopLoggingAsync();
}
IsRunning = true;
CreateLogger();
Directory.CreateDirectory(Settings.FileLoggerOptions.LogDirectory);
_logDate = CurrentDateTime;
}
private void CreateLogger()
{
// Dispose of previous ServiceProvider if it exists
LoggerProvider?.Dispose();
LoggerFactory?.Dispose();
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(Settings.MaxLogType.ToLogLevel())
.AddEonaCatFileLogger(configuration =>
{
var fileLoggerOptions = Settings.FileLoggerOptions;
configuration.MaxWriteTries = fileLoggerOptions.MaxWriteTries;
configuration.RetainedFileCountLimit = fileLoggerOptions.RetainedFileCountLimit;
configuration.FlushPeriod = fileLoggerOptions.FlushPeriod;
configuration.IsEnabled = fileLoggerOptions.IsEnabled;
configuration.BatchSize = fileLoggerOptions.BatchSize;
configuration.FileSizeLimit = fileLoggerOptions.FileSizeLimit;
configuration.LogDirectory = fileLoggerOptions.LogDirectory;
configuration.FileNamePrefix = fileLoggerOptions.FileNamePrefix;
configuration.MaxRolloverFiles = fileLoggerOptions.MaxRolloverFiles;
configuration.UseLocalTime = Settings.UseLocalTime;
}));
var serviceProvider = serviceCollection.BuildServiceProvider();
LoggerProvider = serviceProvider.GetService<ILoggerProvider>();
LoggerFactory = serviceProvider.GetService<ILoggerFactory>();
Logger = LoggerFactory.CreateLogger(Settings.Id);
LogHelper.SendToFile(Logger, Settings, ELogType.INFO, LogHelper.GetStartupMessage());
}
private async Task InternalWriteAsync(DateTime dateTime, string message, ELogType logType = ELogType.INFO,
bool? writeToConsole = null, bool? sendToSyslogServers = null, bool? sendToSplunkServers = null,
string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1")
{
if (string.IsNullOrEmpty(message) || logType == ELogType.NONE ||
(int)logType > (int)Settings.MaxLogType)
{
return;
}
if (_isDisposing)
{
return;
}
if (!IsRunning)
{
await StartNewLogAsync();
}
var messageWithHeader = LogHelper.FormatMessageWithHeader(Settings, logType, message, dateTime, _category);
var writeToConsoleValue = writeToConsole ?? Settings.EnableConsole;
var sendToSyslogServersValue = sendToSyslogServers ?? Settings.SendToSyslogServers;
var sendToSplunkServersValue = sendToSplunkServers ?? Settings.SendToSplunkServers;
var sendToGrayLogServersValue = sendToGrayLogServers ?? Settings.SendToGrayLogServers;
LogHelper.SendToFile(Logger, Settings, logType, message);
if (writeToConsoleValue)
{
LogHelper.SendToConsole(Settings, logType, messageWithHeader, true);
}
var tasks = new List<Task>();
if (sendToSyslogServersValue || sendToSplunkServersValue || sendToGrayLogServersValue)
{ {
if (sendToSyslogServersValue) if (sendToSyslogServersValue)
await LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader, true); {
tasks.Add(LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader, true));
}
if (sendToSplunkServersValue) if (sendToSplunkServersValue)
await LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(), {
messageWithHeader, true); tasks.Add(LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(),
messageWithHeader, true));
}
if (sendToGrayLogServersValue) if (sendToGrayLogServersValue)
await LogHelper.SendToGrayLogServersAsync(Settings, messageWithHeader, logType, grayLogFacility, {
grayLogSource, true, grayLogVersion); tasks.Add(LogHelper.SendToGrayLogServersAsync(Settings, messageWithHeader, logType, grayLogFacility,
}); grayLogSource, true, grayLogVersion));
}
var logMessage = new EonaCatLogMessage await Task.WhenAll(tasks);
}
var logMessage = new EonaCatLogMessage
{
DateTime = dateTime,
Message = message,
LogType = logType,
Origin = string.IsNullOrWhiteSpace(Settings.LogOrigin) ? "LogManager" : Settings.LogOrigin
};
Settings.OnLogEvent(logMessage);
}
public void Reset()
{ {
DateTime = dateTime, Settings.ResetLogEvent();
Message = message, }
LogType = logType,
Origin = string.IsNullOrWhiteSpace(Settings.LogOrigin) ? "LogManager" : Settings.LogOrigin
};
Settings.OnLogEvent(logMessage); private void LogHelper_OnException(object sender, ErrorMessage e)
} {
OnException?.Invoke(sender, e);
}
public void Reset() private void SetupFileLogger(LoggerSettings settings = null, string logFolder = null, bool defaultPrefix = true)
{ {
Settings.ResetLogEvent(); if (settings == null)
} {
settings = Settings;
}
private void LogHelper_OnException(object sender, ErrorMessage e) if (!settings.EnableFileLogging)
{ {
OnException?.Invoke(sender, e); return;
} }
private void SetupFileLogger(LoggerSettings settings = null, string logFolder = null, bool defaultPrefix = true) if (logFolder != null)
{ {
if (settings == null) settings.FileLoggerOptions.LogDirectory = logFolder;
settings = Settings; }
if (!settings.EnableFileLogging) if (string.IsNullOrWhiteSpace(settings.FileLoggerOptions.FileNamePrefix))
return; {
settings.FileLoggerOptions.FileNamePrefix = defaultPrefix ? "EonaCat" : string.Empty;
}
}
if (logFolder != null) private void SetupLogManager()
settings.FileLoggerOptions.LogDirectory = logFolder; {
AppDomain.CurrentDomain.ProcessExit += ProcessExit;
_logDate = CurrentDateTime;
}
if (string.IsNullOrWhiteSpace(settings.FileLoggerOptions.FileNamePrefix)) private void ProcessExit(object sender, EventArgs e)
settings.FileLoggerOptions.FileNamePrefix = defaultPrefix ? "EonaCat" : string.Empty; {
} Dispose();
}
private void SetupLogManager() private Task StopLoggingAsync()
{ {
AppDomain.CurrentDomain.ProcessExit += ProcessExit; WriteStopMessage();
_logDate = CurrentDateTme; IsRunning = false;
} return Task.CompletedTask;
}
private void ProcessExit(object sender, EventArgs e) private void WriteStopMessage()
{ {
Dispose(); var stopMessage = $"{DllInfo.ApplicationName} stopped.{Environment.NewLine}";
} LogHelper.SendToFile(Logger, Settings, ELogType.INFO, stopMessage);
}
private Task StopLoggingAsync() public void DeleteCurrentLogFile()
{ {
WriteStopMessage(); if (!string.IsNullOrEmpty(CurrentLogFile))
IsRunning = false; {
return Task.CompletedTask; File.Delete(CurrentLogFile);
} }
}
private void WriteStopMessage()
{
var stopMessage = $"{DllInfo.ApplicationName} stopped.{Environment.NewLine}";
LogHelper.SendToFile(Logger, Settings, ELogType.INFO, stopMessage);
}
public void DeleteCurrentLogFile()
{
if (CurrentLogFile != null)
File.Delete(CurrentLogFile);
} }
} }

View File

@@ -21,7 +21,7 @@ public class LoggerSettings
private FileLoggerOptions _fileLoggerOptions; private FileLoggerOptions _fileLoggerOptions;
private string _headerFormat = "{ts} {host} {thread} {sev}"; private string _headerFormat = "{ts} {host} {category} {thread} {sev}";
private int _maxMessageLength = 1024; private int _maxMessageLength = 1024;
private string _timestampFormat = "yyyy-MM-dd HH:mm:ss"; private string _timestampFormat = "yyyy-MM-dd HH:mm:ss";
@@ -43,9 +43,10 @@ public class LoggerSettings
/// variables including: /// variables including:
/// {ts}: UTC timestamp /// {ts}: UTC timestamp
/// {host}: Hostname /// {host}: Hostname
/// {category}: Category
/// {thread}: Thread ID /// {thread}: Thread ID
/// {sev}: Severity /// {sev}: Severity
/// Default: {ts} {host} {thread} {sev} /// Default: {ts} {host} {category} {thread} {sev}
/// A space will be inserted between the header and the message. /// A space will be inserted between the header and the message.
/// </summary> /// </summary>
public string HeaderFormat public string HeaderFormat
@@ -53,8 +54,14 @@ public class LoggerSettings
get => _headerFormat; get => _headerFormat;
set set
{ {
if (string.IsNullOrEmpty(value)) _headerFormat = ""; if (string.IsNullOrEmpty(value))
else _headerFormat = value; {
_headerFormat = "";
}
else
{
_headerFormat = value;
}
} }
} }
@@ -66,7 +73,11 @@ public class LoggerSettings
get => _timestampFormat; get => _timestampFormat;
set set
{ {
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(HeaderFormat)); if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException(nameof(HeaderFormat));
}
_timestampFormat = value; _timestampFormat = value;
} }
} }
@@ -81,8 +92,14 @@ public class LoggerSettings
get => _enableConsole; get => _enableConsole;
set set
{ {
if (value) _enableConsole = ConsoleExists(); if (value)
else _enableConsole = false; {
_enableConsole = ConsoleExists();
}
else
{
_enableConsole = false;
}
} }
} }
@@ -99,7 +116,11 @@ public class LoggerSettings
get => _colors; get => _colors;
set set
{ {
if (value == null) throw new ArgumentNullException(nameof(Colors)); if (value == null)
{
throw new ArgumentNullException(nameof(Colors));
}
_colors = value; _colors = value;
} }
} }
@@ -130,7 +151,11 @@ public class LoggerSettings
{ {
get get
{ {
if (_fileLoggerOptions == null) _fileLoggerOptions = CreateDefaultFileLoggerOptions(); if (_fileLoggerOptions == null)
{
_fileLoggerOptions = CreateDefaultFileLoggerOptions();
}
return _fileLoggerOptions; return _fileLoggerOptions;
} }

View File

@@ -29,7 +29,10 @@ public class SplunkServer
SplunkHecUrl = splunkHecUrl; SplunkHecUrl = splunkHecUrl;
SplunkHecToken = splunkHecToken; SplunkHecToken = splunkHecToken;
if (httpClientHandler == null) httpClientHandler = new HttpClientHandler(); if (httpClientHandler == null)
{
httpClientHandler = new HttpClientHandler();
}
SplunkClientHandler = httpClientHandler; SplunkClientHandler = httpClientHandler;
CreateHttpClient(); CreateHttpClient();
@@ -45,7 +48,10 @@ public class SplunkServer
set set
{ {
if (!string.IsNullOrWhiteSpace(_splunkHecUrl) && !_splunkHecUrl.ToLower().Contains("http")) if (!string.IsNullOrWhiteSpace(_splunkHecUrl) && !_splunkHecUrl.ToLower().Contains("http"))
{
value = $"http://{value}"; value = $"http://{value}";
}
_splunkHecUrl = value; _splunkHecUrl = value;
} }
} }
@@ -103,7 +109,10 @@ public class SplunkServer
public async Task<HttpResponseMessage> SendAsync(SplunkPayload splunkPayload) public async Task<HttpResponseMessage> SendAsync(SplunkPayload splunkPayload)
{ {
if (splunkPayload == null) return null; if (splunkPayload == null)
{
return null;
}
// Create an event object with the required fields // Create an event object with the required fields
var eventObject = new var eventObject = new
@@ -116,7 +125,10 @@ public class SplunkServer
// Serialize the event object to JSON // Serialize the event object to JSON
var eventJson = JsonHelper.ToJson(eventObject); var eventJson = JsonHelper.ToJson(eventObject);
if (!HasHecToken) CreateHttpClient(); if (!HasHecToken)
{
CreateHttpClient();
}
// Create an HTTP content with the event data // Create an HTTP content with the event data
var content = new StringContent(eventJson, Encoding.UTF8, "application/json"); var content = new StringContent(eventJson, Encoding.UTF8, "application/json");

View File

@@ -42,7 +42,11 @@ public class SyslogServer
set set
{ {
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Hostname)); if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException(nameof(Hostname));
}
_Hostname = value; _Hostname = value;
SetUdp(); SetUdp();
@@ -57,7 +61,11 @@ public class SyslogServer
get => _Port; get => _Port;
set set
{ {
if (value < 0) throw new ArgumentException("Port must be zero or greater."); if (value < 0)
{
throw new ArgumentException("Port must be zero or greater.");
}
_Port = value; _Port = value;
SetUdp(); SetUdp();

View File

@@ -11,14 +11,14 @@ Microsoft.Extensions.Logging
**Easy way of logging without configuring anything:** **Easy way of logging without configuring anything:**
```csharp ```csharp
LogManager.Instance.Write("INFO", ELogType.INFO, true); LogManager.Instance.WriteAsync("INFO", ELogType.INFO, true);
LogManager.Instance.Write("WARNING", ELogType.WARNING, true); LogManager.Instance.WriteAsync("WARNING", ELogType.WARNING, true);
LogManager.Instance.Write("ERROR", ELogType.ERROR, true); LogManager.Instance.WriteAsync("ERROR", ELogType.ERROR, true);
LogManager.Instance.Write("DEBUG", ELogType.DEBUG, true); LogManager.Instance.WriteAsync("DEBUG", ELogType.DEBUG, true);
LogManager.Instance.Write("CRITICAL", ELogType.CRITICAL, true); LogManager.Instance.WriteAsync("CRITICAL", ELogType.CRITICAL, true);
LogManager.Instance.Write("TRACE", ELogType.TRACE, true); LogManager.Instance.WriteAsync("TRACE", ELogType.TRACE, true);
LogManager.Instance.Write("TRAFFIC", ELogType.TRAFFIC, true); LogManager.Instance.WriteAsync("TRAFFIC", ELogType.TRAFFIC, true);
LogManager.Instance.Write("NONE", ELogType.NONE, true); LogManager.Instance.WriteAsync("NONE", ELogType.NONE, true);
``` ```
**Logging in .NET 4.8 or higher: ** **Logging in .NET 4.8 or higher: **
@@ -186,28 +186,28 @@ namespace EonaCat.Logger.Advanced
// Logs an informational message. // Logs an informational message.
public static void Info(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) public static void Info(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
Write(message, ELogType.INFO, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); WriteAsync(message, ELogType.INFO, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
} }
// Internal method to write logs. // Internal method to write logs.
private static void Write(string message, ELogType logType, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) private static void WriteAsync(string message, ELogType logType, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
if (grayLogSettings != null) if (grayLogSettings != null)
{ {
// Log the message with specified settings. // Log the message with specified settings.
_logManager.Write(message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings.Facility, grayLogSettings.Source, grayLogSettings.Version); _logManager.WriteAsync(message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings.Facility, grayLogSettings.Source, grayLogSettings.Version);
} }
else else
{ {
// Log the message with default settings. // Log the message with default settings.
_logManager.Write(message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers); _logManager.WriteAsync(message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers);
} }
} }
// Logs a debug message. // Logs a debug message.
public static void Debug(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) public static void Debug(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
Write(message, ELogType.DEBUG, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); WriteAsync(message, ELogType.DEBUG, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
} }
// Logs an error message along with an exception. // Logs an error message along with an exception.
@@ -216,12 +216,12 @@ namespace EonaCat.Logger.Advanced
if (grayLogSettings != null) if (grayLogSettings != null)
{ {
// Log the exception and message with specified settings. // Log the exception and message with specified settings.
_logManager.Write(exception, message, criticalException: isCriticalException, writeToConsole: writeToConsole, sendToSysLogServers: sendToSysLogServers, sendToSplunkServers: sendToSplunkServers, customSplunkSourceType: customSplunkSourceType, sendToGrayLogServers: sendToGrayLogServers, grayLogFacility: grayLogSettings.Facility, grayLogSource: grayLogSettings.Source, grayLogVersion: grayLogSettings.Version); _logManager.WriteAsync(exception, message, criticalException: isCriticalException, writeToConsole: writeToConsole, sendToSysLogServers: sendToSysLogServers, sendToSplunkServers: sendToSplunkServers, customSplunkSourceType: customSplunkSourceType, sendToGrayLogServers: sendToGrayLogServers, grayLogFacility: grayLogSettings.Facility, grayLogSource: grayLogSettings.Source, grayLogVersion: grayLogSettings.Version);
} }
else else
{ {
// Log the exception and message with default settings. // Log the exception and message with default settings.
_logManager.Write(exception, message, criticalException: isCriticalException, writeToConsole: writeToConsole, sendToSysLogServers: sendToSysLogServers, sendToSplunkServers: sendToSplunkServers, customSplunkSourceType: customSplunkSourceType, sendToGrayLogServers: sendToGrayLogServers); _logManager.WriteAsync(exception, message, criticalException: isCriticalException, writeToConsole: writeToConsole, sendToSysLogServers: sendToSysLogServers, sendToSplunkServers: sendToSplunkServers, customSplunkSourceType: customSplunkSourceType, sendToGrayLogServers: sendToGrayLogServers);
} }
} }
@@ -231,37 +231,37 @@ namespace EonaCat.Logger.Advanced
if (isCriticalException) if (isCriticalException)
{ {
// Log a critical error message. // Log a critical error message.
_logManager.Write(message, ELogType.CRITICAL, writeToConsole); _logManager.WriteAsync(message, ELogType.CRITICAL, writeToConsole);
} }
else else
{ {
// Log a regular error message. // Log a regular error message.
_logManager.Write(message, ELogType.ERROR, writeToConsole); _logManager.WriteAsync(message, ELogType.ERROR, writeToConsole);
} }
} }
// Logs a warning message. // Logs a warning message.
public static void Warning(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) public static void Warning(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
Write(message, ELogType.WARNING, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); WriteAsync(message, ELogType.WARNING, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
} }
// Logs a critical message. // Logs a critical message.
public static void Critical(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) public static void Critical(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
Write(message, ELogType.CRITICAL, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); WriteAsync(message, ELogType.CRITICAL, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
} }
// Logs a traffic message. // Logs a traffic message.
public static void Traffic(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) public static void Traffic(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
Write(message, ELogType.TRAFFIC, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); WriteAsync(message, ELogType.TRAFFIC, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
} }
// Logs a trace message. // Logs a trace message.
public static void Trace(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) public static void Trace(string message, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null)
{ {
Write(message, ELogType.TRACE, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); WriteAsync(message, ELogType.TRACE, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
} }
} }
} }
@@ -319,14 +319,14 @@ Task.Run(() =>
// 10.000.000 lines to go :) // 10.000.000 lines to go :)
for (int i = 0; i < 10000000; i++) for (int i = 0; i < 10000000; i++)
{ {
logger.Write($"test to file {i} INFO", ELogType.INFO); logger.WriteAsync($"test to file {i} INFO", ELogType.INFO);
logger.Write($"test to file {i} CRITICAL", ELogType.CRITICAL); logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL);
logger.Write($"test to file {i} DEBUG", ELogType.DEBUG); logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG);
logger.Write($"test to file {i} ERROR", ELogType.ERROR); logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR);
logger.Write($"test to file {i} TRACE", ELogType.TRACE); logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE);
logger.Write($"test to file {i} TRAFFIC", ELogType.TRAFFIC); logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC);
logger.Write($"test to file {i} WARNING", ELogType.WARNING); logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING);
logger.Write($"test to file {i} NONE", ELogType.NONE); logger.WriteAsync($"test to file {i} NONE", ELogType.NONE);
Console.WriteLine($"Logged: {i}"); Console.WriteLine($"Logged: {i}");
Task.Delay(1); Task.Delay(1);
} }

View File

@@ -5,29 +5,52 @@ using EonaCat.Logger.Managers;
namespace EonaCat.Logger.Test.Web; namespace EonaCat.Logger.Test.Web;
public static class Logger public class Logger
{ {
private static LogManager LogManager; private LogManager _logManager;
public static ELogType MaxLogType { get; set; } public ELogType MaxLogType { get; set; }
public static bool UseLocalTime { get; set; } public LoggerSettings LoggerSettings { get; }
public static string LogFolder => Path.Combine(FileLoggerOptions.DefaultPath, "logs"); public bool UseLocalTime { get; set; }
public static string CurrentLogFile => LogManager.CurrentLogFile; public string LogFolder { get; set; } = Path.Combine(FileLoggerOptions.DefaultPath, "logs");
public static bool IsDisabled { get; set; } public string CurrentLogFile => _logManager.CurrentLogFile;
public bool IsDisabled { get; set; }
public static void DeleteCurrentLogFile() public Logger(string name = "EonaCatTestLogger", ELogType maxLogType = ELogType.INFO, bool useLocalTime = false, int maxFileSize = 20_000_000)
{ {
if (IsDisabled) UseLocalTime = useLocalTime;
return; MaxLogType = maxLogType;
LogManager.DeleteCurrentLogFile(); LoggerSettings = new LoggerSettings
{
Id = name,
MaxLogType = MaxLogType,
UseLocalTime = UseLocalTime,
FileLoggerOptions =
{
LogDirectory = LogFolder,
FileSizeLimit = maxFileSize,
UseLocalTime = UseLocalTime,
},
};
_logManager = new LogManager(LoggerSettings);
} }
private static string ConvertToAbsolutePath(string path) public void DeleteCurrentLogFile()
{
if (IsDisabled)
{
return;
}
_logManager.DeleteCurrentLogFile();
}
private string ConvertToAbsolutePath(string path)
{ {
return Path.IsPathRooted(path) ? path : Path.Combine(LogFolder, path); return Path.IsPathRooted(path) ? path : Path.Combine(LogFolder, path);
} }
public static async Task DownloadLogAsync(HttpContext context, string logName, long limit) public async Task DownloadLogAsync(HttpContext context, string logName, long limit)
{ {
var logFileName = logName + ".log"; var logFileName = logName + ".log";
@@ -39,7 +62,9 @@ public static class Logger
response.Headers.ContentDisposition = "attachment;filename=" + logFileName; response.Headers.ContentDisposition = "attachment;filename=" + logFileName;
if (limit > fS.Length || limit < 1) if (limit > fS.Length || limit < 1)
{
limit = fS.Length; limit = fS.Length;
}
var oFS = new OffsetStream(fS, 0, limit); var oFS = new OffsetStream(fS, 0, limit);
var request = context.Request; var request = context.Request;
@@ -81,43 +106,32 @@ public static class Logger
await oFS.CopyToAsync(stream).ConfigureAwait(false); await oFS.CopyToAsync(stream).ConfigureAwait(false);
if (fS.Length > limit) if (fS.Length > limit)
{
await stream.WriteAsync("\r\n####__EONACATLOGGER_TRUNCATED___####"u8.ToArray()).ConfigureAwait(false); await stream.WriteAsync("\r\n####__EONACATLOGGER_TRUNCATED___####"u8.ToArray()).ConfigureAwait(false);
}
} }
} }
public static async Task LogAsync(string message, ELogType logType = ELogType.INFO, bool writeToConsole = true) public async Task LogAsync(string message, ELogType logType = ELogType.INFO, bool writeToConsole = true)
{ {
if (IsDisabled) if (IsDisabled)
{
return; return;
}
await LogManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false); await _logManager.WriteAsync(message, logType, writeToConsole).ConfigureAwait(false);
} }
public static async Task LogAsync(Exception exception, string message = "", bool writeToConsole = true) public async Task LogAsync(Exception exception, string message = "", bool writeToConsole = true)
{ {
if (IsDisabled) if (IsDisabled)
{
return; return;
}
if (ELogType.ERROR <= MaxLogType) if (ELogType.ERROR <= MaxLogType)
{ {
await LogManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false); await _logManager.WriteAsync(exception, message, writeToConsole: writeToConsole).ConfigureAwait(false);
} }
} }
public static void Configure()
{
var loggerSettings = new LoggerSettings
{
Id = "EonaCatTestLogger",
MaxLogType = ELogType.INFO,
UseLocalTime = UseLocalTime,
FileLoggerOptions =
{
LogDirectory = LogFolder,
FileSizeLimit = 20_000_000, // 20 MB,
UseLocalTime = UseLocalTime
}
};
LogManager = new LogManager(loggerSettings);
}
} }

View File

@@ -1,6 +1,7 @@
using EonaCat.Logger; using EonaCat.Logger;
using EonaCat.Logger.EonaCatCoreLogger; using EonaCat.Logger.EonaCatCoreLogger;
using EonaCat.Logger.EonaCatCoreLogger.Extensions; using EonaCat.Logger.EonaCatCoreLogger.Extensions;
using EonaCat.Logger.EonaCatCoreLogger.Models;
using EonaCat.Logger.Managers; using EonaCat.Logger.Managers;
using EonaCat.Logger.Test.Web; using EonaCat.Logger.Test.Web;
using EonaCat.Web.RateLimiter; using EonaCat.Web.RateLimiter;
@@ -8,11 +9,21 @@ using EonaCat.Web.RateLimiter.Endpoints.Extensions;
using EonaCat.Web.Tracer.Extensions; using EonaCat.Web.Tracer.Extensions;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
int onLogCounter = 0;
var defaultColor = Console.ForegroundColor;
// Add services to the container. // Add services to the container.
Logger.UseLocalTime = true; Logger logger = new Logger();
Logger.MaxLogType = ELogType.TRACE; logger.UseLocalTime = true;
Logger.Configure(); logger.MaxLogType = ELogType.TRACE;
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
void LoggerSettings_OnLog(EonaCatLogMessage message)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"LogCounter: {++onLogCounter} {message}");
Console.ForegroundColor = defaultColor;
}
var options = new FileLoggerOptions(); var options = new FileLoggerOptions();
options.MaxRolloverFiles = 5; options.MaxRolloverFiles = 5;
@@ -124,11 +135,11 @@ void RunLoggingExceptionTests()
} }
} }
Task.Run(RunWebLoggerTests).ConfigureAwait(false); await Task.Run(RunWebLoggerTestsAsync).ConfigureAwait(false);
Task.Run(RunWebLoggingTests).ConfigureAwait(false); await Task.Run(RunWebLoggingTests).ConfigureAwait(false);
Task.Run(RunLoggingTests).ConfigureAwait(false); await Task.Run(RunLoggingTestsAsync).ConfigureAwait(false);
Task.Run(RunLoggingExceptionTests).ConfigureAwait(false); await Task.Run(RunLoggingExceptionTests).ConfigureAwait(false);
Task.Run(RunWebLoggingExceptionTests).ConfigureAwait(false); await Task.Run(RunWebLoggingExceptionTests).ConfigureAwait(false);
void RunWebLoggingExceptionTests() void RunWebLoggingExceptionTests()
{ {
@@ -155,12 +166,15 @@ void RunWebLoggingExceptionTests()
async void RunWebLoggingTests() async void RunWebLoggingTests()
{ {
if (!Directory.Exists(Logger.LogFolder)) Directory.CreateDirectory(Logger.LogFolder); if (!Directory.Exists(logger.LogFolder))
{
Directory.CreateDirectory(logger.LogFolder);
}
for (var i = 0; i < 9000000; i++) for (var i = 0; i < 9000000; i++)
{ {
app.Logger.LogInformation($"web-test {i}"); app.Logger.LogInformation($"web-test {i}");
using (var file = new StreamWriter(Path.Combine(Logger.LogFolder, "test.log"), true)) using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "test.log"), true))
{ {
await file.WriteAsync($"WebLogged: {i}{Environment.NewLine}").ConfigureAwait(false); await file.WriteAsync($"WebLogged: {i}{Environment.NewLine}").ConfigureAwait(false);
} }
@@ -169,7 +183,7 @@ async void RunWebLoggingTests()
} }
} }
void RunLoggingTests() async Task RunLoggingTestsAsync()
{ {
var loggerSettings = new LoggerSettings(); var loggerSettings = new LoggerSettings();
loggerSettings.UseLocalTime = true; loggerSettings.UseLocalTime = true;
@@ -182,38 +196,37 @@ void RunLoggingTests()
for (var i = 0; i < 9000000; i++) for (var i = 0; i < 9000000; i++)
{ {
logger.WriteAsync($"test to file {i} INFO").ConfigureAwait(false); await logger.WriteAsync($"test to file {i} INFO").ConfigureAwait(false);
logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING).ConfigureAwait(false);
logger.WriteAsync($"test to file {i} NONE", ELogType.NONE).ConfigureAwait(false); await logger.WriteAsync($"test to file {i} NONE", ELogType.NONE).ConfigureAwait(false);
Console.WriteLine($"Logged: {i}"); Console.WriteLine($"Logged: {i}");
Task.Delay(1); await Task.Delay(1).ConfigureAwait(false);
} }
} }
void RunWebLoggerTests() async Task RunWebLoggerTestsAsync()
{ {
var i = 0; var i = 0;
while (true) while (true)
{ {
i++; i++;
Task.Run(() => await Task.Run(async () =>
{ {
Logger.LogAsync($"test via logger {i} INFO"); await logger.LogAsync($"test via logger {i} INFO").ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} CRITICAL", ELogType.CRITICAL); await logger.LogAsync($"test via logger {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} DEBUG", ELogType.DEBUG); await logger.LogAsync($"test via logger {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} ERROR", ELogType.ERROR); await logger.LogAsync($"test via logger {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} TRACE", ELogType.TRACE); await logger.LogAsync($"test via logger {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} TRAFFIC", ELogType.TRAFFIC); await logger.LogAsync($"test via logger {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} WARNING", ELogType.WARNING); await logger.LogAsync($"test via logger {i} WARNING", ELogType.WARNING).ConfigureAwait(false);
Logger.LogAsync($"test via logger {i} NONE", ELogType.NONE); await logger.LogAsync($"test via logger {i} NONE", ELogType.NONE).ConfigureAwait(false);
}); }).ConfigureAwait(false);
Console.WriteLine($"Logger: {i}"); await Task.Delay(1).ConfigureAwait(false);
Task.Delay(1);
} }
} }