Log4Net:如何将程序内的日志记录结果输出到一个变量中

本文关键字:输出 变量 一个 结果 记录 程序 日志 Log4Net | 更新日期: 2023-09-27 18:05:30

我正在尝试学习使用Log4Net以便能够在我的程序中改进我的日志记录技术。我已经阅读了Log4Net网站上提供的文件,但是我有这些问题。

这是BasicConfigurator.Configure()制作的Log4Net网站上的示例程序中最简单的输出。

0    [main] INFO  MyApp        - Entering application.
36   [main] DEBUG Com.Foo.Bar  - Did it again!
51   [main] INFO  MyApp        - Exiting application.

我的程序已经有一个窗格(在调试模式下)来显示通过许多异步尝试循环的程序流。因此,当我运行它时,我可以看到程序的流程(典型的大规模调试方法)。

在这个级别,据我所知,通过使用Log4Net,我可以收集日志在那些时刻,这些日志可以附加到许多不同的输出方法,如控制台外部文件,db等。这导致双重up 在代码中。在每个测试点中,一行用于向UI输出日志,另一行用于为Log4Net记录日志。

是否有任何方法可以将其中一个追加器的内容输出到字符串或类似类型的变量中,以便能够在运行时显示它?

我不确定如何在WPF应用程序中看到控制台的输出。将Log4Net输出到一个文件中,然后将它的竞赛输出回一个字符串,这似乎很有趣。


更新当Show output from:下拉框设置为"Debug"时,在Visual Studio output 窗口中可以看到Console Appender的输出。非常感谢@Aron指出这一点。

Log4Net:如何将程序内的日志记录结果输出到一个变量中

Log4net带有UDPAppender,这是一种将日志内容传输到网络上任何侦听器的低调方式。我建议使用它作为将日志推送到UI的方法。

<appender name="UdpAppender" type="log4net.Appender.UdpAppender">
  <remoteAddress value="127.0.0.1" /> <!-- local for the demo on my machine --> 
  <remotePort value="10000" />
  <layout type="log4net.Layout.PatternLayout" value="%-5level %logger [%ndc] - %message%newline" />
</appender>

在UI中,将WPF应用程序的后台线程中的监听器与这些消息挂钩,使您可以按照您喜欢的方式显示它们,例如作为x最新日志的滑动窗口,或者将所有日志推送到您在问题中提到的窗格中。

// launch this in a background thread
private static void UDPListen()
{
    IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
    var udpClient = new UdpClient(10000);
    while (true)
    {
        var buffer = udpClient.Receive(ref remoteEndPoint);
        var loggingEvent = System.Text.Encoding.Unicode.GetString(buffer);
        // write the log to your pane
    }
}

有趣的是,这是log4net的许多"仪表板"用来监控应用程序的一种方法,所以如果你愿意,你可以在应用程序的发布版本中删除窗格,然后从网络上的另一台机器上查看你的应用程序。


EDIT:在任何应用程序中写入到程序的标准输出流,您可以将其管道传输到其他进程;例如,启动使用以下语法写入控制台的WPF应用程序将把消息记录到log.txt文件

myApp.exe > log.txt
作为一个更有用的例子,Visual studio将你所附加的程序的stdout管道到它的输出窗口中,所以任何发送到ConsoleAppender的东西都会出现在输出窗口中。

因此,如果您重用程序的默认输出,控制台附加程序可能很有用,但没有什么强制您使用它。

也许有点偏离主题,但我发现这个主题时,试图找到一种方法来写日志文件和消息栏在应用程序。我设法找到一个更优雅的解决方案。

所以,我们在2020年,有。net Core和Microsoft.Extensions.Logging及其通用记录器工厂和接口:

        var messageBar = new MessageBar();
        using var loggerFactory = LoggerFactory.Create(builder => builder
            .AddLog4Net()
            .AddProvider(new MessageBarLoggerProvider(messageBar))
            .SetMinimumLevel(LogLevel.Debug));
        ILogger programLogger = loggerFactory.CreateLogger(nameof(App));
        programLogger.LogDebug("hello world!");

"hello world!"文本出现在log4net中配置。配置日志文件和消息栏。实现ILoggerProviderILogger并不难,概念如下:

internal sealed class MessageBarLoggerProvider : ILoggerProvider
{
    private readonly MessageBar _messageBar;
    public MessageBarLoggerProvider(MessageBar messageBar) => _messageBar = messageBar;
    public ILogger CreateLogger(string categoryName) => new MessageBarLogger(_messageBar);
    public void Dispose() { }
}

internal class MessageBarLogger : ILogger
{
    private readonly MessageBar _messageBar;
    public MessageBarLogger(MessageBar messageBar) => _messageBar = messageBar;
    public IDisposable BeginScope<TState>(TState state) => throw new NotImplementedException();
    public bool IsEnabled(LogLevel logLevel) => true;
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
        Func<TState, Exception, string> formatter)
    {
        _messageBar.MessagesList.Add(new Message(formatter(state, exception)));
    }
}