20 | 结构化日志组件Serilog:记录对查询分析友好的日志

之前讲解的日志框架,记录的日志都是文本,而且是非结构化的,这样一串串文本实际上不利于我们去做分析

结构化的日志它的好处就显而易见,它可以让我们更易于去检索,更易于与现有的分析系统进行结合

结构化日志的主要场景:

1、实现日志告警

2、实现上下文的关联:可以在日志系统里面对一段业务逻辑输出的日志进行分析

3、实现与追踪系统集成:在调用链的系统里面看到有问题的情况下,可以追踪到调用链过程中间的所有的日志信息

这里创建的依然是一个默认的 ASP.NET Core 的工程

引用包:Serilog.AspNetCore

这个包实际上依赖了 Serilog 很多的内置的包

比如核心的 Serilog (2.8.0)

配置 Serilog.Settings.Configuration (3.1.0)

Console 的输出 Serilog.Sinks.Console (3.1.1)

Debug 的输出 Serilog.Sinks.Debug (1.0.1)

File 的输出 Serilog.Sinks.File (4.0.0)

我们在 Program 这里提前读取一下配置,然后传递给 Serilog 的初始化过程,这里我们把 Main 函数进行了稍微的改造,以让 Serilog 可以接替整个默认的日志记录框架

namespace LoggingSerilogDemo
{
public class Program
{
// 读取配置
public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.AddEnvironmentVariables()
.Build(); public static int Main(string[] args)
{
// 将配置传递给 Serilog 的初始化过程
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)
.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);// dispose 设置为 true,它就会在退出时帮我们释放我们的日志对象
}
}

启动程序,输出如下:

{"@t":"2020-03-08T15:47:40.2569100Z","@m":"Starting web host","@i":"4872fd06"}
{"@t":"2020-03-08T15:47:44.1978171Z","@m":"Get 随机创建数据","@i":"6936e72c","SourceContext":"LoggingSerilogDemo.Controllers.WeatherForecastController","ActionId":"8d8ebb60-2211-4acb-bc91-a079be45a689","ActionName":"LoggingSerilogDemo.Controllers.WeatherForecastController.Get (LoggingSerilogDemo)","RequestId":"0HLU3F052RUUN:00000001","RequestPath":"/weatherforecast","SpanId":"|99917a4d-4ccf47636d09b066.","TraceId":"99917a4d-4ccf47636d09b066","ParentId":""}

可以看到每一行都是一个 json,也就是将日志输出为 json 格式,这就意味着可以在整个日志系统里面以 json 的格式去检索数据,比如 SourceContext 就是 Logger 的 name

它还记录了请求上下文,并且输出了 RequestId,SpanId,TraceId,ParentId

RequestId 与 SpanId 的作用就是与追踪系统可以结合

我们记录的日志的方式实际上是与之前是一样的,Controller 里面还是注入了 ILogger,依然使用 ILogger 来记录日志

namespace LoggingSerilogDemo.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
}; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
} [HttpGet]
public IEnumerable<WeatherForecast> Get()
{ _logger.LogInformation("Get 随机创建数据");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray(); }
}
}

也就是说可以通过简单的配置和几行代码的设置就可以替换官方提供的日志框架,让我们具备记录结构化日志的能力

我们刚才看到日志输出到 Console,同时输出到文件,可以看到 logs 目录已经产生了一个 myapp20200308.txt 文件

{"@t":"2020-03-08T15:47:40.2569100Z","@mt":"Starting web host"}
{"@t":"2020-03-08T15:47:44.1978171Z","@mt":"Get 随机创建数据","SourceContext":"LoggingSerilogDemo.Controllers.WeatherForecastController","ActionId":"8d8ebb60-2211-4acb-bc91-a079be45a689","ActionName":"LoggingSerilogDemo.Controllers.WeatherForecastController.Get (LoggingSerilogDemo)","RequestId":"0HLU3F052RUUN:00000001","RequestPath":"/weatherforecast","SpanId":"|99917a4d-4ccf47636d09b066.","TraceId":"99917a4d-4ccf47636d09b066","ParentId":""}

这个文件可以看到每一行是一条日志,每一条日志都是一个 json 对象,包括刚才我们记录的 Get 随机创建数据,已经输出出来了

我们可以调整日志级别,打开配置文件

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Error",
"System": "Information"
}
}
},
"AllowedHosts": "*"
}

Serilog 需要单独配置,它与之前的配置方式略有不同,它需要配置最小的日志输出级别,默认是 Information

Override 是重载上面 Logging 定义的日志级别

设置 Microsoft 为 Error 之后会把 Microsoft 默认的日志输出级别过滤掉

也意味着整个的配置和输出的方式与之前是级别类似的,我们可以把日志输出到 Console,也可以把日志输出到文件,当然实际上 Serilog 还提供了很多的这种输出的提供程序,还可以与 EFK,ELK 这种日志的套件进行集成,把日志输出到分析系统里面

GitHub源码链接:

https://github.com/MingsonZheng/DotNetCoreDevelopmentActualCombat/tree/main/LoggingSerilogDemo

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

.NET Core开发实战(第20课:结构化日志组件Serilog:记录对查询分析友好的日志)--学习笔记的更多相关文章

  1. 2月送书福利:ASP.NET Core开发实战

    大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...

  2. [ASP.NET Core开发实战]开篇词

    前言 本系列课程文章主要是学习官方文档,再输出自己学习心得,希望对你有所帮助. 课程大纲 本系列课程主要分为三个部分:基础篇.实战篇和部署篇. 希望通过本系列课程,能让大家初步掌握使用ASP.NET ...

  3. 【.NET Core项目实战-统一认证平台】第八章 授权篇-IdentityServer4源码分析

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我介绍了如何在网关上实现客户端自定义限流功能,基本完成了关于网关的一些自定义扩展需求,后面几篇将介绍基于IdentityServer ...

  4. [AI开发]基于DeepStream的视频结构化解决方案

    视频结构化的定义 利用深度学习技术实时分析视频中有价值的内容,并输出结构化数据.相比数据库中每条结构化数据记录,视频.图片.音频等属于非结构化数据,计算机程序不能直接识别非结构化数据,因此需要先将这些 ...

  5. 吴恩达《深度学习》-课后测验-第三门课 结构化机器学习项目(Structuring Machine Learning Projects)-Week1 Bird recognition in the city of Peacetopia (case study)( 和平之城中的鸟类识别(案例研究))

    Week1 Bird recognition in the city of Peacetopia (case study)( 和平之城中的鸟类识别(案例研究)) 1.Problem Statement ...

  6. Elasticsearch 结构化搜索、keyword、Term查询

    前言 Elasticsearch 中的结构化搜索,即面向数值.日期.时间.布尔等类型数据的搜索,这些数据类型格式精确,通常使用基于词项的term精确匹配或者prefix前缀匹配.本文还将新版本的&qu ...

  7. 那些年我们用过的组件-结构化日志组件 Serilog

    什么是结构化日志 我们记录日志惯常使用 log4j2.NLog 等日志组件,这些组件提供了输出到多种终端的能力,但是大部分时候我们选择将日志输出到操作系统的文件系统中,为什么呢?至少有一部分原因是记录 ...

  8. 第2课第6节_Java面向对象编程_包和权限_P【学习笔记】

    摘要:韦东山android视频学习笔记  1.使用package定义编译的时候存放的位置 package a.b.c.d; public class Package { public static v ...

  9. 第2课第1节_Java面向对象编程_类的引入_P【学习笔记】

    摘要:韦东山android视频学习笔记 1. 面向对象编程的引入,我们先写一个简单的程序输出张三,李四的名字.代码如下,假如,现在我们要在名字前面添加籍贯广东,那样岂不是每个printf语句都得修改添 ...

  10. .NET Core开发实战(第11课:文件配置提供程序)--学习笔记

    11 | 文件配置提供程序:自由选择配置的格式 文件配置提供程序 Microsoft.Extensions.Configuration.Ini Microsoft.Extensions.Configu ...

随机推荐

  1. BTC-实现

    BTC-实现 Transaction-based ledger(比特币是基于交易的账本模式) Account-based ledger(以太坊是基于账户的账本模式) UTXO Unspent Tran ...

  2. java基础-常用类-day11

    目录 1. 包装类 2. Integer类 3.util.date 4. java.sql.Date 5. SimpleDateFormat 6. Calendar 7. Math 8. String ...

  3. python毕业设计选题15例,马上要毕业啦,大家做好准备了没

    Hi,大家好,大四的同学马上要开始毕业设计啦,大家做好准备了没! 学长给大家详细整理了最新的python计算机毕设相关选题,对选题有任何疑问,都可以问学长哦. 1. 网上商城系统 这是一个基于pyth ...

  4. java: 程序包xxx.xxx.xxx不存在

    1.问题 在拷贝进来一个文件夹/文件进入项目后,发生报错:java: 程序包com.itheima.mp.domain.query不存在 2.解决 这里主要是由于我们的文件直接拷贝进来,导致编译的时候 ...

  5. 【css】 text-align 居中导航

    原理 :利用 inline-block 将 导航 作为 文本 , 被外层具有 text-align 属性的导航盒子包含 .从而实现居中效果 1.  html 结构 <header> < ...

  6. 【wayn商城】本地开发指南

    这篇文章给大家带来我自己写的开源项目[wayn商城]的本地开发指南,帮助各位朋友在本地快速运行[wayn商城],避免踩坑,减少不必要的精力在软件下载安装上. waynboot-mall 是一套全部开源 ...

  7. [转帖]MySQL ALTER TABLE: ALTER vs CHANGE vs MODIFY COLUMN

    https://www.cnblogs.com/pachongshangdexuebi/p/5029152.html ALTER COLUMN 语法: ALTER [COLUMN] col_name ...

  8. [转帖]Kingbase实现Oracle userenv函数功能

    目录 1. 问题 2. 文档概述 3. Oracle userenv()函数功能调研 3.1. 函数名称/函数原型 3.2. 函数功能 3.3. 参数介绍 3.3.1. Parameter 3.4. ...

  9. [转帖]大模型训练,英伟达Turing、Ampere和Hopper算力分析

    https://www.eet-china.com/mp/a219195.html 大 GPU 优势在于通过并行计算实现大量重复性计算.GPGPU即通用GPU,能够帮助 CPU 进行非图形相关程序的运 ...

  10. [转帖]Shell中常用的date时间命令

    常用FORMAT %Y  YYYY格式的年份(Year) %m  mm格式的月份(),01-12 %d   dd格式的日期(day of month),01-31 %H   HH格式的小时数(),00 ...