.NetCore
之日志记录(一)日志记录对一个系统而言非常重要,一般来说日志记录是新系统上线必备的功能,日志记录可以帮助我们排查系统在运行中的问题,以及记录用户的操作行为,有助于我们在后续出现问题的时候,追溯和排查问题的根源,也有助于系统的完善、升级和维护。
.NetCore
框架集成了自己的日志系统,也能很
方便的与第三方日志记录系统集成,例如Log4Net
、NLog
和Serilog
等。
一般来说日志主要由以下部分组成,日志消息,日志等级、日志记录器,日志配置。
日志消息是我们需要记录的消息,一般日志消息需要准确的描述当前需要表达的状态以及结果。一般的日志消息,都是根据消息模板来进行组成日志消息的。
一般来说日志消息模板主要有两种方式
数字型模板
变量型模板
数字型模板
logger.LogInformation("This method is:{0} excute the result is: {1}", typeof(mymehtod).name,result);
变量名型模板
logger.LogInformation("Can't find the id {id}",id);
注意点
var weather = new WeatherForecast()
{
Date= DateTime.Now,
TemperatureC=32
}
;
_logger.LogInformation("The weather of Date({Date}) is :{Temperture}℃", weather.Date, weather.TemperatureC);
_logger.LogInformation("The weather of Date({Date}) is :{Temperature}℃", weather.TemperatureC, weather.Date);
_logger.LogInformation("The weather of Date({weather.Date}) is :{weather.TemperatureC}℃", weather.TemperatureC, weather.Date);
_logger.LogInformation("The weather of Date({0}) is :{1}℃", weather.Date, weather.TemperatureC);
_logger.LogInformation("The weather of Date({0}) is :{1}℃", weather.TemperatureC, weather.Date);
可以看出上述不论是数字型还是变量型消息模板,参数的占位符必须和后续的参数一一对应,才能正确显示正确的消息
但是还是推荐使用变量名式的消息模板,因为这样可读性比较高
变量型的消息模板,变量名不必和实际的变量保持一致,如上 weather.Date 完全可以只用Date来表示占位。
日志等级也称为日志级别,不同的日志等级,对应消息的不同程序,方便我们查找和过滤消息。一般来说日志等级主要分为五种,但是.NET Core
内置框架分了6种。
logLevel | “值” | 方法 | 说明 |
---|---|---|---|
Trace | 0 | LogTrace | 包含最详细的消息。 这些消息可能包含敏感的应用数据。 这些消息默认情况下处于禁用状态,并且不应在生产中启用。 |
Debug | 1 | LogDebug | 用于调试和开发。 由于量大,请在生产中小心使用。 |
Information | 2 | LogInformation | 跟踪应用的常规流。 可能具有长期值。 |
Warning | 3 | LogWarning | 对于异常事件或意外事件。 通常包括不会导致应用失败的错误或情况。 |
Error | 4 | LogError | 表示无法处理的错误和异常。 这些消息表示当前操作或请求失败,而不是整个应用失败。 |
Critical | 5 | LogCritical | 需要立即关注的失败。 例如数据丢失、磁盘空间不足。 |
None | 6 | 指定日志记录类别不应写入消息。 |
在NETCore
的内置框架中,有两种使用日志级别的方式,
_logger.LogInformation(message); //直接使用对应级别的实现
_logger.Log(LogLevel.None, MyLogEvents.TestItem, routeInfo);//使用logger,传入对应的级别
一般来说等级越低的日志级别记录的消息应该越详细。
ASP.NET Core
包括以下日志记录提供程序作为共享框架的一部分:
Console
提供程序将输出记录到控制台
Debug
提供程序使用 [System.Diagnostics.Debug]
(https://learn.microsoft.com/zh-cn/dotnet/api/system.diagnostics.debug) 类写入日志输出。 对 System.Diagnostics.Debug.WriteLine
的调用写入到 Debug
提供程序。
在 Linux 上,Debug
提供程序日志位置取决于分发,并且可以是以下位置之一:
/var/log/message
/var/log/syslog
EventSource
将日志写入事件追踪源。
EventLog
提供程序将日志输出发送到 Windows 事件日志。默认级别是Warning。
ASP.NET Core
不包括用于将日志写入文件的日志记录提供程序,如果想要将日志写入文件或者数据库必须使用第三方日志。但是我们在日常使用100%都是要文件记录日志的,这微软好像没搞懂实际需求,把最重要的记录器省略了,这也是我们到目前为止,每次使用ASP.NET Core
记录日志,必须要使用第三方日志的原因。
大部分的日志框架都提供了两种配置方式,一种是以纯代码的形式进行日志配置,一种是以配置文件的形式,其中配置文件又分为以json 和xml 格式为主。配置文件的形式比较灵活,而且很多优秀的日志框架可以支持热加载,就是更改完配置文件后可以立即生效,不需要重启程序。
日志记录配置通常由 appsettings.{ENVIRONMENT}.json
文件的 Logging
部分提供,其中 {ENVIRONMENT}
占位符是环境。 以下 appsettings.Development.json
文件由 ASP.NET Core Web
应用模板生成
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
在上述 JSON 中:
"Default"
和 "Microsoft.AspNetCore"
类别。"Microsoft.AspNetCore"
类别适用于以 "Microsoft.AspNetCore"
开头的所有类别。 例如,此设置适用于 "Microsoft.AspNetCore.Routing.EndpointMiddleware"
类别。"Microsoft.AspNetCore"
类别在日志级别 Warning
或更高级别记录。LogLevel
适用于所有启用的日志记录提供程序,但 Windows EventLog 除外日志可以根据不同的输出源进行设置,相同的日志设置,后面的会覆盖前面的,带环境名称的配置文件中的设置,会覆盖不带环境名配置文件中的相同设置。
Program.cs
中的使用日志var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();
.Net6之前没有顶级语句的在Main中使用日志
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
var logger = host.Services.GetRequiredService>();
logger.LogInformation("Host created.");
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
在Starup中使用日志
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
ILogger logger)
{
if (env.IsDevelopment())
{
logger.LogInformation("In Development.");
app.UseDeveloperExceptionPage();
}
else
{
logger.LogInformation("Not Development.");
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
不支持在 Startup.ConfigureServices
方法中完成 DI 容器设置之前就写入日志:
Startup
构造函数中。Startup.ConfigureServices
方法签名中这一限制的原因是,日志记录依赖于 DI 和配置,而配置又依赖于 DI。 在完成 ConfigureServices
之前,不会设置 DI 容器。