You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
6.0 KiB
168 lines
6.0 KiB
using Common.Logging;
|
|
using Serilog;
|
|
using Serilog.Core;
|
|
using Serilog.Events;
|
|
|
|
namespace Common.Logger;
|
|
|
|
/// <summary>
|
|
/// Implements a Logger that uses the Serilog package to create log entries and distributes them into different sinks.
|
|
/// Implemented Sinks: File (rolling file), Debug (<see cref="System.Diagnostics.Debug"/>).
|
|
/// </summary>
|
|
public class SerilogLogger : Logging.ILogger
|
|
{
|
|
private readonly LoggingLevelSwitch loggingLevelSwitch;
|
|
public event EventHandler<NewLogEntryEventArgs>? NewLogEntry;
|
|
|
|
/// <summary>
|
|
/// Constructor of a Logger that uses the Serilog package to create log entries and distributes them into different sinks.
|
|
/// </summary>
|
|
/// <param name="logFilePath">
|
|
/// path where the logfile shall be created.
|
|
/// rolling file is created with daily interval. date is automatically added to file name.
|
|
/// Example: "C:/log/log-.txt"
|
|
/// </param>
|
|
/// <param name="logToDebug">
|
|
/// if true the log entries are written to <see cref="System.Diagnostics.Debug"/>.
|
|
/// Minimum level is ignored for this log entries, therefore every log entry will be logged.
|
|
/// </param>
|
|
public SerilogLogger(string logFilePath, bool logToDebug)
|
|
{
|
|
// create logging level switch and initialized with lowest level
|
|
this.loggingLevelSwitch = new LoggingLevelSwitch() { MinimumLevel = Serilog.Events.LogEventLevel.Verbose };
|
|
|
|
// create logger instance
|
|
if (logToDebug)
|
|
{
|
|
Log.Logger = new LoggerConfiguration()
|
|
.WriteTo.Debug()
|
|
.WriteTo.File(logFilePath,
|
|
rollingInterval: RollingInterval.Day,
|
|
levelSwitch: loggingLevelSwitch,
|
|
outputTemplate: "{Message:lj}") // outputTemplate = plain message, formatting is done inside log entry
|
|
.CreateLogger();
|
|
}
|
|
else
|
|
{
|
|
Log.Logger = new LoggerConfiguration()
|
|
.WriteTo.File(logFilePath,
|
|
rollingInterval: RollingInterval.Day,
|
|
levelSwitch: loggingLevelSwitch,
|
|
outputTemplate: "{Message:lj}") // outputTemplate = plain message, formatting is done inside log entry
|
|
.CreateLogger();
|
|
}
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
this.Initialize(LogLevel.Trace);
|
|
}
|
|
|
|
public void Initialize(LogLevel minimumLogLevel)
|
|
{
|
|
this.SetMinimumLogLevel(minimumLogLevel);
|
|
// Nothing else to do for this logger
|
|
}
|
|
|
|
public void SetMinimumLogLevel(LogLevel newMinimumLogLevel)
|
|
{
|
|
this.loggingLevelSwitch.MinimumLevel = this.ConvertGenericToSerilogLogLevel(newMinimumLogLevel);
|
|
}
|
|
|
|
private LogEventLevel ConvertGenericToSerilogLogLevel(LogLevel newMinimumLogLevel) => newMinimumLogLevel switch
|
|
{
|
|
LogLevel.Undefined => LogEventLevel.Verbose,
|
|
LogLevel.Trace => LogEventLevel.Verbose,
|
|
LogLevel.Debug => LogEventLevel.Debug,
|
|
LogLevel.Info => LogEventLevel.Information,
|
|
LogLevel.Warn => LogEventLevel.Warning,
|
|
LogLevel.Error => LogEventLevel.Error,
|
|
_ => throw new NotImplementedException($"'{nameof(ConvertGenericToSerilogLogLevel)}()' does not contain an entry for {nameof(LogLevel)} {newMinimumLogLevel}"),
|
|
};
|
|
|
|
public void StopLogging()
|
|
{
|
|
Log.CloseAndFlush();
|
|
}
|
|
|
|
private void CreateLogEntry(LogEntry logEntry)
|
|
{
|
|
var serilogEventLevel = this.ConvertGenericToSerilogLogLevel(logEntry.LogLevel);
|
|
// formatting is done inside logEntry.ToString() method => therefore log plain message text with right category
|
|
switch (serilogEventLevel)
|
|
{
|
|
case LogEventLevel.Verbose:
|
|
Log.Verbose(logEntry.ToString());
|
|
break;
|
|
|
|
case LogEventLevel.Debug:
|
|
Log.Debug(logEntry.ToString());
|
|
break;
|
|
|
|
case LogEventLevel.Information:
|
|
Log.Information(logEntry.ToString());
|
|
break;
|
|
|
|
case LogEventLevel.Warning:
|
|
Log.Warning(logEntry.ToString());
|
|
break;
|
|
|
|
case LogEventLevel.Error:
|
|
Log.Error(logEntry.ToString());
|
|
break;
|
|
|
|
case LogEventLevel.Fatal:
|
|
Log.Error(logEntry.ToString());
|
|
break;
|
|
|
|
default:
|
|
throw new NotImplementedException($"'{nameof(CreateLogEntry)}()' does not contain an implementation for {nameof(LogEventLevel)} {serilogEventLevel}.");
|
|
}
|
|
}
|
|
|
|
|
|
#region Logging methods
|
|
public void LogTrace(string message, string category = "")
|
|
{
|
|
this.CreateLogEntry(new LogEntry { Category = category, LogLevel = LogLevel.Trace, Message = message });
|
|
}
|
|
|
|
public void LogDebug(string message, string category = "")
|
|
{
|
|
this.CreateLogEntry(new LogEntry { Category = category, LogLevel = LogLevel.Debug, Message = message });
|
|
}
|
|
|
|
public void LogInfo(string message, string category = "")
|
|
{
|
|
this.CreateLogEntry(new LogEntry { Category = category, LogLevel = LogLevel.Info, Message = message });
|
|
}
|
|
|
|
public void LogWarn(string message, string category = "")
|
|
{
|
|
this.CreateLogEntry(new LogEntry { Category = category, LogLevel = LogLevel.Warn, Message = message });
|
|
}
|
|
|
|
public void LogError(string message, string category = "")
|
|
{
|
|
this.CreateLogEntry(new LogEntry { Category = category, LogLevel = LogLevel.Error, Message = message });
|
|
}
|
|
|
|
public void LogException(Exception exception, string category = "")
|
|
{
|
|
this.CreateLogEntry(new LogEntry { Category = category, LogLevel = LogLevel.Error, Exception = exception });
|
|
}
|
|
|
|
public void LogException(Exception exception, string message, string category = "")
|
|
{
|
|
this.CreateLogEntry(
|
|
new LogEntry
|
|
{
|
|
Category = category,
|
|
LogLevel = LogLevel.Error,
|
|
Message = message,
|
|
Exception = exception
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
|