Files
EonaCat.Logger/EonaCat.Logger/EonaCatCoreLogger/DatabaseLogger.cs
2025-04-27 08:07:47 +02:00

87 lines
3.2 KiB
C#

using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
namespace EonaCat.Logger.EonaCatCoreLogger
{
public class DatabaseLogger : ILogger
{
private readonly string _categoryName;
private readonly DatabaseLoggerOptions _options;
private readonly LoggerScopedContext _context = new();
public bool IncludeCorrelationId { get; set; }
public event EventHandler<Exception> OnException;
public DatabaseLogger(string categoryName, DatabaseLoggerOptions options)
{
_categoryName = categoryName;
_options = options;
IncludeCorrelationId = options.IncludeCorrelationId;
}
public IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => _options.IsEnabled;
public void SetContext(string key, string value) => _context.Set(key, value);
public void ClearContext() => _context.Clear();
public string GetContext(string key) => _context.Get(key);
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel) || formatter == null)
{
return;
}
var message = formatter(state, exception);
if (IncludeCorrelationId)
{
var correlationId = _context.Get("CorrelationId") ?? Guid.NewGuid().ToString();
_context.Set("CorrelationId", correlationId);
}
try
{
using var connection = _options.DbProviderFactory.CreateConnection();
if (connection == null)
{
throw new InvalidOperationException("Failed to create database connection.");
}
connection.ConnectionString = _options.ConnectionString;
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = _options.InsertCommand;
command.Parameters.Clear();
command.Parameters.Add(CreateParameter(command, "Timestamp", DateTime.UtcNow));
command.Parameters.Add(CreateParameter(command, "LogLevel", logLevel.ToString()));
command.Parameters.Add(CreateParameter(command, "Category", _categoryName));
command.Parameters.Add(CreateParameter(command, "Message", message));
command.Parameters.Add(CreateParameter(command, "Exception", exception?.ToString()));
command.Parameters.Add(CreateParameter(command, "CorrelationId", _context.Get("CorrelationId")));
command.ExecuteNonQuery();
}
catch (Exception e)
{
OnException?.Invoke(this, e);
}
}
private DbParameter CreateParameter(DbCommand command, string name, object value)
{
var param = command.CreateParameter();
param.ParameterName = $"@{name}";
param.Value = value ?? DBNull.Value;
return param;
}
}
}