项目开发过程写过几个WPF的小工具,在使用过程中就需要把软件运行的情况以日志的形式输出到界面上,这里就把用过的几种方式总结一下。
输出到RichTextBox很简单直接了,代码如下:
///
/// 日志输出
///
///
public void WriteToLog(string message)
{
if (!(txtRich.CheckAccess()))
{
this.Dispatcher.Invoke(() =>
WriteToStatus(message)
);
return;
}
string strTime = "[" + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
txtRich.AppendText(strTime + message + "\r");
if (txtRich.ExtentHeight > 200)
{
txtRich.Document.Blocks.Clear();
}
}
其中txtRich就是界面UI上RichTextBox的名称,在需要输出日志的地方调用方法WriteToLog()即可。
上面的方法只能算是“伪日志”,毕竟只是将信息输出到UI控件上,正统的日志还是要靠NLog、log4net这样的日志组件。
打开项目的Nuget管理器,搜索NLog.Config并安装。
其实只安装NLog也是可以的。但是NLog.Config已经包含了NLog,而且有了NLog.Config编写配置文件更方便些。
NLog.Config安装成功后,项目跟目录下会增加NLog.config和NLog.xsd两个文件。修改NLog.config文件,对输出日志的格式、输出形式、跟踪级别进行配置。
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<variable name="myvar" value="myvalue"/>
<targets>
<!- 输出至文件 -->
<target name="info_file" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
<target name="error_file" xsi:type="File" fileName="${basedir}/logs/${shortdate}_error.log"
layout="${longdate} ${uppercase:${level}} ${message} ${exception:stacktrace}" />
targets>
<rules>
<logger name="*" minlevel="Info" writeTo="info_file" />
<logger name="*" minlevel="Error" writeTo="error_file" />
rules>
nlog>
在代码中定义日志管理器,直接调用。
//定义日志
private Logger logger = LogManager.GetCurrentClassLogger();
//调用日志
private void BtnLog_Click(object sender, RoutedEventArgs e)
{
logger.Info("开始输出日志!");
}
启动程序,在运行过程中产生的信息就会输出到指定目录的文件中。也可以通过修改配置文件,将日志输出到其他目标位置。
将上述两种方法结合起来,既可以在UI界面实时显示,也能在后台稳定输出。幸运的是可以使用NLog.wpf.RichTextBox这个库,虽然时间比较久远了,但是用起来还是很方便的。打开Nuget管理器,安装NLog.wpf.RichTextBox。安装完成后项目会增加WpfRichTextBoxTarget.cs、WpfRichTextBoxRowColoringRule.cs、WpfRichTextBoxWordColoringRule.cs三个文件,具体使用方法可以参考附带的txt文件。
在需要输出日志的地方修改代码如下:
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Dispatcher.Invoke(() =>
{
var target = new WpfRichTextBoxTarget
{
Name = "RichText",
Layout = "[${longdate:useUTC=false}] :: [${level:uppercase=true}] :: ${logger}:${callsite} :: ${message} ${exception:innerFormat=tostring:maxInnerExceptionLevel=10:separator=,:format=tostring}",
ControlName = "你的控件名称",
FormName = GetType().Name,
AutoScroll = true,
MaxLines = 1000,
UseDefaultRowColoringRules = true,
};
var asyncWrapper = new AsyncTargetWrapper { Name = "RichTextAsync", WrappedTarget = target };
LogManager.Configuration.AddTarget(asyncWrapper.Name, asyncWrapper);
LogManager.Configuration.LoggingRules.Insert(0, new LoggingRule("*", LogLevel.Info, asyncWrapper));
LogManager.ReconfigExistingLoggers();
});
}
同样是把日志输出到RichTextBox,结合了上两种方法,对于软件运行的监测和问题检查会有很大的帮助。