我正在尝试使用 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,我可以在那些时刻收集日志,这些日志可以附加到许多不同的输出方法中,例如 console ,外部文件,db 等这会导致代码中出现双倍。在每个测试点中,一行将日志输出到UI,另一行记录Log4Net。
是否有任何方法可以将其中一个appender(如上所示)的内容输出到类型字符串或类似的变量中,以便能够在运行时显示它?
我不知道如何在WPF应用程序中看到控制台的输出。将 Log4Net 输出到文件中然后将其竞赛打印回字符串似乎很有趣。
显示输出时, Visual Studio 的 输出 窗口中可以看到Console Appender
的输出:下拉菜单设置为" Debug"。非常感谢@Aron指出它。
答案 0 :(得分:4)
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
}
}
有趣的是,这是一种方法很多&#34;仪表板&#34; for log4net用于监视应用程序,因此如果需要,可以删除应用程序的发布版本中的窗格,并从网络上的另一台计算机上查看您的应用程序。
编辑:在程序的任何应用程序writes to the standard output stream中写入控制台,您可以将其导入其他进程;例如,使用以下语法启动写入控制台的wpf应用程序会将消息记录到log.txt文件
myApp.exe > log.txt
(以下示例对@Aron的称赞)作为一个更有用的示例,Visual Studio将您附加的程序的stdout传递到其Output窗口,因此发送到ConsoleAppender的任何内容都将出现在Output窗口中。
因此,如果重用程序的默认输出,控制台appender会很有用,但没有任何东西强迫你使用它。
答案 1 :(得分:0)
也许有点偏离主题,但是当我试图找到一种将日志既写入文件又写入应用程序中的消息栏的方法时,我找到了这个主题。我设法找到了一个更优雅的解决方案。
所以,我们到了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!");
“你好,世界!”文本同时出现在log4net.config日志文件和消息栏中的配置文件中。实现ILoggerProvider
和ILogger
并不难,这是概念:
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)));
}
}