WebAPI学习(十):Log4net记录全局日志

  1. 在TEST.Common中NuGet安装log4net

    3

  2. 在TEST.Common下新建 Helper 文件夹内,新建 ILoggerHelper.cs
    /// <summary>
    /// 日志接口
    /// </summary>
    public interface ILoggerHelper
    {
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Debug(object source, string message);
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="ps">ps</param>
        void Debug(object source, string message, params object[] ps);
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Debug(Type source, string message);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Info(object source, object message);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Info(Type source, object message);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Warn(object source, object message);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Warn(Type source, object message);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Error(object source, object message);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Error(Type source, object message);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Fatal(object source, object message);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Fatal(Type source, object message);
    
        /* Log a message object and exception */
    
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Debug(object source, object message, Exception exception);
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Debug(Type source, object message, Exception exception);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Info(object source, object message, Exception exception);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Info(Type source, object message, Exception exception);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Warn(object source, object message, Exception exception);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Warn(Type source, object message, Exception exception);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Error(object source, object message, Exception exception);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Error(Type source, object message, Exception exception);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Fatal(object source, object message, Exception exception);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Fatal(Type source, object message, Exception exception);
    }
  3. 新增LogHelper.cs
    /// <summary>
    /// 日志帮助实现类
    /// </summary>
    public class LogHelper : ILoggerHelper
    {
        private readonly ConcurrentDictionary<Type,ILog> Loggers = new ConcurrentDictionary<Type, ILog> ();
    
        private static ILog logger;
    
        public LogHelper()
        {
            if(logger == null)
            {
                var repository = LogManager.CreateRepository("NETCoreRepository");
                XmlConfigurator.Configure(repository,new FileInfo("Log4net.config"));
                logger = LogManager.GetLogger(repository.Name, "Logger");
            }
        }
    
        /// <summary>
        /// 获取记录器
        /// </summary>
        /// <param name="source">soruce</param>
        /// <returns></returns>
        private ILog GetLogger(Type source)
        {
            if (Loggers.ContainsKey(source))
            {
                return Loggers[source];
            }
            else
            {
                Loggers.TryAdd(source, logger);
                return logger;
            }
        }
    
        /* Log a message object */
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Debug(object source, string message)
        {
            Debug(source.GetType(), message);
        }
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="ps">ps</param>
        public void Debug(object source, string message, params object[] ps)
        {
            Debug(source.GetType(), string.Format(message, ps));
        }
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Debug(Type source, string message)
        {
            logger = GetLogger(source);
            if (logger.IsDebugEnabled)
            {
                logger.Debug(message);
            }
        }
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Info(object source, object message)
        {
            Info(source.GetType(), message);
        }
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Info(Type source, object message)
        {
            logger = GetLogger(source);
            if (logger.IsInfoEnabled)
            {
                logger.Info(message);
            }
        }
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Warn(object source, object message)
        {
            Warn(source.GetType(), message);
        }
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Warn(Type source, object message)
        {
            logger = GetLogger(source);
            if (logger.IsWarnEnabled)
            {
                logger.Warn(message);
            }
        }
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Error(object source, object message)
        {
            Error(source.GetType(), message);
        }
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Error(Type source, object message)
        {
            logger = GetLogger(source);
            if (logger.IsErrorEnabled)
            {
                logger.Error(message);
            }
        }
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Fatal(object source, object message)
        {
            Fatal(source.GetType(), message);
        }
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        public void Fatal(Type source, object message)
        {
            logger = GetLogger(source);
            if (logger.IsFatalEnabled)
            {
                logger.Fatal(message);
            }
        }
        /* Log a message object and exception */
    
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Debug(object source, object message, Exception exception)
        {
            Debug(source.GetType(), message, exception);
        }
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Debug(Type source, object message, Exception exception)
        {
            GetLogger(source).Debug(message, exception);
        }
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Info(object source, object message, Exception exception)
        {
            Info(source.GetType(), message, exception);
        }
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Info(Type source, object message, Exception exception)
        {
            GetLogger(source).Info(message, exception);
        }
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Warn(object source, object message, Exception exception)
        {
            Warn(source.GetType(), message, exception);
        }
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Warn(Type source, object message, Exception exception)
        {
            GetLogger(source).Warn(message, exception);
        }
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Error(object source, object message, Exception exception)
        {
            Error(source.GetType(), message, exception);
        }
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Error(Type source, object message, Exception exception)
        {
            GetLogger(source).Error(message, exception);
        }
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Fatal(object source, object message, Exception exception)
        {
            Fatal(source.GetType(), message, exception);
        }
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        public void Fatal(Type source, object message, Exception exception)
        {
            GetLogger(source).Fatal(message, exception);
        }
    }
  4. 配置 log4net.config 文件,在 TEST.API 根目录下,添加 Log4net.config
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    	<configSections>
    		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    	</configSections>
    
    	<system.web>
    		<compilation debug="true" targetFramework="4.5.2" />
    		<httpRuntime targetFramework="4.5.2" />
    	</system.web>
    	<log4net>
    		<!--错误日志:::记录错误日志-->
    		<!--按日期分割日志文件 一天一个-->
    		<!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
    		<appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
    			<!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
    			<file value="log/error/error_" />
    			<!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
    			<appendToFile value="true"/>
    			<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
    			<rollingStyle value="Date"/>
    			<!--这是按日期产生文件夹-->
    			<datePattern value="yyyy-MM-dd'.log'"/>
    			<!--是否只写到一个文件中-->
    			<staticLogFileName value="false"/>
    			<!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
    			<param name="MaxSizeRollBackups" value="100"/>
    			<!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
    			<maximumFileSize value="50MB" />
    			<!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
    			<layout type="log4net.Layout.PatternLayout">
    				<!--每条日志末尾的文字说明-->
    				<!--输出格式 模板-->
    				<!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
            操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
            记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->
    
    				<!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
    				<!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
    				<conversionPattern value="%n==========
                                      %n【日志级别】%-5level
                                      %n【记录时间】%date
                                      %n【执行时间】[%r]毫秒
                                      %n【错误位置】%logger 属性[%property{NDC}]
                                      %n【错误描述】%message
                                      %n【错误详情】%newline"/>
    			</layout>
    			<filter type="log4net.Filter.LevelRangeFilter,log4net">
    				<levelMin value="ERROR" />
    				<levelMax value="FATAL" />
    			</filter>
    		</appender>
    
    		<!--DEBUG:::记录DEBUG日志-->
    		<!--按日期分割日志文件 一天一个-->
    		<!-- appender 定义日志输出方式   将日志以回滚文件的形式写到文件中。-->
    		<appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
    			<!--保存路径:下面路径项目启动的时候自动在C盘中创建log、logError文件-->
    			<file value="log/debug/debug_" />
    			<!-- 如果想在本项目中添加路径,那就直接去掉C:\\  只设置log\\LogError   项目启动中默认创建文件 -->
    			<appendToFile value="true"/>
    			<!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
    			<rollingStyle value="Date"/>
    			<!--这是按日期产生文件夹-->
    			<datePattern value="yyyy-MM-dd'.log'"/>
    			<!--是否只写到一个文件中-->
    			<staticLogFileName value="false"/>
    			<!--保留的log文件数量 超过此数量后 自动删除之前的   好像只有在 按Size分割时有效 设定值value="-1"为不限文件数-->
    			<param name="MaxSizeRollBackups" value="100"/>
    			<!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
    			<maximumFileSize value="50MB" />
    			<!-- layout 控制Appender的输出格式,也可以是xml  一个Appender只能是一个layout-->
    			<layout type="log4net.Layout.PatternLayout">
    				<!--每条日志末尾的文字说明-->
    				<!--输出格式 模板-->
    				<!-- <param name="ConversionPattern"  value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger   
            操作者ID:%property{Operator} 操作类型:%property{Action}%n  当前机器名:%property%n当前机器名及登录用户:%username %n  
            记录位置:%location%n 消息描述:%property{Message}%n   异常:%exception%n 消息:%message%newline%n%n" />-->
    
    				<!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
    				<!--<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n错误描述:%message%newline %n"/>-->
    				<conversionPattern value="%n==========
                                      %n【日志级别】%-2level
                                      %n【记录时间】%date
                                      %n【执行时间】[%r]毫秒
                                      %n【debug位置】%logger 属性[%property{NDC}]
                                      %n【debug描述】%message"/>
    			</layout>
    			<filter type="log4net.Filter.LevelRangeFilter,log4net">
    				<levelMin value="DEBUG" />
    				<levelMax value="WARN" />
    			</filter>
    		</appender>
    		<!--Set root logger level to DEBUG and its only appender to A1-->
    		<root>
    			<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
    			<level value="ALL" />
    			<appender-ref ref="DebugAppender" />
    			<appender-ref ref="ErrorAppender" />
    		</root>
    	</log4net>
    </configuration>

     

  5. 在program.cs中注入日志服务
    //log日志注入
    builder.Services.AddSingleton<ILoggerHelper, LogHelper>();
  6. TEST.Common新建Filter 文件夹,添加 GlobalExceptionFilter.cs
    public class GlobalExceptionFilter :IExceptionFilter
    {
        private readonly IWebHostEnvironment _env;
        private readonly ILoggerHelper _loggerHelper;
    
        public GlobalExceptionFilter(IWebHostEnvironment env,ILoggerHelper loggerHelper)
        {
            _env = env;
            _loggerHelper = loggerHelper;
        }
    
        public void OnException(ExceptionContext context) 
        {
            var json = new JsonErrorResponse();
            json.Message = context.Exception.Message;
    
            if(_env.IsDevelopment())
            {
                json.DevelopmentMessage = context.Exception.StackTrace;
            }
    
            context.Result = new InternalServerErrorObjectResult(json);
    
            _loggerHelper.Error(json.Message, WriteLog(json.Message, context.Exception));
    
        }
    
        public string WriteLog(string throwMsg,Exception ex) 
        {
            return string.Format("【自定义错误】:{0} \r\n【异常类型】:{1} \r\n【异常信息】:{2} \r\n【堆栈调用】:{3}", new object[] { throwMsg,
                ex.GetType().Name, ex.Message, ex.StackTrace });
        }
    
    
    }
    
    public class InternalServerErrorObjectResult : ObjectResult
    {
        public InternalServerErrorObjectResult(object value) : base(value)
        {
    
            StatusCode = StatusCode.GetValueOrDefault();
        }
    }
    
    public class JsonErrorResponse
    {
        /// <summary>
        /// 生产环境消息
        /// </summary>
        public string Message { get; set; }
    
        /// <summary>
        /// 开发环境消息
        /// </summary>
        public string DevelopmentMessage { get; set; }
    }
  7. 在program.cs中注入全局异常捕获:
    builder.Services.AddControllers(options =>
    {
        options.SuppressAsyncSuffixInActionNames = true;
        options.Filters.Add(typeof(GlobalExceptionFilter));
    });
  8. 运行项目测试

    4

    5

     

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容