zoukankan      html  css  js  c++  java
  • 蜗牛历险记(二) Web框架(中)

        上篇简单介绍了框架所使用的Autofac,采用Autofac提供的Ioc管理整个Web项目中所有对象的生命周期,实现框架面向接口编程。接下来介绍框架的日志系统。


    一、介绍之前

        框架日志是否有存在的必要性?假如你认为你的框架永远不会出现Bug,或者你能根据错误提示就能还原现场,重现这个问题,那你不需要日志。目前看来这样的项目不存在(Helloworld之类除外)。因此日志框架还是很必要的。

        日志框架用于记录:系统运行过程中错误详情;用于记录系统使用过程中产生的意外情况;用于记录系统一些状态信息等等。通过不同分类,不同严重级别的日志信息可以很方便地为我们解决问题、为提高系统能效提供等提供数据支持。

        目前.Net方向上成熟的日志框架有Log4net、NLog等,这两个框架各有优劣,具体如何选择要根据个人熟悉程度,以及使用环境来判断。

    二、初始化

        或许会因为各种原因,我们会在系统投入使用后,替换原有的日志框架。因此,在系统设计之初,我们就应该注意不要让框架本身与日志框架有太大的依赖。所以,我们定义日志的级别和日志的标准接口:

        1.日志等级

     /// <summary>
        /// 日志等级
        /// </summary>
        public enum LogLevel {
            /// <summary>
            /// 调试
            /// </summary>
            Debug,
            /// <summary>
            /// 信息
            /// </summary>
            Information,
            /// <summary>
            /// 警告
            /// </summary>
            Warning,
            /// <summary>
            /// 错误
            /// </summary>
            Error,
            /// <summary>
            /// 严重错误
            /// </summary>
            Fatal
        }

        2.日志基础接口:

        /// <summary>
        /// 日志接口
        /// </summary>
        public interface ILogger {
            /// <summary>
            /// 判断日志等级是否开启
            /// </summary>
            /// <param name="level">日志等级</param>
            /// <returns>若开启则返回true,否则返回false</returns>
            bool IsEnabled(LogLevel level);
    
            /// <summary>
            /// 记录日志
            /// </summary>
            /// <param name="level">日志等级</param>
            /// <param name="exception">异常信息</param>
            /// <param name="format">日志格式</param>
            /// <param name="args">日志格式的格式化参数</param>
            void Log(LogLevel level, Exception exception, string format, params object[] args);
        }

        3.日志扩展方法:

      public static class LoggingExtensions {
            /// <summary>
            /// 记录调试日志
            /// </summary>
            /// <param name="logger">日志对象</param>
            /// <param name="message">消息</param>
            public static void Debug(this ILogger logger, string message) {
                FilteredLog(logger, LogLevel.Debug, null, message, null);
            }
    
            /// <summary>
            /// 记录信息日志
            /// </summary>
            /// <param name="logger">日志对象</param>
            /// <param name="message">消息</param>
            public static void Information(this ILogger logger, string message) {
                FilteredLog(logger, LogLevel.Information, null, message, null);
            }
    
            /// <summary>
            /// 记录警告日志
            /// </summary>
            /// <param name="logger">日志对象</param>
            /// <param name="message">消息</param>
            public static void Warning(this ILogger logger, string message) {
                FilteredLog(logger, LogLevel.Warning, null, message, null);
            }
    
            /// <summary>
            /// 记录错误日志
            /// </summary>
            /// <param name="logger">日志对象</param>
            /// <param name="message">消息</param>
            public static void Error(this ILogger logger, string message) {
                FilteredLog(logger, LogLevel.Error, null, message, null);
            }
    
            /// <summary>
            /// 记录严重错误日志
            /// </summary>
            /// <param name="logger">日志对象</param>
            /// <param name="message">消息</param>
            public static void Fatal(this ILogger logger, string message) {
                FilteredLog(logger, LogLevel.Fatal, null, message, null);
            }
    
            public static void Debug(this ILogger logger, Exception exception, string message) {
                FilteredLog(logger, LogLevel.Debug, exception, message, null);
            }
            public static void Information(this ILogger logger, Exception exception, string message) {
                FilteredLog(logger, LogLevel.Information, exception, message, null);
            }
            public static void Warning(this ILogger logger, Exception exception, string message) {
                FilteredLog(logger, LogLevel.Warning, exception, message, null);
            }
            public static void Error(this ILogger logger, Exception exception, string message) {
                FilteredLog(logger, LogLevel.Error, exception, message, null);
            }
            public static void Fatal(this ILogger logger, Exception exception, string message) {
                FilteredLog(logger, LogLevel.Fatal, exception, message, null);
            }
    
            public static void Debug(this ILogger logger, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Debug, null, format, args);
            }
            public static void Information(this ILogger logger, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Information, null, format, args);
            }
            public static void Warning(this ILogger logger, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Warning, null, format, args);
            }
            public static void Error(this ILogger logger, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Error, null, format, args);
            }
            public static void Fatal(this ILogger logger, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Fatal, null, format, args);
            }
    
            public static void Debug(this ILogger logger, Exception exception, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Debug, exception, format, args);
            }
            public static void Information(this ILogger logger, Exception exception, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Information, exception, format, args);
            }
            public static void Warning(this ILogger logger, Exception exception, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Warning, exception, format, args);
            }
            public static void Error(this ILogger logger, Exception exception, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Error, exception, format, args);
            }
            public static void Fatal(this ILogger logger, Exception exception, string format, params object[] args) {
                FilteredLog(logger, LogLevel.Fatal, exception, format, args);
            }
    
            private static void FilteredLog(ILogger logger, LogLevel level, Exception exception, string format, object[] objects) {
                if (logger.IsEnabled(level)) {
                    logger.Log(level, exception, format, objects);
                }
            }
        }

        我们可以自己实现基于Log4net的实现Log4NetLogger,基于NLog的实现NLogLogger,均继承ILogger接口,并实现Log方法,由于类似文章众多,本篇不赘述。

    三、与Ioc结合的优劣

        设置日志框架为全局单例,这样可以减少每次都CreateLogger,提高效率。但有时我们又需要在框架初始化之前就需要日志记录。比如蜗牛历险记(二) Web框架(上)简述部分的PreApplicationStartMethod,我们需要在框架初始化之前做插件的拷贝初始化工作,这里记录日志,方便我们分析解决框架启动失败等问题。因此我们有必要提供独立于框架之外的日志系统,同时也需要提供为框架使用的IOC环境内的日志系统。我们可以再加一个LoggerFactory,用工厂根据不同条件提供具体的日志实现方式。

    四、日志的使用

        一个健康的日志应该包含:发生时间、日志级别、日志类别、日志堆栈,日志内容。

    public class HomeController:Controller{
        
        public ILogger Logger{get;set;}//日志采用属性注入
        private readonly IService _service;    
        public HomeController(IService service){
            _service=service;
        }
        
        public ActionResult Index(){
            var val=_service.DoSomeBusiness();
            Logger.Information(null,"记录日志,开始业务。结果是:"+val);//
            return View(val);
        }
    }

    五、总结

        日志框架是必不可少的,如何规范日志记录,方便查询排查,也需要在框架之外做更多工作。

  • 相关阅读:
    Sample XPS Documents Download
    触发器中的inserted表和deleted表
    Using freewheel.labs.autodesk.com to auto generate preview images of DWF files on your web site
    解除SQL对组件"Ad Hoc Distributed Queries"的"STATEMENT'OpenRowset OpenDatasource"的访问
    读写xps
    XPS文件,在Windows XP下的打开查看阅读和打印方法。
    Learning to Reference Inserted and Deleted Tables
    Get value from updated, inserted and deleted
    Reinstall Microsoft Helper Viewer
    如何查找文件的IFilter
  • 原文地址:https://www.cnblogs.com/leafly/p/5137675.html
Copyright © 2011-2022 走看看