Extends the Microsoft.Extensions.Logging class to provide a rolling file logger.
// ---------------------------------------------------------------------------
// Logging/FileLogger.cs
// https://github.com/NonFactors/AspNetCore.Template/blob/develop/src/MvcTemplate.Components/Logging/FileLogger.cs
// ---------------------------------------------------------------------------
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using DotnetCommon.Components.Extensions;
using System;
using System.IO;
using System.Text;
namespace Components.Logging
{
public class FileLogger : ILogger
{
private Int64 RollSize { get; }
private String LogPath { get; }
private String LogDirectory { get; }
private String RollingFileFormat { get; }
private IHttpContextAccessor Accessor { get; }
private static Object LogWriting { get; } = new Object();
public FileLogger(String path, Int64 rollSize)
{
String file = Path.GetFileNameWithoutExtension(path);
LogDirectory = Path.GetDirectoryName(path) ?? "";
String extension = Path.GetExtension(path);
Accessor = new HttpContextAccessor();
RollingFileFormat = $"{file}-{{0:yyyyMMdd-HHmmss}}{extension}";
RollSize = rollSize;
LogPath = path;
}
public Boolean IsEnabled(LogLevel logLevel)
{
return logLevel != LogLevel.None;
}
public IDisposable? BeginScope<TState>(TState state)
{
return null;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, String> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
StringBuilder log = new StringBuilder();
log.Append("Id : ").Append(Accessor.HttpContext?.TraceIdentifier).Append(" [").Append(Accessor.HttpContext?.User.Id()).AppendLine("]");
log.Append("Time : ").AppendFormat("{0:yyyy-MM-dd HH:mm:ss.ffffff}", DateTime.Now).AppendLine();
log.AppendFormat("{0,11}", logLevel).Append(": ").AppendLine(formatter(state, exception));
if (exception != null)
{
log.AppendLine("Stack trace:");
}
while (exception != null)
{
log.Append(" ").Append(exception.GetType()).Append(": ").AppendLine(exception.Message);
if (exception.StackTrace is String stackTrace)
{
foreach (String line in stackTrace.Split('\n'))
{
log.Append(" ").AppendLine(line.TrimEnd('\r'));
}
}
exception = exception.InnerException;
}
log.AppendLine();
lock (LogWriting)
{
Directory.CreateDirectory(LogDirectory);
File.AppendAllText(LogPath, log.ToString());
if (RollSize <= new FileInfo(LogPath).Length)
{
File.Move(LogPath, Path.Combine(LogDirectory, String.Format(RollingFileFormat, DateTime.Now)));
}
}
}
}
}
// ---------------------------------------------------------------------------
// Logging/FileLoggerProvider.cs
// https://github.com/NonFactors/AspNetCore.Template/blob/develop/src/MvcTemplate.Components/Logging/FileLoggerProvider.cs
// ---------------------------------------------------------------------------
using Microsoft.Extensions.Logging;
using System;
namespace Components.Logging
{
[ProviderAlias("File")]
public class FileLoggerProvider : ILoggerProvider
{
private ILogger Logger { get; }
public FileLoggerProvider(String path, Int64 rollSize)
{
Logger = new FileLogger(path, rollSize);
}
public ILogger CreateLogger(String categoryName)
{
return Logger;
}
public void Dispose()
{
}
}
}
// ---------------------------------------------------------------------------
// Startup.cs
// https://github.com/NonFactors/AspNetCore.Template/blob/develop/src/MvcTemplate.Web/Startup.cs
// ---------------------------------------------------------------------------
// ...
// ...
services.AddLogging(builder =>
{
builder.AddConfiguration(Config.GetSection("Logging"));
if (Environment.IsDevelopment())
{
builder.AddConsole();
}
else
{
builder.AddProvider(new FileLoggerProvider(Config["Logging:File:Path"], Config.GetValue<Int64>("Logging:File:RollSize")));
}
});
// ...
// ...
// ---------------------------------------------------------------------------
// Log Configuration section in "configuration.json"
// https://github.com/NonFactors/AspNetCore.Template/blob/develop/src/MvcTemplate.Web/configuration.json
// ---------------------------------------------------------------------------
//
// ...
// ...
//
// "Logging": {
// "File": {
// "Path": "Logs/log.txt",
// "RollSize": 5242880
// }
// }
//
// ...
// ...