Як реєструвати повідомлення про трасування за допомогою log4net?


75

Я використовую log4net для реєстрації запису журналу повідомлення у рухомий файл журналу.

Тепер я б також перенаправив усі повідомлення трасування з System.Diagnostics.Traceцього журналу. Як я можу це налаштувати? Я намагався знайти щось про це в документації log4net, але безуспішно. Чи можливо це взагалі?

Причиною того, що я хочу це зробити, є те, що я зацікавлений у повідомленнях Trace сторонньої бібліотеки.

<log4net>
    <appender name="R1" type="log4net.Appender.RollingFileAppender">
      <file value="C:\Logs\MyService.log" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <maxSizeRollBackups value="10" />
      <datePattern value="yyyyMMdd" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>
</log4net>

Відповіді:


73

Згідно з пропозицією Rune, я реалізував базовий TraceListener, який виводить у log4net:

public class Log4netTraceListener : System.Diagnostics.TraceListener
{
    private readonly log4net.ILog _log;

    public Log4netTraceListener()
    {
        _log = log4net.LogManager.GetLogger("System.Diagnostics.Redirection");
    }

    public Log4netTraceListener(log4net.ILog log)
    {
        _log = log;
    }

    public override void Write(string message)
    {
        if (_log != null)
        {
            _log.Debug(message);
        }
    }

    public override void WriteLine(string message)
    {
        if (_log != null)
        {
            _log.Debug(message);
        }
    }
}

14
+1 для відповіді вище. Я був би обережний, якщо log4net також налаштований на запис у TraceAppender. Я насправді не тестував цього, але ви можете потрапити в ситуацію, коли Trace пише в log4net, а log4net пише в Trace, що призводить до нескінченного циклу. Наприклад, враховуючи приклад вище, ви можете пом'якшити це, не включаючи TraceAppender у додатки для реєстратора 'System.Diagnostics.Redirection'.
Jimit

1
Оскільки це прослуховувач трасування, вам слід реалізувати блоки try / catch у методах Write, щоб гарантувати, що спроба запису ніколи не зазнає помилки на хості. Я надіслав редагування коду, які виправляють конструкцію об’єкта та роблять код більш читабельним і менш імовірним невдалим результатом.
Шон Вільсон

@JYL Ось оновлене посилання на цю публікацію в блозі . Однак схоже, що деякі речі, можливо, загубилися під час руху. Код XML у цій публікації тепер неправильний, і посилання на Log4netTraceListener не працює. Сподіваємось, автор воскресить код.
Джон-Ерік,

3
Чи є вбудований слухач у log4net, який може прослуховувати подію трасування?
Manjay_TBAG

4
Погляньте на джерело класу log4net.Util.LogLog. Це входить у Trace за замовчуванням, і @Jimit в основному має рацію - ви потрапите в глухий кут, якщо трапиться помилка додатка. У вашій реалізації TraceListener я б обов’язково встановив log4net.Util.LogLog.EmitInternalMessages = false у конструкторі вашої реалізації, і, можливо, обробляв подію LogLog.LogReceived і реєстрував ці повідомлення іншим способом. Сумна частина цього полягає в тому, що деякі помилки додатків не реєструються через це налаштування. Джерело - ваш друг тут.
Стівен Боун

26

Я не знаю, чи підтримує log4net це, але ви можете реалізувати власний прослуховувач трасування, який це зробив.

У TraceListener не надто багато методів, які потрібно реалізувати, і все, що вам потрібно зробити, це переслати значення в log4net, тому це має бути легко зробити.

Щоб додати власний прослуховувач трасування, ви або зміните свій app.config / web.config, або додасте його в код за допомогою Trace.Listeners.Add(new Log4NetTraceListener());


1

Відповідно до наведених вище відповідей, тут є реалізація (це посилання нестійке, але я знайшов вихідний код):

https://code.google.com/archive/p/cavity/

Щоб грубо розібратися з проблемою (описаною в коментарях до попередньої відповіді) внутрішнього виведення трасування log4net з класу LogLog, я перевірив, чи є цей клас джерелом трасування, перевіривши фрейм стека (що ця реалізація вже робила) і ігноруючи ці повідомлення трасування:

    public override void WriteLine(object o, string category)
    {
        // hack to prevent log4nets own diagnostic trace getting fed back
        var method = GetTracingStackFrame(new StackTrace()).GetMethod();
        var declaringType = method.DeclaringType;
        if (declaringType == typeof(LogLog))
        {
            return;
        }
        /* rest of method writes to log4net */
    }

Використання TraceAppender все одно створить проблеми, описані у коментарях вище.


1

Дякую,

Я відповів, що відповідь Дірка трохи схудла.

public class Log4netTraceListener : System.Diagnostics.TraceListener
{
    private readonly log4net.ILog _log;

    public Log4netTraceListener()
        : this(log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType))
    {

    }

    public Log4netTraceListener(log4net.ILog log)
    {
        _log = log;
    }

    public override void Write(string message) => _log?.Debug(message);

    public override void WriteLine(string message) => _log?.Debug(message);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.