Подтвердить что ты не робот

Идентификатор журнала LogLognet EventLogAppender

Есть ли способ зарегистрировать событие в журнале событий Windows с указанным событием для каждого сообщения? Я использую log4net v 1.2.10.

4b9b3361

Ответ 1

Ну, решение заключалось в создании проекта расширения "log4net.Ext.EventID" и использовании его типов: IEventIDLog, EventIDLogImpl и EventIDLogManager.

Ответ 2

Основываясь на том, что я вижу в исходном коде EventLogAppender, следует сделать следующее:

log4net.ThreadContext.Properties [ "EventID" ] = 5;

Просто вызовите это, прежде чем писать сообщения журнала (если вы не установите его для всех сообщений, вы должны снова удалить "EventID" из свойств.

N.B ключ свойства чувствителен к регистру.

Ответ 3

Когда вы используете собственные API журнала событий .net в System.Diagnostics, методы WriteEntry позволяют устанавливать идентификатор события и категорию. В этих API:

  • eventID - 32-битный int, но его значение должно быть от 0 до 65535
  • - это 16-битный int, но его значение должно быть положительным. Если источник событий включает файл ресурсов категории, средство просмотра событий будет используйте значение целочисленной категории для поиска локализованной "категории задач", строка. В противном случае отображается целочисленное значение. Категории должны нумеруться последовательно, начиная с номер 1

Log4net поддерживает запись EventID и категории, но это не прямо. Когда log4nets EventLogAppender регистрирует событие, он просматривает словарь свойств. Именованные свойства "EventID" и "Category" автоматически сопоставляются EventLogAppender с соответствующими значениями в журнале событий. Я видел несколько полезных способов использовать log4nets EventLogAppender и установить EventID и Category в журнале событий Windows.

а. Используя фильтрацию appender log4nets, можно зарегистрировать фильтр , который может добавить свойства EventID и Category. Этот метод имеет приятную выгоду, что стандартные обертки log4net используются и поэтому могут быть реализованы без изменения существующего кода ведения журнала. Трудность в этом методе заключается в создании некоторого механизма для вычисления EventID и Category из зарегистрированной информации. Например, фильтр может смотреть на источник исключения и отображать этот источник в значение категории.

б. Log4net может быть расширен, поэтому могут использоваться пользовательские обертки журналов, которые могут включать параметры EventID и Category. Добавление EventID показано в примере log4net "Расширяемость - EventIDLogApp", который включен в источник log4net. В примере расширения используется новый интерфейс (IEventIDLog), который расширяет стандартный интерфейс ILog, используемый приложениями для регистрации. Это обеспечивает новые методы ведения журнала, которые включают параметр eventId. Новые методы ведения журнала добавляют eventId в словарь свойств перед записью события.

public void Info(int eventId, object message, System.Exception t)
{
       if (this.IsInfoEnabled)
       {
             LoggingEvent loggingEvent = new LoggingEvent(ThisDeclaringType, Logger.Repository, Logger.Name, Level.Info, message, t);
             loggingEvent.Properties["EventID"] = eventId;
             Logger.Log(loggingEvent);
       }
}

с. Log4net поддерживает объект ThreadContext, содержащий словарь свойств. Приложение может устанавливать свойства EventID и Category в этом словаре, а затем, когда поток вызывает метод ведения журнала, значения будут использоваться EventLogAppender.

log4net.ThreadContext.Properties["EventID"] = 5;

Некоторые полезные ссылки:

Ответ 4

Другим решением является добавление пользовательского Filter, как описано здесь: Улучшение ведения журнала журналов log4net (прямая ссылка на Gist на всякий случай).

Как указывает автор:

... EventLogAppender использует встроенные константы для проверки. После их добавления они будут использоваться указанным EventLogAppender, чтобы пометить данные с помощью EventId и Category.

Реализация фильтра будет выглядеть так, как показано ниже (разделите вниз) с добавленной выгодой, если вы сделаете общедоступным метод GetEventId, вы можете написать несколько тестов против него

public class ExceptionBasedLogEnhancer : FilterSkeleton
{
    private const string EventLogKeyEventId = "EventID";

    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
        var ex = loggingEvent.ExceptionObject;
        if (ex != null)
        {
            loggingEvent.Properties[EventLogKeyEventId] = GetEventId(ex);
        }

        return FilterDecision.Neutral;
    }

    private static short GetEventId(Exception ex)
    {
        // more fancy implementation, like getting hash of ex properties 
        // can be provided, or mapping types of exceptions to eventids
        // return no more than short.MaxValue, otherwise the EventLog will throw
        return 0;
    }
}

Ответ 5

Расширьте ILog.Info(), чтобы принять идентификатор события:

public static class LogUtils
{
    public static void Info(this ILog logger, int eventId, object message)
    {
        log4net.ThreadContext.Properties["EventID"] = eventId;
        logger.Info(message);
        log4net.ThreadContext.Properties["EventID"] = 0; // back to default
    }
}

Затем назовите его следующим образом:

using LogUtils;
private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

_logger.Info(3, "First shalt thou take out the Holy Pin, then shalt thou count to three.");