serilog-sinks-eventlog icon indicating copy to clipboard operation
serilog-sinks-eventlog copied to clipboard

Different EventId for each Log

Open BernhardNinaus opened this issue 4 years ago • 0 comments

Hey.

Is there a way to specify a EventId for diffrent Log calls? If not, I came up with my own solution, maybe there is good use of such functionality.

I made use of the IEventIdProvider:

public class EventIdProvider : IEventIdProvider {
    public ushort ComputeEventId(LogEvent logEvent) {
        var val = (Serilog.Events.ScalarValue)logEvent.Properties.FirstOrDefault(f => f.Key == "eventId").Value;
        if (val?.Value != null && val.Value is ushort) {
            return (ushort)val.Value;
        }

        // My custom Part, but one could derive from EventIdHashProvider 
        // and call base.ComputeEventId(logEvent), if it weren't sealed
        if (logEvent.Level > LogEventLevel.Warning) {
            return 200;
        } else {
            return 100;
        }
    }
}

I use the Microsoft.Extensions.Logging.ILogger and worte an extension to it

public static class ILoggerExtension {
    public static LoggerEventId<T> WindowsEventEventId<T>(this ILogger<T> logger, ushort enventId) {
        return new LoggerEventId<T>(logger, enventId);
    }
}

where I return e new instance of a derived ILogger.

public class LoggerEventId<T> : ILogger {
    private readonly ushort _eventId;
    private readonly ILogger _logger;
    public LoggerEventId(ILogger<T> logger, ushort eventId) => (_logger, _eventId) = (logger, eventId);

    public IDisposable BeginScope<TState>(TState state) => _logger.BeginScope(state);
		
    public bool IsEnabled(LogLevel logLevel) => _logger.IsEnabled(logLevel);
		
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) {
        using (_logger.BeginScope(new Dictionary<string, ushort> { { "eventId", _eventId } })) {
             _logger.Log(logLevel, eventId, state, exception, formatter);
        }
    }
}

Calling looks something like this:

_logger.WindowsEventEventId(1).LogError("Error");
Log.ForContext("eventId", (ushort)1).Error("Error");

BernhardNinaus avatar Jul 14 '20 08:07 BernhardNinaus