日常生活的交流与学习

首页 新随笔 联系 管理

一、ILogger 介绍

1.1 简介

ILogger 是. NET 框架提供的一个接口,用于统一不同日志库的调用方式。ILogger 本身并不提供具体的日志记录功能,而是通过实现它的类来执行这些操作。

所以我们可以借助第三方日志库或自定义实现 ILoggerProvider,将日志消息写入到文件、控制台或数据库中,也可以将其发送到远程服务器或其他目标。

1.2 开启日志记录提供程序

Asp.Net Core 默认内置了如下日志记录提供程序:

  1. Console
  2. Debug
  3. EventSource
  4. EventLog

除了以上日志记录提供程序,还可以通过 NuGet 安装,使用以下日志记录提供程序:

  1. AzureAppServicesFile 和 AzureAppServicesBlob
  2. ApplicationInsights

我们在 Windows 开发,一般就使用 Console,如果是正式环境,可能会用到 EventLog,记录到系统事件里去;
在 Linux 环境下,会使用 Debug 开发;其他大家可以根据自己的需求选择。

开启方式如下:在 Program.cs 添加如下代码,支持同时开启多个日志记录提供程序

builder.Logging.AddConsole().AddEventLog();

1.3 日志记录提供程序的使用

Asp.Net Core 为我们提供 2 个注入方式: ILogger 和 ILoggerFactory。

我们通过查看 ILoggerFactory 与 Logger 的源码,我们可以发现其实 Logger,是针对 ILoggerFactory 再次封装,简化我们的使用。

这两种的使用方式,如下,ILoggerFactory 的初始化的参数:categoryName,可以根据自己的需求自定义命名。

运行后的效果,在输出窗口,我们就可以看到日志:

系统事件可以看到日志记录:

1.4 日志配置

在 .Net 已经给日志定义了级别,我们可以在 appsettings.json,配置我们需要打印的日志。比如配置如下:

"Logging": {
    "LogLevel": {
    "Default": "Information",
    "Microsoft.AspNetCore": "Information"
    }
}

配置说明:

  1. 指定了 "Default"、"Microsoft.AspNetCore" 日志级别类别。
  2. "Default" 为全局类别,如果系统为找到对于的类别,就以这个 "Default" 为准。
  3. "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="&quot;logs_&quot;yyyyMMdd&quot;.log&quot;" />
		<!--日志文件名是否是固定不变的-->
		<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 其中一个,或者其他组件。

posted on 2024-05-02 19:41  lazycookie  阅读(143)  评论(0编辑  收藏  举报