Files
EonaCat.Logger/EonaCat.Logger/EonaCatCoreLogger/JsonFileLogger.cs

101 lines
3.4 KiB
C#

using EonaCat.Json;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
namespace EonaCat.Logger.EonaCatCoreLogger
{
// 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 JsonFileLogger : ILogger
{
private readonly string _categoryName;
private readonly JsonFileLoggerOptions _options;
private readonly string _filePath;
private readonly LoggerScopedContext _context = new();
private static readonly SemaphoreSlim _fileLock = new(1, 1);
public bool IncludeCorrelationId { get; set; }
public event EventHandler<Exception> OnException;
public JsonFileLogger(string categoryName, JsonFileLoggerOptions options)
{
_categoryName = categoryName;
_options = options;
_filePath = Path.Combine(_options.LogDirectory, _options.FileName);
IncludeCorrelationId = options.IncludeCorrelationId;
try
{
Directory.CreateDirectory(_options.LogDirectory);
}
catch (Exception ex)
{
OnException?.Invoke(this, ex);
}
}
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 IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => _options.IsEnabled;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel) || formatter == null)
{
return;
}
try
{
string message = formatter(state, exception);
if (IncludeCorrelationId)
{
var correlationId = _context.Get("CorrelationId") ?? Guid.NewGuid().ToString();
_context.Set("CorrelationId", correlationId);
}
var logObject = new Dictionary<string, object>
{
{ "timestamp", DateTime.UtcNow },
{ "level", logLevel.ToString() },
{ "category", _categoryName },
{ "message", message },
{ "exception", exception?.ToString() },
{ "eventId", eventId.Id }
};
var contextData = _context.GetAll();
if (contextData.Count > 0)
{
logObject["context"] = contextData;
}
string json = JsonHelper.ToJson(logObject);
_fileLock.Wait();
try
{
File.AppendAllText(_filePath, json + Environment.NewLine, Encoding.UTF8);
}
finally
{
_fileLock.Release();
}
}
catch (Exception ex)
{
OnException?.Invoke(this, ex);
}
}
}
}