如何使用 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>
33913 次浏览

I don't know if log4net supports this, but you could implement your own trace listener that did this.

The TraceListener doesn't have too many method that needs to be implemented and all you would do is to forward the values to log4net so this should be easy to do.

To add a custom trace listener you would either modify your app.config/web.config or you would add it in code using Trace.Listeners.Add(new Log4NetTraceListener());

According to Rune's suggestion I implemented a basic TraceListener which output to 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);
}
}
}

As per the answers above, there's an implementation here (this link is flaky, but I did find the source code):

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

To crudely deal with the issue (described in the comments to a previous answer) of internal log4net trace issuing from the LogLog class, I checked for this class being the source of the trace by inspecting the stack frame (which this implementation did already) and ignoring those trace messages:

    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 */
}

Using a TraceAppender will still create the problems described in the comments above.

Thanks,

I went with Dirk's answer slimmed down a bit.

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