Как протоколировать сообщения Trace с log4net?

Я использую 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>

Ответ 1

В соответствии с предложением 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);
        }
    }
}

Ответ 2

Я не знаю, поддерживает ли log4net это, но вы можете реализовать свой собственный прослушиватель трассировки, который сделал это.

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

Чтобы добавить пользовательский прослушиватель трассировки, вы либо измените свой файл app.config/web.config, либо добавите его в код с помощью Trace.Listeners.Add(new Log4NetTraceListener());

Ответ 3

В соответствии с вышеприведенными ответами здесь реализована реализация (эта ссылка нечеткая, но я нашел исходный код):

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 все равно создаст проблемы, описанные в комментариях выше.

Ответ 4

Спасибо,

Я пошел с Дирком, ответ немного похудел.

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);
}