mirror of
https://github.com/hmaxnl/DotBased.git
synced 2025-01-18 18:14:20 +01:00
Compare commits
4 Commits
448d85d6f6
...
a3be0d9648
Author | SHA1 | Date | |
---|---|---|---|
|
a3be0d9648 | ||
|
7ec3257eac | ||
|
91476907f0 | ||
|
e1cba8d68c |
|
@ -4,6 +4,7 @@ namespace DotBased.Logging.MEL;
|
||||||
|
|
||||||
public class BasedLogger : Microsoft.Extensions.Logging.ILogger
|
public class BasedLogger : Microsoft.Extensions.Logging.ILogger
|
||||||
{
|
{
|
||||||
|
private const string _messageTemplateKey = "{OriginalFormat}";
|
||||||
public BasedLogger(ILogger logger)
|
public BasedLogger(ILogger logger)
|
||||||
{
|
{
|
||||||
basedLogger = logger;
|
basedLogger = logger;
|
||||||
|
@ -22,24 +23,26 @@ public class BasedLogger : Microsoft.Extensions.Logging.ILogger
|
||||||
|
|
||||||
private LogCapsule ConstructCapsule<TState>(LogSeverity severity, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
|
private LogCapsule ConstructCapsule<TState>(LogSeverity severity, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
|
||||||
{
|
{
|
||||||
//TODO: Extract parameters & format
|
|
||||||
var msgTemplate = string.Empty;
|
var msgTemplate = string.Empty;
|
||||||
|
List<object?> templateParams = [];
|
||||||
if (state is IEnumerable<KeyValuePair<string, object>> stateEnum)
|
if (state is IEnumerable<KeyValuePair<string, object>> stateEnum)
|
||||||
{
|
{
|
||||||
foreach (var prop in stateEnum)
|
foreach (var prop in stateEnum)
|
||||||
{
|
{
|
||||||
if (prop is { Key: "{OriginalFormat}", Value: string propValueString })
|
if (prop is { Key: _messageTemplateKey, Value: string propValueString })
|
||||||
{
|
{
|
||||||
msgTemplate = propValueString;
|
msgTemplate = propValueString;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
templateParams.Add(prop.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LogCapsule()
|
return new LogCapsule()
|
||||||
{
|
{
|
||||||
Exception = exception,
|
Exception = exception,
|
||||||
Message = formatter.Invoke(state, exception),
|
Message = msgTemplate,
|
||||||
Parameters = [],
|
Parameters = templateParams.ToArray(),
|
||||||
Severity = severity,
|
Severity = severity,
|
||||||
TimeStamp = DateTime.Now,
|
TimeStamp = DateTime.Now,
|
||||||
Logger = basedLogger as LoggerBase ?? throw new NullReferenceException(nameof(basedLogger))
|
Logger = basedLogger as LoggerBase ?? throw new NullReferenceException(nameof(basedLogger))
|
||||||
|
|
|
@ -4,11 +4,10 @@ namespace DotBased.Logging.MEL;
|
||||||
|
|
||||||
public static class LoggerBuilderExtensions
|
public static class LoggerBuilderExtensions
|
||||||
{
|
{
|
||||||
public static ILoggingBuilder AddDotBased(this ILoggingBuilder builder, LogOptions options)
|
public static void AddDotBasedLoggerProvider(this ILoggingBuilder builder, LogOptions options)
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
throw new ArgumentNullException(nameof(builder));
|
throw new ArgumentNullException(nameof(builder));
|
||||||
builder.AddProvider(new BasedLoggerProvider(options));
|
builder.AddProvider(new BasedLoggerProvider(options));
|
||||||
return builder;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@ public static class BasedSerilog
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default output template with the extra properties that can be used for serilog sinks.
|
/// Default output template with the extra properties that can be used for serilog sinks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string OutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3} - {LoggerName}]{NewLine} {Message:lj}{NewLine}{Exception}";
|
public const string OutputTemplate = "[{Timestamp:HH:mm:ss} {Level} - {LoggerName}] {Message:lj}{NewLine}{Exception}";
|
||||||
|
|
||||||
public static LoggerConfiguration UseBasedExtension(this LoggerConfiguration loggerConfiguration)
|
public static LoggerConfiguration UseBasedExtension(this LoggerConfiguration loggerConfiguration)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace DotBased.Logging;
|
namespace DotBased.Logging;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -7,21 +9,16 @@ public class LogProcessor : IDisposable
|
||||||
{
|
{
|
||||||
public LogProcessor()
|
public LogProcessor()
|
||||||
{
|
{
|
||||||
_processorQueue = new Queue<LogCapsule>();
|
_canLog = true;
|
||||||
|
_capsuleCollection = new BlockingCollection<LogCapsule>();
|
||||||
IncomingLogHandlerEvent = IncomingLogHandler;
|
IncomingLogHandlerEvent = IncomingLogHandler;
|
||||||
_processorThread = new Thread(ProcessLog)
|
_processTask = Task.Factory.StartNew(ProcessLog);
|
||||||
{
|
|
||||||
IsBackground = true,
|
|
||||||
Name = "Log processor thread (DotBased)"
|
|
||||||
};
|
|
||||||
_processorThread.Start();
|
|
||||||
}
|
}
|
||||||
public readonly Action<LogCapsule> IncomingLogHandlerEvent;
|
public readonly Action<LogCapsule> IncomingLogHandlerEvent;
|
||||||
public event EventHandler<LogCapsule>? LogProcessed;
|
public event EventHandler<LogCapsule>? LogProcessed;
|
||||||
private readonly Queue<LogCapsule> _processorQueue;
|
private bool _canLog;
|
||||||
private readonly Thread _processorThread;
|
private readonly BlockingCollection<LogCapsule> _capsuleCollection;
|
||||||
private readonly ManualResetEvent _threadSuspendEvent = new ManualResetEvent(false);
|
private readonly Task _processTask;
|
||||||
private readonly ManualResetEvent _threadShutdownEvent = new ManualResetEvent(false);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop the LogProcessor
|
/// Stop the LogProcessor
|
||||||
|
@ -31,9 +28,9 @@ public class LogProcessor : IDisposable
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_threadShutdownEvent.Set();
|
_canLog = false;
|
||||||
_threadSuspendEvent.Set();
|
_capsuleCollection.CompleteAdding();
|
||||||
_processorThread.Join();
|
_processTask.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -43,35 +40,31 @@ public class LogProcessor : IDisposable
|
||||||
|
|
||||||
private void IncomingLogHandler(LogCapsule e)
|
private void IncomingLogHandler(LogCapsule e)
|
||||||
{
|
{
|
||||||
_processorQueue.Enqueue(e);
|
if (!_canLog)
|
||||||
// Check if the thread is running, if not wake up the thread.
|
return;
|
||||||
if (!_threadSuspendEvent.WaitOne(0))
|
if (!_capsuleCollection.TryAdd(e))
|
||||||
_threadSuspendEvent.Set();
|
{
|
||||||
|
_canLog = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessLog()
|
private void ProcessLog()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (true)
|
while (!_capsuleCollection.IsCompleted)
|
||||||
{
|
{
|
||||||
_threadSuspendEvent.WaitOne(Timeout.Infinite);
|
if (_capsuleCollection.TryTake(out var capsule, Timeout.Infinite))
|
||||||
|
|
||||||
if (_threadShutdownEvent.WaitOne(0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (_processorQueue.Count != 0)
|
|
||||||
{
|
{
|
||||||
var capsule = _processorQueue.Dequeue();
|
|
||||||
if (!LogService.CanLog(LogService.Options.Severity, capsule.Severity))
|
if (!LogService.CanLog(LogService.Options.Severity, capsule.Severity))
|
||||||
continue;
|
continue;
|
||||||
if (LogService.FilterSeverityLog(capsule))
|
if (LogService.FilterSeverityLog(capsule))
|
||||||
LogProcessed?.Invoke(this, capsule);
|
LogProcessed?.Invoke(this, capsule);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_threadSuspendEvent.Reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{ }
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// Write exception to the output
|
// Write exception to the output
|
||||||
|
@ -81,7 +74,8 @@ public class LogProcessor : IDisposable
|
||||||
Console.ForegroundColor = ConsoleColor.Blue;
|
Console.ForegroundColor = ConsoleColor.Blue;
|
||||||
Console.Write($"[{DateTime.Now}] ");
|
Console.Write($"[{DateTime.Now}] ");
|
||||||
Console.ForegroundColor = oldColor;
|
Console.ForegroundColor = oldColor;
|
||||||
Console.WriteLine($"[{nameof(LogProcessor)} (DotBased)] Log processor thread failed! No logs are being processed!");
|
Console.WriteLine(
|
||||||
|
$"[{nameof(LogProcessor)} (DotBased)] Log processor thread failed! No logs are being processed!");
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
|
|
@ -16,7 +16,7 @@ var serilogLogger = SetupSerilog();
|
||||||
LogService.AddLogAdapter(new BasedSerilogAdapter(serilogLogger));
|
LogService.AddLogAdapter(new BasedSerilogAdapter(serilogLogger));
|
||||||
|
|
||||||
builder.Logging.ClearProviders();
|
builder.Logging.ClearProviders();
|
||||||
builder.Logging.AddDotBased(LogService.Options);
|
builder.Logging.AddDotBasedLoggerProvider(LogService.Options);
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
|
@ -25,8 +25,6 @@ builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
|
|
41
TestWebApi/Properties/launchSettings.json
Normal file
41
TestWebApi/Properties/launchSettings.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:35507",
|
||||||
|
"sslPort": 44353
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:5044",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7234;http://localhost:5044",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
TestWebApi/appsettings.Development.json
Normal file
3
TestWebApi/appsettings.Development.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
3
TestWebApi/appsettings.json
Normal file
3
TestWebApi/appsettings.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user