【学习笔记】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添加信息如下:

试一下,你能看到更多的调试信息。

posted @ 2011-07-27 11:21  超时空饭盒  阅读(1436)  评论(0编辑  收藏  举报