我有一个应用程序,有多个部分。
我在整个过程中使用log4net来记录事件,我希望这些事件的源代码与他们来自的应用程序中的WHERE相匹配(你知道" SOURCE"暗示)。所以我在"应用程序和服务日志"下面有一个日志。并按照您的预期设置了log4net。
在log4net配置中有一个元素" applicationName"根据文档指定"将存储消息的日志名称。"
文档中的示例显示
<applicationName value="MyApp" />
Log4Net使用来自&#34; applicationName&#34;的值记录事件。根据log4net源代码中的文档,应该使用&#34; ApplicationName属性来区分事件&#34;。
因此假设LogName设置正确,我希望看到我的&#34; LogName&#34;在&#34;应用程序和服务日志&#34;在事件查看器中,然后我只需要设置applicationName以使源正确。但是,applicationName似乎只在配置中设置...但这意味着所有事件都记录在相同的源下:
如何设置源名称?有没有其他方法可以做到这一点?
答案 0 :(得分:4)
我没有找到答案,所以我下载了log4net的来源并决定弄明白。
以下代码段在log4net
中设置ApplicationName private static void SetEventSource(string sourceName)
{
var repository = LogManager.GetRepository();
if (repository != null)
{
var appender = repository.GetAppenders().Where(x => x.Name == "eventLogAppender").FirstOrDefault();
if (appender is log4net.Appender.EventLogAppender)
{
var eventAppender = (log4net.Appender.EventLogAppender)appender;
eventAppender.ApplicationName = sourceName;
eventAppender.ActivateOptions();
}
}
}
我有一个&#34; LoggingSources&#34;的枚举,所以当应用程序开始确保存在日志源时,我只是循环使用它。
public static void ConfigureWindowsEvents()
{
// Create event log sources for each of our Logging types
var loggingEvents = Enum.GetValues(typeof(LoggingSources));
foreach (var item in loggingSources)
{
string source = item.ToString();
if (!EventLog.SourceExists(source))
{
EventLog.CreateEventSource(source, EVENT_LOG_NAME);
}
}
}
然后当我记录一个事件时,我设置了源和事件id
public static void SetThreadContextAndLog(LoggingSources eventId, Action logAction)
{
if (logAction != null)
{
log4net.ThreadContext.Properties[EVENT_ID_KEY] = (int)eventId;
try
{
SetEventSource(eventId.ToString());
logAction();
}
finally
{
log4net.ThreadContext.Properties[EVENT_ID_KEY] = DEFAULT_EVENT_ID;
}
}
}
调用方法如下......
public static void LogEvent(LoggingSources pEvent, string pMessage, EventLogEntryType pEventType)
{
SetThreadContextAndLog(pEvent, () =>
{
if (pEventType == EventLogEntryType.Warning)
{
Log.Warn(pMessage);
}
});
}
这会导致源和事件ID被正确设置...
这有点像faff,但我无法在不创建自定义Appender的情况下看到更简洁的日志源设置方式...