Log4net EventLogAppender Log ID события - PullRequest
       1

Log4net EventLogAppender Log ID события

11 голосов
/ 18 февраля 2010

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

Ответы [ 5 ]

19 голосов
/ 18 февраля 2010

Исходя из того, что я вижу в исходном коде EventLogAppender, следует выполнить следующее:

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

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

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

6 голосов
/ 04 апреля 2014

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

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

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

а. Используя фильтрацию в log4net, можно зарегистрировать фильтр , который может добавить свойства 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;

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

5 голосов
/ 19 февраля 2010

Что ж, решением было построить проект расширения "log4net.Ext.EventID" и использовать его типы: IEventIDLog, EventIDLogImpl и EventIDLogManager.

2 голосов
/ 26 марта 2014

Другое решение - добавить пользовательский Фильтр , как описано здесь: Расширение регистрации исключений 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;
    }
}
0 голосов
/ 07 сентября 2017

Расширьте 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.");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...