Currently, I have set up my logger to log to the event viewer like so:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.EventLog("MySource", "EventViewerArea")
.CreateLogger();
When I log I use the following command:
_logger.LogWarning(logText);
It looks as though I can pass in the EventId to the LogWarning method, so I wanted to set it when running the LogWarning/LogInformation methods:
_logger.LogWarning(9876, logText);
But this does not override the Event ID in the entry in the Event Viewer. Any ideas on how I can dynamically set this EventId when logging? I need to have this dynamic and not set to one value when instantiating the logger.
Thanks in advance
I was able to solve this with the following steps:
Add the following when instantiating the logger:
.WriteTo.EventLog("SourceInEventViewer",
"AreaInEventViewer",
formatProvider: new EventLogFormatProvider(),
eventIdProvider: new EventIdProvider(),
manageEventSource: true,
restrictedToMinimumLevel: LogEventLevel.Information)
Add the following class to the project
using Newtonsoft.Json.Linq;
using Serilog.Events;
using Serilog.Sinks.EventLog;
using System;
using System.Linq;
namespace IndependentFile.Extensions
{
public class LoggerSetupExtensions
{
public class EventLogFormatProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
return formatType == typeof(ICustomFormatter) ? this : null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
return arg.ToString();
}
}
public class EventIdProvider : IEventIdProvider
{
public ushort ComputeEventId(LogEvent logEvent)
{
var eventTypeProp = logEvent.Properties.FirstOrDefault(prop => prop.Key == "EventId");
if (eventTypeProp.Value == null)
{
return (ushort)LogValuesEnum.Unknown;
}
try
{
var val = eventTypeProp.Value;
string eventType = eventTypeProp.Value.ToString();
//this is not the right way to parse the logEventPropertyValue
var parseEventType = JObject.Parse(eventType);
var eventIdInt = parseEventType["Id"].ToString();
if (eventType == null) return (int)LogValuesEnum.Unknown;
var tryParseEventId = Enum.TryParse<LogValuesEnum>(eventIdInt, ignoreCase: true, out var res);
if (tryParseEventId)
{
return (ushort)res;
}
return (ushort)LogValuesEnum.Unknown;
}
catch(Exception exc)
{
return (ushort)LogValuesEnum.Unknown;
}
}
}
}
}
Now you can use the log and pass your event id to that:
_logger.LogInformation(LogValuesEnum.MyEnumVal, "My log message");