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);
        }
    }

    五、总结

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

  • 相关阅读:
    nginx第三方模块---nginx-sticky-module的使用(基于cookie的会话保持)
    通过redis的monitor命令排除故障
    redis数据过期策略【转】
    PHP通用分页类page.php[仿google分页]
    简洁php的MVC框架
    Jquery插件开发之图片放大镜效果(仿淘宝)
    PHPCMS V9标签循环嵌套调用数据的方法
    虚拟主机服务器php fsockopen函数被禁用的解决方法
    PHPCMS V9 fsockopen 函数被禁用解决方案
    PHP IN_ARRAY 函数 使用需要注意的地方
  • 原文地址:https://www.cnblogs.com/leafly/p/5137675.html
Copyright © 2011-2022 走看看