版权声明:本文为博主原创文章,未经博主允许不得转载。转载请标明文章出处和原文链接。欢迎加QQ群交流:191695206 https://blog.csdn.net/wangzl1163/article/details/83184537
一、前言
log4net是一个比较知名的日志提供程序,.NET Core发布1.0的时候log4net已经给予支持;不过,.NET Core官方推荐的日志提供程序中却没有log4net,不知道内在原因是啥。用.NET Core 写了一个小工具,在这个小工具中使用了log4net来进行日志记录。文章主要记录.NET Core中如何整合log4net以及全局异常捕获的实现。
二、准备
在使用log4net之前先安装log4net。这里操作很简单,通过nuget下载并安装log4net很方便。如下图。
三、实现
a、log4net配置
新建一个配置文件并命名为log4net.config用来保存log4net的配置。配置好的log4net配置如下。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<log4net>
<!--定义输出到一个固定文件中-->
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log/log.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<!--每条日志末尾的文字说明-->
<header value=" [============================应用程序日志开始============================ ] " />
<footer value=" [ ===========================应用程序日志结束=============================] " />
<!--输出格式-->
<!--样例:2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info-->
<conversionPattern value="%newline%newline记录时间:%date 线程ID:[%thread] 日志级别:%-5level 类名或程序集名:%logger %newline property:[%property{NDC}] - 描述:%message%newline" />
</layout>
</appender>
<!--定义输出到文件中,循环创建日志文件,以日期命名-->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<!--定义文件存放位置 保存当前日期的日志,当第二天新日志产生时会把当前日期的日志保存备份-->
<file value="log/log" />
<!--禁止覆盖原有文件,true:覆盖原有文件-->
<appendToFile value="false" />
<rollingStyle value="Date" />
<!--以天为单位进行日志滚动,保存过去日期的日志-->
<datePattern value="yyyy-MM-dd-HHmm".txt"" />
<layout type="log4net.Layout.PatternLayout">
<!--每条日志末尾的文字说明-->
<header value=" [============================应用程序日志开始============================ ] " />
<footer value=" [ ===========================应用程序日志结束=============================] " />
<!--输出格式-->
<!--样例:2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info-->
<conversionPattern value="%newline%newline记录时间:%date 线程ID:[%thread] 日志级别:%-5level 类名或程序集名:%logger %newline property:[%property{NDC}] - 描述:%message%newline" />
</layout>
</appender>
<!--定义输出到控制台命令行中-->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!--输出格式-->
<conversionPattern value="%newline时间:%date 线程ID:[%thread] 日志级别:%-5level 类名或程序集名:%logger %newline property:[%property{NDC}] - 描述:%message%newline" />
</layout>
</appender>
<!--定义以不同颜色输出到控制台-->
<appender name="ManagedColoredConsoleAppender" type="log4net.Appender.ManagedColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<foreColor value="DarkRed" />
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="Yellow" />
</mapping>
<mapping>
<level value="INFO" />
<foreColor value="DarkGray" />
</mapping>
<mapping>
<level value="DEBUG" />
<foreColor value="DarkGreen" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<!--输出格式-->
<conversionPattern value="%newline时间:%date 线程ID:[%thread] 日志级别:%-5level 类名或程序集名:%logger %newline property:[%property{NDC}] - 描述:%message%newline" />
</layout>
</appender>
<!--定义输出到数据库中,这里举例输出到Access数据库中,数据库为log4net.mdb(可以自定义路径)-->
<appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender">
<connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=logDB/log4net.mdb" />
<commandText value="INSERT INTO LogDetails ([LogDate],[Thread],[Level],[Logger],[Message]) VALUES (@logDate, @thread, @logLevel, @logger,@message)" />
<!--定义各个参数-->
<parameter>
<parameterName value="@logDate" />
<dbType value="String" />
<size value="240" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date" />
</layout>
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="240" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@logLevel" />
<dbType value="String" />
<size value="240" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="240" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="240" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
</appender>
<!--定义日志的输出媒介,下面定义日志以四种方式输出。也可以下面的按照一种类型或其他类型输出。-->
<root>
<!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF
比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录
如果没有定义LEVEL的值,则缺省为DEBUG-->
<level value="ALL"/>
<!--文件形式记录日志-->
<appender-ref ref="RollingFileAppender" />
<!--控制台控制显示日志-->
<!--<appender-ref ref="ConsoleAppender" />-->
<!--控制台以不同颜色显示日志-->
<appender-ref ref="ManagedColoredConsoleAppender" />
<!--定义输出到数据库中。 如果不启用相应的日志记录,可以通过这种方式注释掉-->
<!--<appender-ref ref="AdoNetAppender_Access" />-->
</root>
</log4net>
</configuration>
b、日志帮助类——Logger
把log4net加载以及常用方法封装在日志帮助类——Logger中。代码如下。
using System;
using log4net;
using log4net.Repository;
namespace wxApp.Code.Creater.Api.Common
{
public static class Logger
{
private static ILoggerRepository loggerRepository;
public static ILoggerRepository LoggerRepository { get; private set; }
public static ILog Log { get; private set; }
/// <summary>
/// 静态构造函数,程序启动时自动执行
/// </summary>
//static Logger()
//{
// LoggerRepository = CreateLoggerRepository();
// LoadLog4NetConfig();
//}
/// <summary>
/// 初始化日志
/// </summary>
/// <returns></returns>
public static void LoadLogger()
{
LoggerRepository = CreateLoggerRepository();
LoadLog4NetConfig();
}
/// <summary>
/// 创建日志仓储实例
/// </summary>
/// <returns></returns>
private static ILoggerRepository CreateLoggerRepository()
{
loggerRepository = loggerRepository ?? LogManager.CreateRepository("GlobalExceptionHandler"); // 单例
return loggerRepository;
}
/// <summary>
/// 加载log4net配置
/// </summary>
private static void LoadLog4NetConfig()
{
// 配置log4net
log4net.Config.XmlConfigurator.Configure(loggerRepository, new System.IO.FileInfo(System.IO.Directory.GetCurrentDirectory() + "/Config/log4net.config"));
// 创建log实例
Log = LogManager.GetLogger(loggerRepository.Name, AppDomain.CurrentDomain.FriendlyName);
Log.Info("已加载日志配置");
}
}
}
c、全局异常捕获过滤器
全局异常捕获过滤器的代码如下,代码中并没有对异常做处理,只是直接输出到日志中,可以进一步对日志信息做处理使日志信息可读性更强。
using Microsoft.AspNetCore.Mvc.Filters;
namespace wxApp.Code.Creater.Api.Common
{
public class HttpGlobalExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
Logger.Log.Error("全局异常过滤器捕获的异常:", context.Exception);
}
}
}
c、指定日志提供程序为log4net以及全局异常捕获
在Startup类的ConfigureServices方法中指定日志提供程序,代码如下。
// 配置日志
services.AddLogging(logConfig => {
//log4net.Config.XmlConfigurator.Configure(Common.Logger.LoggerRepository);
Common.Logger.LoadLogger();
});
代码中Common.Logger.LoggerRepository为日志帮助类——Logger中创建的日志仓储实例。
在Startup类的ConfigureServices方法中添加全局异常捕获过滤器,代码如下。
// 添加全局异常捕获
services.AddMvc(option =>
{
option.Filters.Add<Common.HttpGlobalExceptionFilter>();
});
ConfigureServices方法中完整代码如下。