.Net Core日志记录之第三方框架Serilog

原文链接:https://www.jb51.net/article/251755.htm

                 https://blog.csdn.net/hiose89/article/details/125012881

这篇文章介绍了.Net Core日志记录之第三方框架Serilog

一、前言
对内置日志系统的整体实现进行了介绍之后,可以通过使用内置记录器来实现日志的输出路径。而在实际项目开发中,使用第三方日志框架(如: Log4Net、NLog、Loggr、Serilog、Sentry 等)来记录也是非常多的。首先一般基础的内置日志记录器在第三方日志框架中都有实现,然后第三方日志框架在功能上更加强大和丰富,能满足我们更多的项目分析和诊断的需求。

所以在这一篇中,我们将介绍第三方日志记录提供程序——Serilog

二、回顾

系统内置日志系列:

这个时候我们发现,其实在asp.net core中已经内置了日志系统,并提供了各种内置和第三方日志记录提供程序的日志记录接口,在进行应用开发中,可以进行统一配置,并且利用第三方日志框架相结合,更加有效的实现日志记录。所以在这个系列中,主要是对内置日志记录系统的学习,以及后续使用第三方日志框架集成我们需要的日志系统。

在新建项目成功之后,我们都会看到一个命名为appsettings.json配置,打开一看,短短的几行配置,

然后启动运行的时候,程序会在调试面板和控制台中分别输出显示来源如下:

在控制台中:

 在调试面板中:

 这里的日志配置,在系统中到底都起来什么作用?让我们来一探究竟吧!

三、开始

3.1 默认配置

我们查看源代码发现,在程序的入口点中发现,在初始化时候,通过CreateDefaultBuilder方法来实现日志记录的默认配置。

从Serilog的官方介绍中,我们可以发现 其框架是.net中的诊断日志库,可以在所有的.net平台上运行。支持结构化日志记录,对复杂、分布式、异步应用程序的支持非常出色。

Serilog是基于日志事件(log events),而不是日志消息(log message)。可以将日志事件格式化为控制台的可读文本或者将事件化为JSON格式。应用程序中的日志语句会创建LogEvent对象,而连接到管道的接收器(sinks)会知道如何记录它们。(接收器 包括各种终端、控制台、文本、SqlServer、ElasticSearch等等可用的列表)

 

为什么要使用Serilog?

Serilog比NLog 功能更为强大,能支持结构化的消息,不像NLog扁平和繁琐,配置也更加方便。支持代码配置、json、xml。但我觉得用代码配置就挺好,nlog就是XML配置太麻烦。

1、nuget 安装 
 Serilog.AspNetCore  会自动安装依赖项

2、(可选,异步写入)nuget 安装 Serilog.Sinks.Async  

3、注册服务配置写入文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
builder.Services.AddLogging(bulid =>
{
     Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Enrich.FromLogContext()
     WriteTo.Async(config => config.File(
               "d://.log",
               rollingInterval: RollingInterval.Day,
               fileSizeLimitBytes: 1024 * 1024 * 10,//单位字节 不配置时默認1GB
               retainedFileCountLimit: 10,//保留最近多少個文件  不配置时默認31個
               rollOnFileSizeLimit: true,//超過文件大小時 自動創建新文件
               shared: true)
     ))
    .CreateLogger();
    bulid.AddSerilog();
  
});

  4、随便找个控制器在构造函数注入后即可使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[HttpGet(Name = "GetWeatherForecast")]
      public IEnumerable<WeatherForecast> Get()
      {
          while (true)
          {
              _logger.LogInformation("ASDASDASDASDASDADSASDASDASDASDASDADSASDASDASDASDASDADSASDASDASDASDASDADS");
          }
         
          
           
          return Enumerable.Range(1, 5).Select(index => new WeatherForecast
          {
              Date = DateTime.Now.AddDays(index),
              TemperatureC = Random.Shared.Next(-20, 55),
              Summary = Summaries[Random.Shared.Next(Summaries.Length)]
          })
          .ToArray();
      }

  

打开d盘找到即可看见日志文本

输出格式如下:

2022-05-28 00:12:35.949 +08:00 [INF] ASDASDASDASDASDADSASDASDASDASDASDADSASDASDASDASDASDADSASDASDAS

(推荐)更高级一些的详细配置,建议把log等级分开配置 推荐配置4种

1、设置好4个路径,对应不同的日志类型

1
2
3
4
string infoPath = Directory.GetCurrentDirectory() + @"\logs\info\.log"; ;
string waringPath = Directory.GetCurrentDirectory() + @"\logs\waring\.log";
string errorPath = Directory.GetCurrentDirectory() + @"\logs\error\.log";
string fatalPath = Directory.GetCurrentDirectory() + @"\logs\fatal\.log";

 2、(推荐,不设也行)设置好模板

1
string template = "{NewLine}时间:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}等级:{Level}{NewLine}来源:{SourceContext}{NewLine}具体消息:{Message}{NewLine}{Exception}";

  3、具体配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
builder.Services.AddLogging(bulid =>
{
     Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .Enrich.FromLogContext()
    .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Information).
     WriteTo.Async(congfig => congfig.File(
               infoPath,
               rollingInterval: RollingInterval.Day,
               fileSizeLimitBytes: 1024 * 1024 * 10,//默認1GB
               retainedFileCountLimit: 10,//保留最近多少個文件  默認31個
               rollOnFileSizeLimit: true,//超過文件大小時 自動創建新文件 
               shared: true,
               outputTemplate: template)
     ))
    //-----------------------------------------------------------------------------------
     .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Warning).
     WriteTo.Async(congfig => congfig.File(
               waringPath,
               rollingInterval: RollingInterval.Day,
               fileSizeLimitBytes: 1024 * 1024 * 10,
               retainedFileCountLimit: 10,
               rollOnFileSizeLimit: true,
               shared: true,
               outputTemplate: template)
     ))
    //-----------------------------------------------------------------------------------
    .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Error).
     WriteTo.Async(congfig => congfig.File(
               errorPath,
               rollingInterval: RollingInterval.Day,
               fileSizeLimitBytes: 1024 * 1024 * 10,
               retainedFileCountLimit: 10,
               rollOnFileSizeLimit: true,
               shared: true,
               outputTemplate: template)
     ))
    //-----------------------------------------------------------------------------------
     .WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(lev => lev.Level == LogEventLevel.Fatal).
     WriteTo.Async(congfig => congfig.File(
               fatalPath,
               rollingInterval: RollingInterval.Day,
               fileSizeLimitBytes: 1024 * 1024 * 10,
               retainedFileCountLimit: 10,
               rollOnFileSizeLimit: true,
               shared: true,
               outputTemplate: template)
     ))
    //-----------------------------------------------------------------------------------
    .CreateLogger();
    bulid.AddSerilog();

  

只做了基本配置,不够用的话,具体更多配置或更高级用法自行查询官网。

https://github.com/serilog

 

疑问
Serilog 在 ASP.NET Core 5 中用的好好的,原项目升级到6也没有问题,可是为什么新建ASP.NET Core 6.0项目,使用不了"UseSerilog()"呢?

解释
因为6使用了"new minimal hosting model",5上面"UseSerilog()"是扩展在"IHostBuilder"上面的,而6上使用的是"WebApplicationBuilder",所以"UseSerilog()"自然就无法使用了,但是"builder.Host"上是"IHostBuilder"类型,可以把"UseSerilog()"用在"builder.Host"上,不建议使用"builder.WebHost"哦。

正确示例
.csproj 文件

1
2
3
4
5
6
7
<ItemGroup>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>

 

Program.cs

1
2
3
4
using Serilog;
 
const string OUTPUT_TEMPLATE = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}";
Log.Logger = new LoggerConfiguration()<br>.MinimumLevel.Override("Microsoft", LogEventLevel.Information)//排除Microsoft日志.MinimumLevel.Debug()<br>.Enrich.WithThreadId()<br>.Enrich.FromLogContext() <br>.WriteTo.Console(outputTemplate: OUTPUT_TEMPLATE) <br>.WriteTo.File("logs/app.txt" , rollingInterval: RollingInterval.Day , outputTemplate: OUTPUT_TEMPLATE) <br>.CreateLogger(); <br>try {<br>Log.Information("Starting web host"); <br>var builder = WebApplication .CreateBuilder(args); <br>builder.Host.UseSerilog(Log.Logger, dispose: true); // Add services to the container<br>. builder.Services.AddControllers(); <br>var app = builder.Build(); // Configure the HTTP request pipeline<br>. app.UseAuthorization(); <br>app.UseSerilogRequestLogging(); <br>app.MapControllers(); <br>app.Run(); <br>} catch (Exception ex) <br>{ Log.Fatal(ex, "Host terminated unexpectedly"); } <br>finally { Log.CloseAndFlush(); }

  

 

posted @   yinghualeihenmei  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2023-06-27 sql server DATEPART() 函数的使用(注意防止入坑)
2023-06-27 浅谈asp.net中的AsyncPostBackTrigger
2023-06-27 asp.net中Timer定时器在web中无刷新的使用
2023-06-27 UpdatePanel控件的使用(实现局部刷新,简单例子)
点击右上角即可分享
微信分享提示