日志系统
历时两天,研读文档,梳理并编码应用了.NET下的日志系统,日志系统相较于配置系统难度不大,目前总共研究了四个,.NET原生的logging,以配置为基础的NLog,在集群服务中的结构化日志Serilog,以及个人服务器Exceptionless/ELK(三个软件部署难度很高)。此篇文章仅记录基本使用,更加复杂和详细的使用请查阅单独的官方文档。
Logging
在.NET下,日志级别分为六类:Critical>Error>Warning>Information>Debug>Trace。使用只需要进行服务提供者注入即可。在AddConsole或者AddEventLog方法中实现的其实就是ConfigurationBuilder.Addxxx(),服务提供者。
static void Main(string[] args)
{
var service = new ServiceCollection();
service.AddLogging(e=> {
e.AddConsole();//Console Provider 保存日志到控制台下
e.AddEventLog();//EventLog Provider 保存日志到Windows平台下的EventViewer下。
//设置日志最低的输出级别,Critical>Error>Warning>Information>Debug>Trace
e.SetMinimumLevel(LogLevel.Trace);
});
service.AddScoped<EmailLog>();
using (var sp = service.BuildServiceProvider())
{
sp.GetRequiredService<EmailLog>().InitData();
sp.GetRequiredService<EmailLog>().OperateDataError();
}
}
//调用方
//这里面绑定的是什么类,输出的日志就会绑定到什么类上。
private readonly ILogger<CalculateLog> logger;
public CalculateLog(ILogger<CalculateLog> logger)
{
this.logger = logger;
}
public void OperateDataError()
{
logger.LogError("Operate calculate failed.");
logger.LogTrace("Tracking error.");
logger.LogError("Operate database failed.");
logger.LogDebug("Add a person{@person}", new { name = "Albert", age = 25, email = "szdxzhy@outlook.com" });
//可以将异常信息写入
try
{
File.ReadAllText("x");
}
catch (Exception ex)
{
logger.LogError(ex, "Exception");
}
}
NLog-文本日志
NLog通过Target和Rule来管理,将日志以什么样的规则输入到哪里(Target),默认配置nlog.config(最好小写,在linux下方便使用约定,约定大于配置)。如何实现滚动日志的效果:设置参数archiveAboveSize(单个文件最大字节数),maxArchiveFiles(单文件最多个数)。注意在使用NLog的时候尽量避免使用Logging的日志级别设置,因为NLog有自己一套日志级别设置,在配置文件中,具体请查阅NLog官方说明文档。
static void Main(string[] args)
{
var service = new ServiceCollection();
service.AddLogging(e=> {
e.AddNLog();//NLog Provider,保存日志到文件中,日志文件保存路径在配置文件中设置。
});
service.AddScoped<EmailLog>();
using (var sp = service.BuildServiceProvider())
{
sp.GetRequiredService<EmailLog>().InitData();
sp.GetRequiredService<EmailLog>().OperateDataError();
}
}
Serilog结构化日志
在设备集群中,结构化日志要比普通文本日志更加便于分析。安装Serilog的包,配置Log.Logger,e.AddSerilog()添加服务提供者。
static void Main(string[] args)
{
var service = new ServiceCollection();
service.AddLogging(e=> {
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.Console(new JsonFormatter())
.CreateLogger();
e.AddSerilog();
});
service.AddScoped<EmailLog>();
using (var sp = service.BuildServiceProvider())
{
sp.GetRequiredService<EmailLog>().InitData();
sp.GetRequiredService<EmailLog>().OperateDataError();
}
}
Serilog&Exceptionless集中日志服务
使用Serilog将结构化日志记录到数据库、MongoDB、云(此处选择私有云Exceptionless),请前往exceptionless.com注册账号并申请云服务。
static void Main(string[] args)
{
ExceptionlessClient.Default.Startup("xxxx");
var service = new ServiceCollection();
service.AddLogging(e=> {
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug()
.Enrich.FromLogContext()
.WriteTo.Console(new JsonFormatter())
.WriteTo.Exceptionless()
.CreateLogger();
e.AddSerilog();
});
service.AddScoped<EmailLog>();
using (var sp = service.BuildServiceProvider())
{
sp.GetRequiredService<EmailLog>().InitData();
sp.GetRequiredService<EmailLog>().OperateDataError();
}
}