.NET003-日志系统

Posted on 2022-01-14 14:20  DotNet技术官  阅读(133)  评论(0编辑  收藏  举报

日志系统

历时两天,研读文档,梳理并编码应用了.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();
    }
}