Updated
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<TargetFrameworks>.netstandard2.1; net6.0; net7.0; net8.0; net4.8;</TargetFrameworks>
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<FileVersion>1.2.9</FileVersion>
|
||||
<FileVersion>1.3.0</FileVersion>
|
||||
<Authors>EonaCat (Jeroen Saey)</Authors>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Company>EonaCat (Jeroen Saey)</Company>
|
||||
@@ -24,7 +24,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<EVRevisionFormat>1.2.9+{chash:10}.{c:ymd}</EVRevisionFormat>
|
||||
<EVRevisionFormat>1.3.0+{chash:10}.{c:ymd}</EVRevisionFormat>
|
||||
<EVDefault>true</EVDefault>
|
||||
<EVInfo>true</EVInfo>
|
||||
<EVTagMatch>v[0-9]*</EVTagMatch>
|
||||
|
||||
@@ -26,9 +26,16 @@ public static class FileLoggerFactoryExtensions
|
||||
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder, string filenamePrefix = 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 =>
|
||||
{
|
||||
options.FileNamePrefix = fileLoggerOptions.FileNamePrefix;
|
||||
@@ -55,7 +62,11 @@ public static class FileLoggerFactoryExtensions
|
||||
public static ILoggingBuilder AddEonaCatFileLogger(this ILoggingBuilder builder,
|
||||
Action<FileLoggerOptions> configure)
|
||||
{
|
||||
if (configure == null) throw new ArgumentNullException(nameof(configure));
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
builder.AddEonaCatFileLogger();
|
||||
builder.Services.Configure(configure);
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@ public class FileLoggerOptions : BatchingLoggerOptions
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FileSizeLimit)} must be positive.");
|
||||
}
|
||||
|
||||
_fileSizeLimit = value;
|
||||
}
|
||||
}
|
||||
@@ -46,8 +49,11 @@ public class FileLoggerOptions : BatchingLoggerOptions
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value),
|
||||
$"{nameof(RetainedFileCountLimit)} must be positive.");
|
||||
}
|
||||
|
||||
_retainedFileCountLimit = value;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +80,10 @@ public class FileLoggerOptions : BatchingLoggerOptions
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(MaxRolloverFiles)} must be positive.");
|
||||
}
|
||||
|
||||
_maxRolloverFiles = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,12 @@ public class FileLoggerProvider : BatchingLoggerProvider
|
||||
{
|
||||
var dir = Path.GetDirectoryName(_logFile);
|
||||
if (!string.IsNullOrEmpty(dir))
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +132,10 @@ public class FileLoggerProvider : BatchingLoggerProvider
|
||||
|
||||
private async Task<bool> TryWriteToFileAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!_buffer.ContainsKey(LogFile)) return true;
|
||||
if (!_buffer.ContainsKey(LogFile))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var tries = 0;
|
||||
var completed = false;
|
||||
@@ -193,7 +200,10 @@ public class FileLoggerProvider : BatchingLoggerProvider
|
||||
{
|
||||
var hasPrefix = !string.IsNullOrWhiteSpace(_fileNamePrefix);
|
||||
if (hasPrefix)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -260,7 +270,7 @@ public class FileLoggerProvider : BatchingLoggerProvider
|
||||
private async Task WriteEndMessageAsync(string logFilePath)
|
||||
{
|
||||
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))
|
||||
{
|
||||
@@ -292,13 +302,20 @@ public class FileLoggerProvider : BatchingLoggerProvider
|
||||
IEnumerable<FileInfo> files = null;
|
||||
|
||||
if (hasPrefix)
|
||||
{
|
||||
files = new DirectoryInfo(_path).GetFiles(_fileNamePrefix + "*");
|
||||
}
|
||||
else
|
||||
{
|
||||
files = new DirectoryInfo(_path).GetFiles("*");
|
||||
}
|
||||
|
||||
files = files.OrderByDescending(file => file.Name).Skip(_maxRetainedFiles);
|
||||
|
||||
foreach (var item in files) item.Delete();
|
||||
foreach (var item in files)
|
||||
{
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,67 +4,70 @@ using EonaCat.Logger.Extensions;
|
||||
using EonaCat.Logger.Managers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
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
|
||||
namespace EonaCat.Logger.EonaCatCoreLogger.Internal
|
||||
{
|
||||
private readonly string _category;
|
||||
private readonly BatchingLoggerProvider _provider;
|
||||
private LoggerSettings _loggerSettings;
|
||||
// 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 BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings)
|
||||
public class BatchingLogger : ILogger
|
||||
{
|
||||
_loggerSettings = loggerSettings;
|
||||
_provider = loggerProvider;
|
||||
_category = categoryName;
|
||||
}
|
||||
private readonly string _category;
|
||||
private readonly BatchingLoggerProvider _provider;
|
||||
private readonly LoggerSettings _loggerSettings;
|
||||
|
||||
private DateTimeOffset CurrentDateTimeOffset =>
|
||||
_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
|
||||
public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName, LoggerSettings loggerSettings)
|
||||
{
|
||||
DateTime = timestamp.DateTime,
|
||||
Message = message,
|
||||
LogType = logLevel.FromLogLevel()
|
||||
};
|
||||
_provider = loggerProvider ?? throw new ArgumentNullException(nameof(loggerProvider));
|
||||
_category = categoryName ?? throw new ArgumentNullException(nameof(categoryName));
|
||||
_loggerSettings = loggerSettings ?? throw new ArgumentNullException(nameof(loggerSettings));
|
||||
}
|
||||
|
||||
currentMessage.Origin = string.IsNullOrWhiteSpace(_loggerSettings.LogOrigin)
|
||||
? "BatchingLogger"
|
||||
: _loggerSettings.LogOrigin;
|
||||
_loggerSettings?.OnLogEvent(currentMessage);
|
||||
private DateTimeOffset CurrentDateTimeOffset => CurrentDateTime;
|
||||
|
||||
private DateTime CurrentDateTime => _loggerSettings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,10 @@ public class BatchingLoggerOptions
|
||||
set
|
||||
{
|
||||
if (value <= TimeSpan.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FlushPeriod)} must be positive.");
|
||||
}
|
||||
|
||||
_flushPeriod = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,16 +23,23 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
||||
private Task _outputTask;
|
||||
private object _writeLock = new object();
|
||||
private bool _isDisposing;
|
||||
protected string Category;
|
||||
|
||||
protected BatchingLoggerProvider(IOptions<BatchingLoggerOptions> options)
|
||||
{
|
||||
var loggerOptions = options.Value;
|
||||
|
||||
if (loggerOptions.FlushPeriod <= TimeSpan.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(loggerOptions.FlushPeriod),
|
||||
$"{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;
|
||||
|
||||
StartAsync().ConfigureAwait(false);
|
||||
@@ -47,7 +54,10 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_loggerSettings != null) return _loggerSettings;
|
||||
if (_loggerSettings != null)
|
||||
{
|
||||
return _loggerSettings;
|
||||
}
|
||||
|
||||
_loggerSettings = new LoggerSettings();
|
||||
_loggerSettings.UseLocalTime = UseLocalTime;
|
||||
@@ -73,6 +83,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
||||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
{
|
||||
Category = categoryName;
|
||||
return new BatchingLogger(this, categoryName, LoggerSettings);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ public static class ExceptionExtensions
|
||||
public static string FormatExceptionToMessage(this Exception exception, string module = null, string method = null)
|
||||
{
|
||||
if (exception == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var st = new StackTrace(exception, true);
|
||||
var frame = st.GetFrame(0);
|
||||
@@ -28,9 +30,15 @@ public static class ExceptionExtensions
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("--- Exception details provided by EonaCatLogger ---");
|
||||
if (!string.IsNullOrEmpty(module))
|
||||
{
|
||||
sb.AppendLine(" Module : " + module);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(method))
|
||||
{
|
||||
sb.AppendLine(" Method : " + method);
|
||||
}
|
||||
|
||||
sb.Append(" Type : ").AppendLine(exception.GetType().ToString());
|
||||
sb.Append(" Data : ").AppendLine(exception.Data != null && exception.Data.Count > 0
|
||||
? FormatExceptionData(exception.Data)
|
||||
@@ -54,10 +62,12 @@ public static class ExceptionExtensions
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (DictionaryEntry entry in data)
|
||||
{
|
||||
sb.Append(" | ")
|
||||
.Append(entry.Key)
|
||||
.Append(": ")
|
||||
.AppendLine(entry.Value.ToString());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -13,16 +13,26 @@ public class OffsetStream : Stream
|
||||
{
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
if (offset > stream.Length) throw new EndOfStreamException();
|
||||
if (offset > stream.Length)
|
||||
{
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
BaseStreamOffset = offset;
|
||||
|
||||
if (length > stream.Length - offset) throw new EndOfStreamException();
|
||||
if (length > stream.Length - offset)
|
||||
{
|
||||
throw new EndOfStreamException();
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
Length1 = stream.Length - offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
Length1 = length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -49,9 +59,15 @@ public class OffsetStream : Stream
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -71,11 +87,18 @@ public class OffsetStream : Stream
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (Disposed) return;
|
||||
if (Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (OwnStream & (BaseStream != null))
|
||||
{
|
||||
BaseStream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
|
||||
@@ -84,20 +107,35 @@ public class OffsetStream : Stream
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
if (ReadOnly) throw new IOException("OffsetStream is read only.");
|
||||
if (ReadOnly)
|
||||
{
|
||||
throw new IOException("OffsetStream is read only.");
|
||||
}
|
||||
|
||||
BaseStream.Flush();
|
||||
}
|
||||
|
||||
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);
|
||||
Position1 += bytesRead;
|
||||
@@ -107,7 +145,10 @@ public class OffsetStream : Stream
|
||||
|
||||
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;
|
||||
|
||||
@@ -130,7 +171,10 @@ public class OffsetStream : Stream
|
||||
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;
|
||||
|
||||
@@ -139,7 +183,10 @@ public class OffsetStream : Stream
|
||||
|
||||
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);
|
||||
Length1 = value;
|
||||
@@ -147,15 +194,27 @@ public class OffsetStream : Stream
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
Position1 = pos;
|
||||
@@ -175,9 +234,15 @@ public class OffsetStream : Stream
|
||||
|
||||
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;
|
||||
Position1 = 0;
|
||||
|
||||
@@ -42,7 +42,11 @@ public class GrayLogServer
|
||||
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Hostname));
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Hostname));
|
||||
}
|
||||
|
||||
_Hostname = value;
|
||||
|
||||
SetUdp();
|
||||
@@ -57,7 +61,11 @@ public class GrayLogServer
|
||||
get => _Port;
|
||||
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;
|
||||
|
||||
SetUdp();
|
||||
|
||||
@@ -80,10 +80,15 @@ public static class ColorHelper
|
||||
|
||||
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)
|
||||
{
|
||||
throw new ArgumentException($"Provided parameter '{htmlColor}' is not valid");
|
||||
}
|
||||
|
||||
htmlColor = htmlColor.TrimStart('#');
|
||||
|
||||
|
||||
@@ -26,10 +26,17 @@ internal static class LogHelper
|
||||
internal static event EventHandler<ErrorMessage> OnException;
|
||||
|
||||
internal static string FormatMessageWithHeader(LoggerSettings settings, ELogType logType, string currentMessage,
|
||||
DateTime dateTime)
|
||||
DateTime dateTime, string category = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(currentMessage))
|
||||
{
|
||||
return currentMessage;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(category))
|
||||
{
|
||||
category = "General";
|
||||
}
|
||||
|
||||
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") + " " +
|
||||
(settings?.UseLocalTime ?? false ? "[LOCAL]" : "[UTC]"))
|
||||
.Replace("{host}", $"[Host:{Dns.GetHostName()}]")
|
||||
.Replace("{category}", $"[Category:{category}]")
|
||||
.Replace("{thread}", $"[ThreadId:{Environment.CurrentManagedThreadId}]")
|
||||
.Replace("{sev}", $"[{logType}]");
|
||||
|
||||
if (!settings?.RemoveMessagePrefix ?? (false && !currentMessage.Contains("[EonaCatLogger]")))
|
||||
{
|
||||
sb.Insert(0, "[EonaCatLogger] ");
|
||||
}
|
||||
|
||||
sb.Append(" ").Append(currentMessage);
|
||||
|
||||
@@ -51,7 +61,9 @@ internal static class LogHelper
|
||||
internal static void SendToConsole(LoggerSettings settings, ELogType logType, string message, bool writeToConsole)
|
||||
{
|
||||
if (settings == null || !writeToConsole || string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (logger == null || settings == null || !settings.EnableFileLogging ||
|
||||
string.IsNullOrWhiteSpace(message)) return;
|
||||
string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var logLevel = logType.ToLogLevel();
|
||||
if (IsLogLevelEnabled(settings, logType))
|
||||
@@ -132,9 +147,14 @@ internal static class LogHelper
|
||||
bool sendToSplunkServer)
|
||||
{
|
||||
if (settings == null || !sendToSplunkServer || splunkPayload == null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -154,12 +174,14 @@ internal static class LogHelper
|
||||
var response = await splunkServer.SendAsync(splunkPayload);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
OnException?.Invoke(null,
|
||||
new ErrorMessage
|
||||
{
|
||||
Message =
|
||||
$"Failed to send log to Splunk '{splunkServer.SplunkHecUrl}'. Status code: {response.StatusCode}"
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
@@ -178,7 +200,9 @@ internal static class LogHelper
|
||||
bool sendToSplunkServer)
|
||||
{
|
||||
if (settings == null || !sendToSplunkServer || string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var splunkPayload = new SplunkPayload
|
||||
{
|
||||
@@ -194,9 +218,12 @@ internal static class LogHelper
|
||||
string facility, string source, bool sendToGrayLogServer, string version = "1.1")
|
||||
{
|
||||
if (settings == null || !sendToGrayLogServer || string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var grayLogServer in settings.GrayLogServers ?? new List<GrayLogServer> { new("127.0.0.1") })
|
||||
{
|
||||
try
|
||||
{
|
||||
var gelfMessage = new
|
||||
@@ -223,15 +250,19 @@ internal static class LogHelper
|
||||
$"Error while logging to GrayLog Server '{grayLogServer.Hostname}': {exception.Message}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task SendToSysLogServersAsync(LoggerSettings settings, string message,
|
||||
bool sendToSyslogServers)
|
||||
{
|
||||
if (settings == null || !sendToSyslogServers || string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var server in settings.SysLogServers ?? new List<SyslogServer> { new("127.0.0.1") })
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(server.Hostname))
|
||||
@@ -260,6 +291,7 @@ internal static class LogHelper
|
||||
Message = $"Error while logging to SysLog Server '{server.Hostname}': {exception.Message}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetStartupMessage()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -11,274 +12,309 @@ using EonaCat.Logger.Syslog;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
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
|
||||
namespace EonaCat.Logger.Managers
|
||||
{
|
||||
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();
|
||||
private DateTime _logDate;
|
||||
private bool _isDisposing;
|
||||
|
||||
public LogManager(LoggerSettings settings, string serverIp, int serverPort)
|
||||
public class LogManager : ILogManager, IDisposable
|
||||
{
|
||||
if (string.IsNullOrEmpty(serverIp))
|
||||
throw new ArgumentNullException(nameof(serverIp));
|
||||
private static readonly Lazy<LogManager> _instance = new(() => new LogManager(CreateDefaultSettings()));
|
||||
private readonly CancellationTokenSource _tokenSource = new();
|
||||
private DateTime _logDate;
|
||||
private bool _isDisposing;
|
||||
private string _category;
|
||||
|
||||
if (serverPort < 0)
|
||||
throw new ArgumentException("Server port must be zero or greater.");
|
||||
|
||||
settings.SysLogServers = new List<SyslogServer>
|
||||
public LogManager(LoggerSettings settings, string serverIp, int serverPort)
|
||||
{
|
||||
new(serverIp, serverPort)
|
||||
};
|
||||
|
||||
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 =>
|
||||
if (string.IsNullOrEmpty(serverIp))
|
||||
{
|
||||
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;
|
||||
}));
|
||||
throw new ArgumentNullException(nameof(serverIp));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
if (serverPort < 0)
|
||||
{
|
||||
throw new ArgumentException("Server port must be zero or greater.");
|
||||
}
|
||||
|
||||
settings.SysLogServers = new List<SyslogServer>
|
||||
{
|
||||
new(serverIp, serverPort)
|
||||
};
|
||||
|
||||
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;
|
||||
Settings = settings;
|
||||
SetupLogManager();
|
||||
}
|
||||
|
||||
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);
|
||||
var writeToConsoleValue = writeToConsole ?? Settings.EnableConsole;
|
||||
var sendToSyslogServersValue = sendToSyslogServers ?? Settings.SendToSyslogServers;
|
||||
var sendToSplunkServersValue = sendToSplunkServers ?? Settings.SendToSplunkServers;
|
||||
var sendToGrayLogServersValue = sendToGrayLogServers ?? Settings.SendToGrayLogServers;
|
||||
private DateTime CurrentDateTime => Settings.UseLocalTime ? DateTime.Now : DateTime.UtcNow;
|
||||
public ILoggerProvider LoggerProvider { get; private set; }
|
||||
public ILoggerFactory LoggerFactory { get; private set; }
|
||||
public ILogger Logger { get; private set; }
|
||||
|
||||
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)
|
||||
await Task.Run(async () =>
|
||||
public static LogManager Instance => _instance.Value;
|
||||
|
||||
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)
|
||||
await LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader, true);
|
||||
{
|
||||
tasks.Add(LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader, true));
|
||||
}
|
||||
|
||||
if (sendToSplunkServersValue)
|
||||
await LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(),
|
||||
messageWithHeader, true);
|
||||
{
|
||||
tasks.Add(LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(),
|
||||
messageWithHeader, true));
|
||||
}
|
||||
|
||||
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,
|
||||
Message = message,
|
||||
LogType = logType,
|
||||
Origin = string.IsNullOrWhiteSpace(Settings.LogOrigin) ? "LogManager" : Settings.LogOrigin
|
||||
};
|
||||
Settings.ResetLogEvent();
|
||||
}
|
||||
|
||||
Settings.OnLogEvent(logMessage);
|
||||
}
|
||||
private void LogHelper_OnException(object sender, ErrorMessage e)
|
||||
{
|
||||
OnException?.Invoke(sender, e);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Settings.ResetLogEvent();
|
||||
}
|
||||
private void SetupFileLogger(LoggerSettings settings = null, string logFolder = null, bool defaultPrefix = true)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
settings = Settings;
|
||||
}
|
||||
|
||||
private void LogHelper_OnException(object sender, ErrorMessage e)
|
||||
{
|
||||
OnException?.Invoke(sender, e);
|
||||
}
|
||||
if (!settings.EnableFileLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void SetupFileLogger(LoggerSettings settings = null, string logFolder = null, bool defaultPrefix = true)
|
||||
{
|
||||
if (settings == null)
|
||||
settings = Settings;
|
||||
if (logFolder != null)
|
||||
{
|
||||
settings.FileLoggerOptions.LogDirectory = logFolder;
|
||||
}
|
||||
|
||||
if (!settings.EnableFileLogging)
|
||||
return;
|
||||
if (string.IsNullOrWhiteSpace(settings.FileLoggerOptions.FileNamePrefix))
|
||||
{
|
||||
settings.FileLoggerOptions.FileNamePrefix = defaultPrefix ? "EonaCat" : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
if (logFolder != null)
|
||||
settings.FileLoggerOptions.LogDirectory = logFolder;
|
||||
private void SetupLogManager()
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit += ProcessExit;
|
||||
_logDate = CurrentDateTime;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(settings.FileLoggerOptions.FileNamePrefix))
|
||||
settings.FileLoggerOptions.FileNamePrefix = defaultPrefix ? "EonaCat" : string.Empty;
|
||||
}
|
||||
private void ProcessExit(object sender, EventArgs e)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void SetupLogManager()
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit += ProcessExit;
|
||||
_logDate = CurrentDateTme;
|
||||
}
|
||||
private Task StopLoggingAsync()
|
||||
{
|
||||
WriteStopMessage();
|
||||
IsRunning = false;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void ProcessExit(object sender, EventArgs e)
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
private void WriteStopMessage()
|
||||
{
|
||||
var stopMessage = $"{DllInfo.ApplicationName} stopped.{Environment.NewLine}";
|
||||
LogHelper.SendToFile(Logger, Settings, ELogType.INFO, stopMessage);
|
||||
}
|
||||
|
||||
private Task StopLoggingAsync()
|
||||
{
|
||||
WriteStopMessage();
|
||||
IsRunning = false;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
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);
|
||||
public void DeleteCurrentLogFile()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(CurrentLogFile))
|
||||
{
|
||||
File.Delete(CurrentLogFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class LoggerSettings
|
||||
|
||||
private FileLoggerOptions _fileLoggerOptions;
|
||||
|
||||
private string _headerFormat = "{ts} {host} {thread} {sev}";
|
||||
private string _headerFormat = "{ts} {host} {category} {thread} {sev}";
|
||||
private int _maxMessageLength = 1024;
|
||||
private string _timestampFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
@@ -43,9 +43,10 @@ public class LoggerSettings
|
||||
/// variables including:
|
||||
/// {ts}: UTC timestamp
|
||||
/// {host}: Hostname
|
||||
/// {category}: Category
|
||||
/// {thread}: Thread ID
|
||||
/// {sev}: Severity
|
||||
/// Default: {ts} {host} {thread} {sev}
|
||||
/// Default: {ts} {host} {category} {thread} {sev}
|
||||
/// A space will be inserted between the header and the message.
|
||||
/// </summary>
|
||||
public string HeaderFormat
|
||||
@@ -53,8 +54,14 @@ public class LoggerSettings
|
||||
get => _headerFormat;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) _headerFormat = "";
|
||||
else _headerFormat = value;
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
_headerFormat = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
_headerFormat = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +73,11 @@ public class LoggerSettings
|
||||
get => _timestampFormat;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(HeaderFormat));
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(HeaderFormat));
|
||||
}
|
||||
|
||||
_timestampFormat = value;
|
||||
}
|
||||
}
|
||||
@@ -81,8 +92,14 @@ public class LoggerSettings
|
||||
get => _enableConsole;
|
||||
set
|
||||
{
|
||||
if (value) _enableConsole = ConsoleExists();
|
||||
else _enableConsole = false;
|
||||
if (value)
|
||||
{
|
||||
_enableConsole = ConsoleExists();
|
||||
}
|
||||
else
|
||||
{
|
||||
_enableConsole = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +116,11 @@ public class LoggerSettings
|
||||
get => _colors;
|
||||
set
|
||||
{
|
||||
if (value == null) throw new ArgumentNullException(nameof(Colors));
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Colors));
|
||||
}
|
||||
|
||||
_colors = value;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +151,11 @@ public class LoggerSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_fileLoggerOptions == null) _fileLoggerOptions = CreateDefaultFileLoggerOptions();
|
||||
if (_fileLoggerOptions == null)
|
||||
{
|
||||
_fileLoggerOptions = CreateDefaultFileLoggerOptions();
|
||||
}
|
||||
|
||||
return _fileLoggerOptions;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@ public class SplunkServer
|
||||
SplunkHecUrl = splunkHecUrl;
|
||||
SplunkHecToken = splunkHecToken;
|
||||
|
||||
if (httpClientHandler == null) httpClientHandler = new HttpClientHandler();
|
||||
if (httpClientHandler == null)
|
||||
{
|
||||
httpClientHandler = new HttpClientHandler();
|
||||
}
|
||||
|
||||
SplunkClientHandler = httpClientHandler;
|
||||
CreateHttpClient();
|
||||
@@ -45,7 +48,10 @@ public class SplunkServer
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_splunkHecUrl) && !_splunkHecUrl.ToLower().Contains("http"))
|
||||
{
|
||||
value = $"http://{value}";
|
||||
}
|
||||
|
||||
_splunkHecUrl = value;
|
||||
}
|
||||
}
|
||||
@@ -103,7 +109,10 @@ public class SplunkServer
|
||||
|
||||
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
|
||||
var eventObject = new
|
||||
@@ -116,7 +125,10 @@ public class SplunkServer
|
||||
// Serialize the event object to JSON
|
||||
var eventJson = JsonHelper.ToJson(eventObject);
|
||||
|
||||
if (!HasHecToken) CreateHttpClient();
|
||||
if (!HasHecToken)
|
||||
{
|
||||
CreateHttpClient();
|
||||
}
|
||||
|
||||
// Create an HTTP content with the event data
|
||||
var content = new StringContent(eventJson, Encoding.UTF8, "application/json");
|
||||
|
||||
@@ -42,7 +42,11 @@ public class SyslogServer
|
||||
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(Hostname));
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Hostname));
|
||||
}
|
||||
|
||||
_Hostname = value;
|
||||
|
||||
SetUdp();
|
||||
@@ -57,7 +61,11 @@ public class SyslogServer
|
||||
get => _Port;
|
||||
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;
|
||||
|
||||
SetUdp();
|
||||
|
||||
58
README.md
58
README.md
@@ -11,14 +11,14 @@ Microsoft.Extensions.Logging
|
||||
|
||||
**Easy way of logging without configuring anything:**
|
||||
```csharp
|
||||
LogManager.Instance.Write("INFO", ELogType.INFO, true);
|
||||
LogManager.Instance.Write("WARNING", ELogType.WARNING, true);
|
||||
LogManager.Instance.Write("ERROR", ELogType.ERROR, true);
|
||||
LogManager.Instance.Write("DEBUG", ELogType.DEBUG, true);
|
||||
LogManager.Instance.Write("CRITICAL", ELogType.CRITICAL, true);
|
||||
LogManager.Instance.Write("TRACE", ELogType.TRACE, true);
|
||||
LogManager.Instance.Write("TRAFFIC", ELogType.TRAFFIC, true);
|
||||
LogManager.Instance.Write("NONE", ELogType.NONE, true);
|
||||
LogManager.Instance.WriteAsync("INFO", ELogType.INFO, true);
|
||||
LogManager.Instance.WriteAsync("WARNING", ELogType.WARNING, true);
|
||||
LogManager.Instance.WriteAsync("ERROR", ELogType.ERROR, true);
|
||||
LogManager.Instance.WriteAsync("DEBUG", ELogType.DEBUG, true);
|
||||
LogManager.Instance.WriteAsync("CRITICAL", ELogType.CRITICAL, true);
|
||||
LogManager.Instance.WriteAsync("TRACE", ELogType.TRACE, true);
|
||||
LogManager.Instance.WriteAsync("TRAFFIC", ELogType.TRAFFIC, true);
|
||||
LogManager.Instance.WriteAsync("NONE", ELogType.NONE, true);
|
||||
```
|
||||
|
||||
**Logging in .NET 4.8 or higher: **
|
||||
@@ -186,28 +186,28 @@ namespace EonaCat.Logger.Advanced
|
||||
// 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)
|
||||
{
|
||||
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.
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
// 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.
|
||||
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.
|
||||
@@ -216,12 +216,12 @@ namespace EonaCat.Logger.Advanced
|
||||
if (grayLogSettings != null)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// Log a critical error message.
|
||||
_logManager.Write(message, ELogType.CRITICAL, writeToConsole);
|
||||
_logManager.WriteAsync(message, ELogType.CRITICAL, writeToConsole);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Log a regular error message.
|
||||
_logManager.Write(message, ELogType.ERROR, writeToConsole);
|
||||
_logManager.WriteAsync(message, ELogType.ERROR, writeToConsole);
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
Write(message, ELogType.WARNING, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
|
||||
WriteAsync(message, ELogType.WARNING, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
Write(message, ELogType.CRITICAL, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
|
||||
WriteAsync(message, ELogType.CRITICAL, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
Write(message, ELogType.TRAFFIC, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
|
||||
WriteAsync(message, ELogType.TRAFFIC, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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 :)
|
||||
for (int i = 0; i < 10000000; i++)
|
||||
{
|
||||
logger.Write($"test to file {i} INFO", ELogType.INFO);
|
||||
logger.Write($"test to file {i} CRITICAL", ELogType.CRITICAL);
|
||||
logger.Write($"test to file {i} DEBUG", ELogType.DEBUG);
|
||||
logger.Write($"test to file {i} ERROR", ELogType.ERROR);
|
||||
logger.Write($"test to file {i} TRACE", ELogType.TRACE);
|
||||
logger.Write($"test to file {i} TRAFFIC", ELogType.TRAFFIC);
|
||||
logger.Write($"test to file {i} WARNING", ELogType.WARNING);
|
||||
logger.Write($"test to file {i} NONE", ELogType.NONE);
|
||||
logger.WriteAsync($"test to file {i} INFO", ELogType.INFO);
|
||||
logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL);
|
||||
logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG);
|
||||
logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR);
|
||||
logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE);
|
||||
logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC);
|
||||
logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING);
|
||||
logger.WriteAsync($"test to file {i} NONE", ELogType.NONE);
|
||||
Console.WriteLine($"Logged: {i}");
|
||||
Task.Delay(1);
|
||||
}
|
||||
|
||||
@@ -5,29 +5,52 @@ using EonaCat.Logger.Managers;
|
||||
|
||||
namespace EonaCat.Logger.Test.Web;
|
||||
|
||||
public static class Logger
|
||||
public class Logger
|
||||
{
|
||||
private static LogManager LogManager;
|
||||
public static ELogType MaxLogType { get; set; }
|
||||
public static bool UseLocalTime { get; set; }
|
||||
public static string LogFolder => Path.Combine(FileLoggerOptions.DefaultPath, "logs");
|
||||
public static string CurrentLogFile => LogManager.CurrentLogFile;
|
||||
public static bool IsDisabled { get; set; }
|
||||
private LogManager _logManager;
|
||||
public ELogType MaxLogType { get; set; }
|
||||
public LoggerSettings LoggerSettings { get; }
|
||||
public bool UseLocalTime { get; set; }
|
||||
public string LogFolder { get; set; } = Path.Combine(FileLoggerOptions.DefaultPath, "logs");
|
||||
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)
|
||||
return;
|
||||
UseLocalTime = useLocalTime;
|
||||
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);
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@@ -39,7 +62,9 @@ public static class Logger
|
||||
response.Headers.ContentDisposition = "attachment;filename=" + logFileName;
|
||||
|
||||
if (limit > fS.Length || limit < 1)
|
||||
{
|
||||
limit = fS.Length;
|
||||
}
|
||||
|
||||
var oFS = new OffsetStream(fS, 0, limit);
|
||||
var request = context.Request;
|
||||
@@ -81,43 +106,32 @@ public static class Logger
|
||||
await oFS.CopyToAsync(stream).ConfigureAwait(false);
|
||||
|
||||
if (fS.Length > limit)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using EonaCat.Logger;
|
||||
using EonaCat.Logger.EonaCatCoreLogger;
|
||||
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
||||
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
||||
using EonaCat.Logger.Managers;
|
||||
using EonaCat.Logger.Test.Web;
|
||||
using EonaCat.Web.RateLimiter;
|
||||
@@ -8,11 +9,21 @@ using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
||||
using EonaCat.Web.Tracer.Extensions;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
int onLogCounter = 0;
|
||||
var defaultColor = Console.ForegroundColor;
|
||||
|
||||
// Add services to the container.
|
||||
Logger.UseLocalTime = true;
|
||||
Logger.MaxLogType = ELogType.TRACE;
|
||||
Logger.Configure();
|
||||
Logger logger = new Logger();
|
||||
logger.UseLocalTime = true;
|
||||
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();
|
||||
options.MaxRolloverFiles = 5;
|
||||
@@ -124,11 +135,11 @@ void RunLoggingExceptionTests()
|
||||
}
|
||||
}
|
||||
|
||||
Task.Run(RunWebLoggerTests).ConfigureAwait(false);
|
||||
Task.Run(RunWebLoggingTests).ConfigureAwait(false);
|
||||
Task.Run(RunLoggingTests).ConfigureAwait(false);
|
||||
Task.Run(RunLoggingExceptionTests).ConfigureAwait(false);
|
||||
Task.Run(RunWebLoggingExceptionTests).ConfigureAwait(false);
|
||||
await Task.Run(RunWebLoggerTestsAsync).ConfigureAwait(false);
|
||||
await Task.Run(RunWebLoggingTests).ConfigureAwait(false);
|
||||
await Task.Run(RunLoggingTestsAsync).ConfigureAwait(false);
|
||||
await Task.Run(RunLoggingExceptionTests).ConfigureAwait(false);
|
||||
await Task.Run(RunWebLoggingExceptionTests).ConfigureAwait(false);
|
||||
|
||||
void RunWebLoggingExceptionTests()
|
||||
{
|
||||
@@ -155,12 +166,15 @@ void RunWebLoggingExceptionTests()
|
||||
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -169,7 +183,7 @@ async void RunWebLoggingTests()
|
||||
}
|
||||
}
|
||||
|
||||
void RunLoggingTests()
|
||||
async Task RunLoggingTestsAsync()
|
||||
{
|
||||
var loggerSettings = new LoggerSettings();
|
||||
loggerSettings.UseLocalTime = true;
|
||||
@@ -182,38 +196,37 @@ void RunLoggingTests()
|
||||
|
||||
for (var i = 0; i < 9000000; i++)
|
||||
{
|
||||
logger.WriteAsync($"test to file {i} INFO").ConfigureAwait(false);
|
||||
logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
|
||||
logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
|
||||
logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
|
||||
logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
|
||||
logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
|
||||
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} INFO").ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING).ConfigureAwait(false);
|
||||
await logger.WriteAsync($"test to file {i} NONE", ELogType.NONE).ConfigureAwait(false);
|
||||
Console.WriteLine($"Logged: {i}");
|
||||
Task.Delay(1);
|
||||
await Task.Delay(1).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
void RunWebLoggerTests()
|
||||
async Task RunWebLoggerTestsAsync()
|
||||
{
|
||||
var i = 0;
|
||||
while (true)
|
||||
{
|
||||
i++;
|
||||
Task.Run(() =>
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
Logger.LogAsync($"test via logger {i} INFO");
|
||||
Logger.LogAsync($"test via logger {i} CRITICAL", ELogType.CRITICAL);
|
||||
Logger.LogAsync($"test via logger {i} DEBUG", ELogType.DEBUG);
|
||||
Logger.LogAsync($"test via logger {i} ERROR", ELogType.ERROR);
|
||||
Logger.LogAsync($"test via logger {i} TRACE", ELogType.TRACE);
|
||||
Logger.LogAsync($"test via logger {i} TRAFFIC", ELogType.TRAFFIC);
|
||||
Logger.LogAsync($"test via logger {i} WARNING", ELogType.WARNING);
|
||||
Logger.LogAsync($"test via logger {i} NONE", ELogType.NONE);
|
||||
});
|
||||
Console.WriteLine($"Logger: {i}");
|
||||
Task.Delay(1);
|
||||
await logger.LogAsync($"test via logger {i} INFO").ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} WARNING", ELogType.WARNING).ConfigureAwait(false);
|
||||
await logger.LogAsync($"test via logger {i} NONE", ELogType.NONE).ConfigureAwait(false);
|
||||
}).ConfigureAwait(false);
|
||||
await Task.Delay(1).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user