LogLevel 日志级别的定义有一下七种:
ILogger 对象也有对应的日志级别记录方法:
以上方法的重载方法都支持传入 EventId事件Id对象以及 Exception异常对象参数,便于更详细的记录日志以及更方便的排查问题。
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"Console": {
"LogLevel": {
"Default": "Information",
"Program": "Trace",
"Demo.OrderService": "None"
}
}
}
}
直接在构造函数中注入ILogging对象即可使用:
class DemoController
{
private readonly ILogger<DemoController> _logger;
public DemoController(ILogger<DemoController> logger)
{
_logger = logger;
_logger.LogInformation("DemoController ctor");
}
}
注意事项:
在记录日志时,应该避免记录敏感信息,如密码、密钥等。
建议使用模板拼接字符串的方式,尽量避免使用$或其他方式拼接字符串,使用模板拼接字符串的方式可以有效减少不必要的消耗:
// 建议使用,在确认要输出日志后,再进行字符串拼接,可以有效减少不必要的消耗
_logger.LogInformation("Show Time{time}", DateTime.Now);
// 尽量避免使用,不管输不输出日志都会先把字符串拼接好
_logger.LogInformation($"Show Time{DateTime.Now}");
使用 BeginScope 开启日志作用域:
using (_logger.BeginScope("ScopeId:{scopeId}", Guid.NewGuid()))
{
logger.LogInformation("这是Info");
logger.LogError("这是Error");
logger.LogTrace("这是Trace");
}
使用结构化日志的好处有:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Error",
"System": "Information"
}
}
},
"AllowedHosts": "*"
}
配置单独存放在配置文件的Serilog节点下,Override下的配置可以重载Logging下配置的日志记录等级
首先需要引用包:Serilog.AspNetCore
在Program应用程序Main函数中配置Serilog:
public class Program
{
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
.MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.Console(new RenderedCompactJsonFormatter()) //输出日志到控制台
.WriteTo.File(formatter: new CompactJsonFormatter(), "logs\\myapp.txt", rollingInterval: RollingInterval.Day) //输出日志到文件 new CompactJsonFormatter():输出格式
.CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog(dispose: true); //使用Serilog
}
在其他服务类中使用时,直接注入ILogger对象即可。
引用包:Serilog.Sinks.Elasticsearch
包内包含的 ElasticsearchJsonFormatter 能够让日志的json输出兼容Elasticsearch的JSON格式(如 @timestamp )
更改 Serilog 配置使用 ElasticsearchJsonFormatter :
.WriteTo.Console(new ElasticsearchJsonFormatter())
控制台输出日志时,将按照Elasticsearch需要的格式来输出,如:
{
"@timestamp": "2021-08-15T22:31:43.9143984+12:00",
"level": "Information",
"messageTemplate": "{HostingRequestStartingLog:l}",
"message": "Request starting HTTP\/1.1 GET http:\/\/localhost:5000\/ ",
"fields": {
"Protocol": "HTTP\/1.1",
"Method": "GET",
"ContentType": null,
"ContentLength": null,
"Scheme": "http",
"Host": "localhost:5000",
"PathBase": "",
"Path": "\/",
"QueryString": "",
"HostingRequestStartingLog": "Request starting HTTP\/1.1 GET http:\/\/localhost:5000\/ ",
"EventId": {
"Id": 1
},
"SourceContext": "Microsoft.AspNetCore.Hosting.Internal.WebHost",
"RequestId": "0HLDRS5H8TSM4:00000001",
"RequestPath": "\/",
"CorrelationId": null,
"ConnectionId": "0HLDRS5H8TSM4"
},
"renderings": {
"HostingRequestStartingLog": [{
"Format": "l",
"Rendering": "Request starting HTTP\/1.1 GET http:\/\/localhost:5000\/ "
}]
}
}
在服务容器化时,可以使用 Fluentd 监控控制台,并将输出通过管道传输到 Elasticsearch 集群。