18. 日志记录
📝 模块更新日志
-
新特性
- 控制台日志
AddConsoleFormatter
服务支持WriteFilter
属性过滤 4.8.8.52 ⏱️2023.11.07 516acb4 - 监听日志
LoggingMonitor
支持打印输出requestHeaders
请求头信息 4.8.8.50 ⏱️2023.10.27 #I8BHM3 - 监听日志
LoggingMonitor
支持配置日志输出级别 4.8.8.41 ⏱️2023.08.25 #I7SRTP - 监听日志
LoggingMonitor
支持Razor Pages
4.8.8.16 ⏱️2023.05.15 #I7332C - 日志配置
WithStackFrame
,可控制是否输出产生日志的程序集,类型和具体方法 4.8.7.16 ⏱️2023.03.19 5ad6ae2
- 控制台日志
查看变化
启用 WithStackFrame
日志配置后,可输出程序集,类型,方法签名信息。
// 控制台日志
services.AddConsoleFormatter(options =>
{
options.WithStackFrame = true;
});
// 文件日志
services.AddFileLogging(options =>
{
options.WithStackFrame = true;
});
// 数据库日志
services.AddDatabaseLogging(options =>
{
options.WithStackFrame = true;
});
日志输出如下:
info: 2023-03-17 18:25:06.7988349 +08:00 星期五 L System.Logging.EventBusService[0] #1
[Furion.dll] async Task Furion.EventBus.EventBusHostedService.ExecuteAsync(CancellationToken stoppingToken)
EventBus hosted service is running.
info: 2023-03-17 18:25:08.1393952 +08:00 星期 五 L Microsoft.Hosting.Lifetime[14] #1
[System.Private.CoreLib.dll] void System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<TStateMachine>(ref TStateMachine stateMachine)
Now listening on: https://localhost:5001
info: 2023-03-17 18:25:08.1620391 +08:00 星期五 L Microsoft.Hosting.Lifetime[14] #1
[System.Private.CoreLib.dll] void System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<TStateMachine>(ref TStateMachine stateMachine)
Now listening on: http://localhost:5000
info: 2023-03-17 18:25:08.1972456 +08:00 星期五 L Microsoft.Hosting.Lifetime[0] #1
[Microsoft.Extensions.Hosting.dll] void Microsoft.Extensions.Hosting.Internal.ConsoleLifetime.OnApplicationStarted()
Application started. Press Ctrl+C to shut down.
info: 2023-03-17 18:25:08.2456579 +08:00 星期五 L Microsoft.Hosting.Lifetime[0] #1
[Microsoft.Extensions.Hosting.dll] void Microsoft.Extensions.Hosting.Internal.ConsoleLifetime.OnApplicationStarted()
Hosting environment: Development
info: 2023-03-17 18:25:08.2746134 +08:00 星期五 L Microsoft.Hosting.Lifetime[0] #1
[System.Private.CoreLib.dll] void System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(bool throwOnFirstException)
Content root path: D:\Workplaces\OpenSources\Furion\samples\Furion.Web.Entry
info: 2023-03-17 18:25:18.1917784 +08:00 星期五 L Furion.Application.TestLoggerServices[0] #16
[Furion.Application.dll] void Furion.Application.TestLoggerServices.测试日志()
我是一个日志 20
这样就清楚地知道日志是哪个程序集、哪个类型、哪个方法输出的了。
-
- 审计日志
LoggingMonitor
支持对参数贴[SuppressMonitor]
特性跳过记录 4.8.7.3 ⏱️2023.03.01 #I6IVGW
- 审计日志
-
- 审计日志
LoggingMonitor
监听TraceId
、ThreadId
、Accept-Language
4.8.7.1 ⏱️2023.02.27 df35201
- 审计日志
-
- 审计日志
LoggingMonitor
支持配置序列化属性命名规则 4.8.6.12 ⏱️2023.02.21 #I6GPUP
- 审计日志
-
- 审计日志
LoggingMonitor
支持[DisplayName]
特性解析和Title
属性记录 4.8.5.10 ⏱️2023.02.07 #I6DHMF
- 审计日志
-
- 审计日志
LoggingMonitor
记录HTTP
响应状态码 4.8.5.2 ⏱️2023.01.30 abb4cbd
- 审计日志
-
突破性变化
- 监听日志
WriteFilter
和ConfigureLogger
的ActionExecutingContext
和ActionExecutedContext
类型为FilterContext
4.8.8.16 ⏱️2023.05.15 #I7332C
- 监听日志
-
问题修复
- 审计日志不支持
dynamic/JsonElement
序列化问题 4.8.8.45 ⏱️2023.09.29 #I84SD5 - 审计日志解析
DateTime
类型参数不是本地时间问题 4.8.8.33 ⏱️2023.06.29 #I7GW32 -
LoggingMonitor
打印泛型类型如果存在多个泛型参数问题 4.8.8.8 ⏱️2023.05.04 8d9cb74 - 日志输出
JSON
格式漏掉了UseUtcTimestamp
和TraceId
键值 4.8.7.21 ⏱️2023.03.27 5c90e65 - 日志消息没有处理
\n
换行符对齐问题 4.8.7.6 ⏱️2023.03.10 759bcc5 - 审计日志
LoggingMonitor
对特定参数贴有[FromServices]
特性依旧记录问题 4.8.7.3 ⏱️2023.03.01 17b134e - 在数据库日志的
IDatabaseLoggingWriter
实现类中依赖注入ILogger<>
导致死循环 4.8.5.4 ⏱️2023.02.01 #I6C6QU - 数据库日志提供程序在应用程序终止时出现空异常问题 4.8.5 ⏱️2023.01.28 #I6AZ8Y
- 数据库日志注册在一些特殊情况下丢失日志上下文问题 4.8.4.6 ⏱️2023.01.04 #I68PDF
- 在类中贴
[SuppressMonitor]
特性但LoggingMonitor
依然输出问题 4.8.4 ⏱️2022.12.30 #I6882I -
LoggingMonitor
序列化IQueryable<>
或OData
返回值类型出现死循环问题 4.8.3.4 ⏱️2022.12.10 7e8c9d0 - 通过
Ctrl + C
终止应用程序后获取TraceId
出现对象已释放异常 4.8.1.12 ⏱️2022.12.07 55c3e49 - 日志模块因
v4.8.0+
版本导致写入数据库日志空异常问题 4.8.2.1 ⏱️2022.11.28 8d9d72b
- 审计日志不支持
-
其他更改
18.1 关于日志
通常日志指的是系统日志和程序日志。
系统日志 是记录系统中硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找受到攻击时攻击者留下的痕迹。系统日志包括系统日志、应用程序日志和安全日志。
程序日志 是程序运行中产生的日志,通常由框架运行时或开发者提供的日志。包括请求日志,异常日志、审计日志、行为日志等。
18.2 日志作用
在项目开发中,都不可避免的使用到日志。没有日志虽然不会影响项目的正确运行,但是没有日志的项目可以说是不完整的。日志在调试,错误或者异常定位,数据分析中的作用是不言而喻的。
- 调试
在项目调试时,查看栈信息可以方便地知道当前程序的运行状态,输出的日志便于记录程序在之前的运行结果。
- 错误定位
不要以为项目能正确跑起来就可以高枕无忧,项目在运行一段时候后, 可能由于数据问题,网络问题,内存问题等出现异常。这时日志可以帮助开发或者运维人员快速定位错误位置,提出解决方案。
- 数据分析
大数据的兴起,使得大量的日志分析成为可能,ELK 也让日志分析门槛降低了很多。日志中蕴含了大量的用户数据,包括点击行为,兴趣偏好等,用户画像对于公司下一步的战略方向有一定指引作用。
18.3 日志级别
日志级别可以有效的对日志信息进行归类,方便准确的查看特定日志内容。通常日志类别有以下级别:
级别 | 值 | 方法 | 描述 |
---|---|---|---|
Trace(跟踪) | 0 | LogTrace | 包含最详细的消息。 这些消息可能包含敏感的应用数据。 这些消息默认情况下处于禁用状态,并且不应在生产中启用。 |
Debug(调试) | 1 | LogDebug | 用于调试和开发。 由于量大,请在生产中小心使用。 |
Information(信息) | 2 | LogInformation | 跟踪应用的常规流。 可能具有长期值。 |
Warning(警告) | 3 | LogWarning | 对于异常事件或意外事件。 通常包括不会导致应用失败的错误或情况。 |
Error(错误) | 4 | LogError | 表示无法处理的错误和异常。 这些消息表示当前操作或请求失败,而不是整个应用失败。 |
Critical(严重) | 5 | LogCritical | 需要立即关注的失败。 例如数据丢失、磁盘空间不足。 |
18.4 如何使用
在 .NET 5
框架中,微软已经为我们内置了 日志组件
,正常情况下,无需我们引用第三方包进行日志记录。.NET 5
框架为我们提供了两种日志对象创建方式。
18.4.1 ILogger<T>
泛型方式
使用非常简单,可以通过 ILogger<T>
对象进行注入,如:
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
_logger.LogInformation("GET Pages.PrivacyModel called.");
}
}
通过泛型 ILogger<T>
方式写入日志,那么默认将 T
类型完整类型名称作为 日志类别
。
18.4.2 ILoggerFactory
工厂方式
使用工厂方式,需手动传入 日志类别
,如:
public class ContactModel : PageModel
{
private readonly ILogger _logger;
public ContactModel(ILoggerFactory logger)
{
_logger = logger.CreateLogger("MyCategory");
}
public void OnGet()
{
_logger.LogInformation("GET Pages.ContactModel called.");
}
}
18.4.3 Log
静态类方式
以下内容仅限 Furion 4.2.1 +
版本使用。
// 创建日志对象
var logger = Log.CreateLogger("日志名称");
// 创建日志工厂
using var loggerFactory = Log.CreateLoggerFactory(builder => {
// ....
});
// 日志记录
Log.Information("Information");
Log.Warning("Warning");
Log.Error("Error");
Log.Debug("Debug");
Log.Trace("Trace");
Log.Critical("Critical");
18.4.4 懒人模式
😁
在 Furion
框架中,提供了更懒的方式写入日志,也就是通过字符串拓展的方式写入,如:
"简单日 志".LogInformation();
"百小僧 新增了一条记录".LogInformation<HomeController>();
"程序出现异常啦".LogError<HomeController>();
"这是自定义类别日志".SetCategory<HomeController>().LogInformation();
通过字符串拓展方式可以在任何时候方便记录日志,专门为懒人提供的。
18.5 输出到控制台
在 ASP.NET Core
应用程序中,主机启动时默认注册了 ConsoleLoggerProvider
提供器,也就是控制台日志输出提供器,所以无需任何注册服务即可在控制台输出。
info: Furion.EventBus.EventBusHostedService[0]
EventBus Hosted Service is running.
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\Workplaces\Furion\samples\Furion.Web.Entry\
18.5.1 日志过滤/筛选
通过日志筛选器可以对日志进行归类写入。
// 例子一:根据日志级别输出
services.AddConsoleFormatter(options =>
{
options.WriteFilter = (logMsg) => // Furion 4.8.8.52+ 版本支持
{
return logMsg.LogLevel == LogLevel.Information;
};
});
// 例子二,根据任何规则,比如特定的类名
services.AddConsoleFormatter(options => // Furion 4.8.8.52+ 版本支持
{
options.WriteFilter = (logMsg) =>
{
return logMsg.LogName == "System.Logging.LoggingMonitor";
};
});
18.5.2 日志标准化(美化)模板
以下内容仅限 Furion 4.5.0 +
版本使用。
在 ASP.NET Core
默认控制台日志相对简洁,并未包含常见的日志时间、线程 Id
等,而且自定义模板也相对复杂,所以 Furion 4.5.0+
版本提供了简化配置,如:
Startup.cs
方式
services.AddConsoleFormatter();
.NET5
方式
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddConsoleFormatter();
});
.NET6
方式
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddConsoleFormatter();
Serve.Run()
方式
Serve.Run(RunOptions.Default.AddWebComponent<WebComponent>());
public class WebComponent : IWebComponent
{
public void Load(WebApplicationBuilder builder, ComponentContext componentContext)
{
builder.Logging.AddConsoleFormatter();
}
}
输出结果:
info: 2023-03-23 11:51:02.3757469 +08:00 星期四 L Microsoft.Hosting.Lifetime[14] #1
Now listening on: https://localhost:7025
info: 2023-03-23 11:51:02.4993301 +08:00 星期四 L Microsoft.Hosting.Lifetime[14] #1
Now listening on: http://localhost:5217
info: 2023-03-23 11:51:02.5058785 +08:00 星期四 L Microsoft.Hosting.Lifetime[0] #1
Application started. Press Ctrl+C to shut down.
info: 2023-03-23 11:51:02.5100496 +08:00 星期四 L Microsoft.Hosting.Lifetime[0] #1
Hosting environment: Development
info: 2023-03-23 11:51:02.5127095 +08:00 星期四 L Microsoft.Hosting.Lifetime[0] #1
Content root path: C:\Users\snrcsoft\source\repos\WebApplication1\WebApplication1
18.5.3 自定义日志模板
services.AddConsoleFormatter(options =>
{
options.MessageFormat = (logMsg) =>
{
var stringBuilder = new StringBuilder();
stringBuilder.Append(DateTime.Now.ToString("o"));
// 其他的。。。自己组装
return stringBuilder.ToString();
};
});
// 输出为 JSON 格式,Furion 4.5.2+
services.AddConsoleFormatter(options =>
{
options.MessageFormat = LoggerFormatter.Json;
// Furion 4.8.0+ 新增 JSON 美化输出
options.MessageFormat = LoggerFormatter.JsonIndented;
});