【学习笔记】Silverlight框架:Jounce(3)——日志记录
日志记录在各个框架里都是差不多的。Jounce里的这个部分也比较简单。涉及的类有三个:接口ILogger、基础实现DefaultLogger和消息等级枚举LogSeverity。
ILogger中定义了4个方法,3个是用来记录日志的,还有1个是SetSeverity(LogSeverity minimumLevel)。根据DefaultLogger中的实现来看,在其内部维护了一个消息等级的变量“_severityLevel”,可以通过SetSeverity方法来进行设置,其相当于一个阈值,控制当前的日志信息要不要输出(作者本意应该是如此吧,实际应用中可以更灵活的变通)。
DefaultLogger中日志默认只是通过Debug.WriteLine输出,因此很多情况下我们需要实现自己的ILogger。
实践下吧,在Prism里有个动态加载模块例子“Open Modularity With Mef”,里面实现了一个日志类,并最终输出日志信息到UI上显示,我们来做个类似的,看看Jounce在初始化的时候会输出哪些信息。
Jounce模板创建的解决方案是没有Web项目的,这次的例子的部分功能设置需要用到Web项目,所以就不用模板创建了。整个结构如下:
CallbackLogger的代码如下:
[Export]
[Export(typeof(ILogger))]
public class CallbackLogger : ILogger
{
private LogSeverity _severityLevel;
private readonly Queue<Tuple<LogSeverity, string, string>> savedLogs =
new Queue<Tuple<LogSeverity, string, string>>();
public Action<LogSeverity, string, string> Callback { get; set; }
public void Log(LogSeverity severity, string source, Exception exception)
{
if (!Debugger.IsAttached || (int)severity < (int)_severityLevel)
{
return;
}
var sb = new StringBuilder();
sb.Append(exception);
var ex = exception.InnerException;
while (ex != null)
{
sb.AppendFormat("{0}{1}", Environment.NewLine, ex);
ex = ex.InnerException;
}
this.Log(severity, source, sb.ToString());
}
public void Log(LogSeverity severity, string source, string message)
{
if (!Debugger.IsAttached || (int)severity < (int)_severityLevel)
{
return;
}
if (this.Callback != null)
{
this.Callback(severity, source, message);
}
else
{
this.savedLogs.Enqueue(new Tuple<LogSeverity, string, string>(severity, source, message));
}
}
public void LogFormat(LogSeverity severity, string source, string messageTemplate, params object[] arguments)
{
this.Log(severity, source, string.Format(messageTemplate, arguments));
}
public void SetSeverity(LogSeverity minimumLevel)
{
_severityLevel = minimumLevel;
}
public void ReplaySavedLogs()
{
if (this.Callback != null)
{
while (this.savedLogs.Count > 0)
{
var log = this.savedLogs.Dequeue();
this.Callback(log.Item1, log.Item2, log.Item3);
}
}
}
}
整个就是DefaultLogger和Prism里的那个CallbackLogger的复合体。
阈值_severityLevel控制信息要不要输出,Callback用于输出信息,savedLogs用于存储当Callback=null时的输出信息。
当给Callback赋值后就可以调用ReplaySavedLogs方法输出savedLogs中存储的信息了。
至于头上为什么要加2个[Export]标记,我想,你懂的。
MainPage的页面内容就是只有一个TextBox用于显示输出信息:
<Grid x:Name="LayoutRoot" Background="White">
<TextBox x:Name="TraceTextBox" Margin="10" TextWrapping="Wrap"/>
</Grid>
看一下MainPage.cs:
[ExportAsView(typeof(MainPage), IsShell = true)]
public partial class MainPage : UserControl, IPartImportsSatisfiedNotification
{
[Import]
public CallbackLogger Logger { get; set; }
public MainPage()
{
InitializeComponent();
}
public void Log(LogSeverity severity, string source, string message)
{
this.TraceTextBox.Text += string.Format(CultureInfo.CurrentUICulture, "[{0}][{1}] {2}\r\n", severity, source, message);
}
public void OnImportsSatisfied()
{
this.Logger.SetSeverity(LogSeverity.Verbose);
this.Logger.Callback = this.Log;
this.Logger.ReplaySavedLogs();
}
}
标记[ExportAsView]指定这是一个输出视图,并且是Shell,这样程序启动的时候就会把Application.Current.RootVisual设为MainPage了,具体以后再说。
程序启动的时候会去启动页里读取LogLevel参数,并调用Ilogger.SetSeverity方法,如果没有获取到参数,默认的Level是LogSeverity.Warning,比较高,而我们这次需要看一下所有的信息,所以在模块加载完的时候需要重新设一下this.Logger.SetSeverity(LogSeverity.Verbose)。
运行下看看:
再回头来看一下如何在启动页里配置LogLevel,打开LoggerTestPage.html,找到Host添加信息如下:
试一下,你能看到更多的调试信息。

半路和尚 by 超时空饭盒 is licensed under a Creative Commons 署名-非商业性使用-相同方式共享 3.0 Unported License.
基于halfwaymonk.cnblogs.com上的作品创作。


浙公网安备 33010602011771号