一、ILogger 介绍
1.1 简介
ILogger 是. NET 框架提供的一个接口,用于统一不同日志库的调用方式。ILogger 本身并不提供具体的日志记录功能,而是通过实现它的类来执行这些操作。
所以我们可以借助第三方日志库或自定义实现 ILoggerProvider,将日志消息写入到文件、控制台或数据库中,也可以将其发送到远程服务器或其他目标。
1.2 开启日志记录提供程序
Asp.Net Core 默认内置了如下日志记录提供程序:
- Console
- Debug
- EventSource
- EventLog
除了以上日志记录提供程序,还可以通过 NuGet 安装,使用以下日志记录提供程序:
- AzureAppServicesFile 和 AzureAppServicesBlob
- ApplicationInsights
我们在 Windows 开发,一般就使用 Console,如果是正式环境,可能会用到 EventLog,记录到系统事件里去;
在 Linux 环境下,会使用 Debug 开发;其他大家可以根据自己的需求选择。
开启方式如下:在 Program.cs 添加如下代码,支持同时开启多个日志记录提供程序。
builder.Logging.AddConsole().AddEventLog();
1.3 日志记录提供程序的使用
Asp.Net Core 为我们提供 2 个注入方式: ILogger
我们通过查看 ILoggerFactory 与 Logger 的源码,我们可以发现其实 Logger,是针对 ILoggerFactory 再次封装,简化我们的使用。
这两种的使用方式,如下,ILoggerFactory 的初始化的参数:categoryName,可以根据自己的需求自定义命名。
运行后的效果,在输出窗口,我们就可以看到日志:
系统事件可以看到日志记录:
1.4 日志配置
在 .Net 已经给日志定义了级别,我们可以在 appsettings.json,配置我们需要打印的日志。比如配置如下:
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information"
}
}
配置说明:
- 指定了 "Default"、"Microsoft.AspNetCore" 日志级别类别。
- "Default" 为全局类别,如果系统为找到对于的类别,就以这个 "Default" 为准。
- "Microsoft.AspNetCore" 适用于以 "Microsoft.AspNetCore" 开头的所有类别,比如:Microsoft.AspNetCore.Mvc 下的所有控制器。
类别配置
比如,在上面的例子中,我们自定义了 “MyLogLevel” 这个类别。
对应的我们可以在配置文件,添加 MyLogLevel 如下配置:
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information",
"MyLogLevel": "Information"
}
},
而 ILogger 会根据传入的类别,获取类以及父类的命名空间,进行匹配。
提供程序配置
.Net 同样为每一个提供程序,提供了别名,可用于更加详细的配置。
比如以下配置,我们可以通过 Console、Debug、EventSource、EventLog、AzureAppServicesFile、AzureAppServicesBlob、ApplicationInsights 来自定义配置。
{
"Logging": {
"LogLevel": {
"Default": "Error",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Information"
}
},
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft.Extensions.Hosting": "Warning",
"Default": "Information"
}
},
"EventSource": {
"LogLevel": {
"Microsoft": "Information"
}
},
"EventLog": {
"LogLevel": {
"Microsoft": "Information"
}
},
"AzureAppServicesFile": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Warning"
}
},
"AzureAppServicesBlob": {
"IncludeScopes": true,
"LogLevel": {
"Microsoft": "Information"
}
},
"ApplicationInsights": {
"LogLevel": {
"Default": "Information"
}
}
}
}
1.5 日志级别
.Net 提供了 7 个日志级别:
- Trace:0,包含最详细的消息。 这些消息可能包含敏感的应用数据。
- Debug:1,用于调试和开发。
- Information:2,一般用于跟踪系统的日志。
- Warning:3,一般用于记录异常事件或意外事件。
- Error:4,一般用于记录无法处理的异常。
- Critical:5,需要马上处理的失败,比如数据丢失、磁盘控件不足。
- None:6,关闭日志打印。
1.6 日志事件 ID
通过查看 ILogger 的扩展方法,我们还可以为每个事件定义一个事件 ID。
事件 ID 定义:
public class AppLogEvents
{
public static EventId Create = new(1000, "Created");
public static EventId Read = new(1001, "Read");
public static EventId Update = new(1002, "Updated");
public static EventId Delete = new(1003, "Deleted");
public static EventId ReadNotFound = 4000;
public static EventId UpdateNotFound = 4001;
}
事件 ID,使用方法:
_logger2.LogInformation(AppLogEvents.Create, "Create 日志记录");
_logger2.LogInformation(AppLogEvents.Update, "Update 日志记录");
_logger2.LogInformation(AppLogEvents.ReadNotFound, "ReadNotFound 日志记录");
日志效果:
二、log4Net
2.1 安装依赖
项目 Electric.API 添加依赖:
1、Microsoft.Extensions.Logging.Log4Net.AspNetCore,版本:6.1.0。
2、log4net,版本:2.0.15。
2.2 开启日志
在 Program.cs,添加如下代码,注入日志,通过 AddLog4Net 这个扩展方法,启用 Log4Net。
添加的代码:
builder.Logging.AddLog4Net();
2.3 日志配置
项目 Electric.API 添加文件 log4net.config。
log4net.config 配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="DebugAppender" type="log4net.Appender.DebugAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<!--指定日记记录方式,以滚动文件的方式(文件记录)-->
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<!--日志路径-->
<file value="log\" />
<!--是否是向文件中追加日志-->
<appendToFile value="true" />
<!--log保留天数-->
<param name= "MaxSizeRollBackups" value= "10"/>
<!--每个文件最大3M-->
<param name="maximumFileSize" value="3MB" />
<!--日志根据日期滚动-->
<param name="RollingStyle" value="Date" />
<!--日志文件名格式为:logs_20230431.log-->
<param name="DatePattern" value=""logs_"yyyyMMdd".log"" />
<!--日志文件名是否是固定不变的-->
<param name="StaticLogFileName" value="false" />
<!--布局-->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="DebugAppender" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
2.4 添加全局异常日志
1、首先在 ElectricExceptionFilterAttribute,构造函数注入日志对象。
2、记录全局异常
ElectricExceptionFilterAttribute 完整代码如下:
namespace Electric.API.Exception;
/// <summary>
/// 异常过滤器
/// </summary>
public class ElectricExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly ILogger<ElectricExceptionFilterAttribute> _logger;
/// <summary>
/// 依赖注入日志对象
/// </summary>
/// <param name="logger"></param>
public ElectricExceptionFilterAttribute(ILogger<ElectricExceptionFilterAttribute> logger)
{
_logger = logger;
}
/// <summary>
/// 异常处理
/// </summary>
/// <param name="context"></param>
public override void OnException(ExceptionContext context)
{
//如果异常没有被处理则进行处理
if (context.ExceptionHandled == false)
{
var str = $"异常:{context.HttpContext.Request.Path}{context.Exception.Message}";
// 记录日志
_logger.LogWarning(str);
context.Result = new ContentResult
{
// 返回状态码500,表示服务器异常
StatusCode = StatusCodes.Status500InternalServerError,
Content = "服务器异常,请联系管理员"
};
//设置为true,表示异常被处理了
context.ExceptionHandled = true;
}
}
}
2.5 日志效果
项目启动调试后,系统就会自动创建文件夹 log,并根据日期记录日志,以下日志信息是配置信息。
比如:我们把数据库配置信息,改为不正确的,系统就会捕捉异常并记录。
2.6 其他
在实际项目开发,如果有其他地方需要记录日志的,只需和异常过滤器一样,通过构造函数注入,直接使用就可以了。这边就不在举例了。
最后
最后做个总结:
ILogger 是一个接口,用于统一不同日志库的调用方式,而 log4net 是一个功能强大的开源组件,用于记录应用程序事件。大家可以根据自己的需求和喜欢,选择合适的日志组件,比如 NLog、Serilog、Log4Net 其中一个,或者其他组件。