[英]Dynamically set EventID when logging to Event Viewer using Serilog
目前,我已經將我的記錄器設置為像這樣記錄到事件查看器:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.EventLog("MySource", "EventViewerArea")
.CreateLogger();
當我登錄時,我使用以下命令:
_logger.LogWarning(logText);
看起來我可以將 EventId 傳遞給 LogWarning 方法,所以我想在運行 LogWarning/LogInformation 方法時設置它:
_logger.LogWarning(9876, logText);
但這不會覆蓋事件查看器條目中的事件 ID。 關於如何在記錄時動態設置此 EventId 的任何想法? 在實例化記錄器時,我需要有這個動態而不是設置為一個值。
提前致謝
我能夠通過以下步驟解決此問題:
在實例化記錄器時添加以下內容:
.WriteTo.EventLog("SourceInEventViewer",
"AreaInEventViewer",
formatProvider: new EventLogFormatProvider(),
eventIdProvider: new EventIdProvider(),
manageEventSource: true,
restrictedToMinimumLevel: LogEventLevel.Information)
將以下類添加到項目中
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;
}
}
}
}
}
現在您可以使用日志並將您的事件 ID 傳遞給它:
_logger.LogInformation(LogValuesEnum.MyEnumVal, "My log message");
如果您檢查事件日志接收器的源代碼,您會發現它使用EventIdHashProvider
通過對事件消息進行哈希處理來生成唯一 ID。
您可以做的是在配置接收器時提供IEventIdProvider
接口的實現,如下所示(添加了eventIdProvider: new CustomEventIdProvider()
):
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.EventLog("MySource", "EventViewerArea", eventIdProvider: new CustomEventIdProvider())
.CreateLogger();
.LogWarnning()
來自Microsoft.Extensions.Logging
。 它實際上接受從 int 隱式轉換的EventId strcut。
但是正如您所看到的,這個 id 從未在接收器中使用過。 EventId 用於輕松跟蹤事件的身份,但我不確定是否有任何接收器正在重用此 ID ... EventLog
接收器沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.