Log4Net: как добавить простой индексатор (номер строки) в каждую строку журнала - PullRequest
3 голосов
/ 04 октября 2010

Вот проблема: Я хочу добавить индексатор строк (номер строки или итератор) для каждой строки в файле журнала. Мне не нужно, чтобы он был уникальным для всего файла журнала, а только для «сеанса приложения» (т. Е. Каждый раз при запуске приложения Win32 мы начинаем обратный отсчет: 1, 2, 3 и т. Д.)

Есть ли где-нибудь встроенный способ (синтаксис тега translationpattern) или какое-то пользовательское расширение?

Большое спасибо!

Ответы [ 2 ]

10 голосов
/ 04 октября 2010

Мое решение работает только для одного аппендера, и счетчик будет сбрасываться при каждом запуске приложения.

Вы можете использовать конвертер шаблонов:

public sealed class LineCounterPatternConverter : PatternLayoutConverter
{       
    private static int _counter = 0;

    protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        var counter = System.Threading.Interlocked.Increment(ref _counter);
        writer.Write(counter.ToString());
    }
}

, затем вы настраиваете еговот так:

<layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="[%LC] %message%newline" />
  <converter>
    <name value="LC" />
    <type value="YourNameSpace.LineCounterPatternConverter" />
  </converter>
</layout>

Скобки [], конечно, необязательны.Вы также можете сделать что-то вроде этого %6LC, которое бы заполняло строку пробелами, чтобы вы хорошо выровняли сообщение.

1 голос
/ 04 октября 2010

я бы сделал следующее:

Сначала определите помощника по ведению журнала

public class WebLoggingHelper
{
    public static CurrentLineHelper CurrentLine = new CurrentLineHelper();

    public class CurrentLineHelper
    {
        private long _counter = 0;

        public override string ToString()
        {
            long counter = System.Threading.Interlocked.Increment(ref _counter);
            return counter.ToString();
        }
    }
}

Затем подключите помощника по протоколированию к свойствам log4net в том месте, где вы инициализируете свой регистратор

public void ConfigureLog4Net()
{
    XmlConfigurator.Configure();
    GlobalContext.Properties["CurrentLine"] = WebLoggingHelper.CurrentLine;
}

Прибыль! или, что более серьезно, теперь вы можете использовать свойство непосредственно в формате log4net, используя %property{CurrentLine}

<conversionPattern value="%property{CurrentLine}- %date - %identity - %property{current_request_id} - %m%n"/>

Я использую этот метод для регистрации большого количества материала, который необходимо рассчитать и определить для конкретного приложения. Возможно, вы захотите добавить некоторую логику для использования длинного числа для очень длинных периодов, а также некоторое форматирование для нумерации строк (например, заполнение нулями слева и т. Д.) ...

Хорошее ведение журнала!


EDIT: Решение, которое я здесь представляю, должно использоваться только для одного файла журнала одновременно. Если вы используете этот шаблон во многих файлах журнала, у вас будет уникальный номер строки в каждом , если вы добавите защиту от условий гонки (просто добавьте synclock в метод tostring объекта-помощника) Для управления несколькими регистраторами с номером строки следует использовать другой метод

EDIT # 2: Обновлен, чтобы быть потокобезопасным, также обновлен, чтобы поделиться именами идентификаторов с принятым ответом для удобства читателей (легче переваривать и сравнивать.)

...