Serilog 是一个用于 .NET 应用程序的诊断日志库。它易于设置,具有干净的 API,并且可以在所有最新的 .NET 平台上运行。尽管即使在最简单的应用程序中它也很有用,但 Serilog 对结构化日志记录的支持在检测复杂、分布式和异步应用程序和系统时大放异彩。

与 .NET 的许多其他库一样,Serilog 为文件、控制台和许多其他输出提供诊断日志记录。

var log = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("log.txt")
.CreateLogger(); log.Information("Hello, Serilog!");

与其他日志库不同,Serilog 是从头开始构建的,用于记录结构化事件数据。

var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34; log.Information("Processed {@Position} in {Elapsed} ms", position, elapsedMs);

Serilog 使用消息模板,这是一种简单的 DSL,它使用命名参数和位置参数扩展 .NET 格式字符串。Serilog 不会立即将事件格式化为文本,而是捕获与每个命名参数关联的值。

上面的示例在日志事件中记录了两个属性Position和。前面Elapsed的操作符告诉 Serilog序列化传入的对象,而不是使用. Serilog 对结构化事件数据的深入而丰富的支持开辟了使用传统记录器时不可用的大量诊断可能性。@PositionToString()

例如,呈现为JSON 格式的这些属性会出现在时间戳、级别和消息旁边,例如:

{"Position": {"Latitude": 25, "Longitude": 134}, "Elapsed": 34}

能够记录结构化事件数据的后端使日志搜索和分析成为可能,而无需日志解析或正则表达式。

支持结构化数据并不意味着放弃文本:当 Serilog 将事件写入文件或控制台时,模板和属性会呈现为友好的人类可读文本,就像传统的日志库会产生一样:

09:14:22 [INF] Processed {"Latitude": 25, "Longitude": 134} in 34 ms.

从 Serilog 1.x 升级?查看2.0 升级指南和发行说明。

特征

  • 社区支持并积极开发
  • 基于格式的日志 API,具有熟悉的级别,如Debug、Information、Warning、Error等
  • 可发现的 C# 配置语法和可选的XML或JSON配置支持
  • 启用时高效,关闭日志记录级别时开销极低
  • 一流的 .NET Core 支持,包括与 ASP.NET Core 的丰富集成
  • 支持全面的接收器,包括文件、控制台、本地和基于云的日志服务器、数据库和消息队列
  • 使用上下文信息对日志事件进行复杂的丰富,包括范围 ( LogContext) 属性、线程和进程标识符以及特定于域的相关 ID,例如HttpRequestId
  • 零共享状态Logger对象,具有可选的全局静态Log类
  • LogEvent格式不可知的日志管道,可以以纯文本、JSON、内存对象(包括Rx 管道)和其他格式发出事件

入门

Serilog 是从 NuGet 安装的。要查看日志事件,还需要安装一个或多个接收器,这里我们将使用漂亮打印控制台接收器和滚动文件集:

dotnet add package Serilog
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File

设置 Serilog 的最简单方法是使用静态Log类。ALoggerConfiguration用于创建和分配默认记录器。

using Serilog;

public class Program
{
public static void Main()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File("log.txt",
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true)
.CreateLogger(); Log.Information("Hello, Serilog!"); Log.CloseAndFlush();
}
}

如被动接受设备数据:

var deviceValue = $"dmv:{dmon.Uid},Value:{dmon.Value},Status:{dmon.Status},BoxNo:{dmon.BoxNo},Name:{dmon.Name},BoxId:{dmon.BoxId},GroupName:{dmon.GroupName},Timestamp:{dmon.Timestamp}";
Log.Information(deviceValue);

 

实践,从 NuGet 安装 Serilog

核心的包是 Serilog 和 Serilog.AspNetCore
建议安装 Serilog.AspNetCore,几乎包含了Serilog常用的所有包
异步写入 Serilog.Sinks.Async
写入MSSQL  Serilog.Sinks.MSSqlServer

Install-Package Serilog.AspNetCore
Install-Package Serilog
Install-Package Serilog.Sinks.Async
Install-Package Serilog.Sinks.MSSqlServer

日志输出

输出到控制台

 1 using Serilog;
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.IO;
6 using System.Linq;
7
8 namespace NetCoreConsoleApp
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 Log.Logger = new LoggerConfiguration()
15 .WriteTo.Console() //输出到控制台
16 .CreateLogger();
17
18 Log.Information("log");
19
20 }
21
22
23 }
24 }

输出到本地日志文件

WriteTo.File详解(日志默认路径为当前程序路径)

path:默认路径是程序的bin目录+path参数,当然也可以写绝对路径,只需要写入参数就可以了
     rollingInterval:创建文件的类别,可以是分钟,小时,天,月。 此参数可以让创建的log文件名默认 + 时间。例如:log20191219.log
     outputTemplate:日志模板,可以自定义
     retainedFileCountLimit:设置日志文件个数最大值,默认31,意思就是只保留最近的31个日志文件,等于null时永远保留文件

 1 using Serilog;
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.IO;
6 using System.Linq;
7
8 namespace NetCoreConsoleApp
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 /*
15 WriteTo.File详解
16 path:默认路径是程序的bin目录+path参数,当然也可以写绝对路径,只需要写入参数就可以了
17 rollingInterval:创建文件的类别,可以是分钟,小时,天,月。 此参数可以让创建的log文件名 + 时间。例如log20191219.log
18 outputTemplate:日志模板,可以自定义
19 retainedFileCountLimit:设置日志文件个数最大值,默认31,意思就是只保留最近的31个日志文件,等于null时永远保留文件
20 */
21
22
23 string SerilogOutputTemplate = "{NewLine}{NewLine}Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}LogLevel:{Level}{NewLine}Message:{Message}{NewLine}{Exception}" + new string('-', 100);
24
25 Log.Logger = new LoggerConfiguration()
26 .MinimumLevel.Debug() // 所有Sink的最小记录级别
27 .WriteTo.Console() //输出到控制台
28 .WriteTo.File("00_Logs\\log.log", //$"{AppContext.BaseDirectory}00_Logs\log.log"
29 rollingInterval: RollingInterval.Day,
30 outputTemplate: SerilogOutputTemplate
31 //,retainedFileCountLimit: 31
32 )
33 .CreateLogger();
34 Log.Information("log");
35 }
36 }
37 }

输出到本地日志文件(异步)

需要Serilog.Sinks.Async包,github详解路径:https://github.com/serilog/serilog-sinks-async

 1 using Serilog;
2
3 namespace NetCoreConsoleApp
4 {
5 class Program
6 {
7 static void Main(string[] args)
8 {
9 //github详解路径:https://github.com/serilog/serilog-sinks-async
10
11 Log.Logger = new LoggerConfiguration()
12 .WriteTo.Async(a => a.File("00_Logs\\log.log", rollingInterval: RollingInterval.Day))
13 .CreateLogger();
14 Log.Information("log");
15 Log.CloseAndFlush();
16 }
17 }
18 }

不同的日志级别输出到不同的文件夹下

using Serilog;
using Serilog.Events;
using System; namespace NetCoreConsoleApp
{
class Program
{
static void Main(string[] args)
{
string LogFilePath(string LogEvent) => $@"{AppContext.BaseDirectory}00_Logs\{LogEvent}\log.log";
string SerilogOutputTemplate = "{NewLine}{NewLine}Date:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}LogLevel:{Level}{NewLine}Message:{Message}{NewLine}{Exception}" + new string('-', 50); Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Console()
.MinimumLevel.Debug() // 所有Sink的最小记录级别
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Debug).WriteTo.File(LogFilePath("Debug"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Information).WriteTo.File(LogFilePath("Information"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Warning).WriteTo.File(LogFilePath("Warning"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Error).WriteTo.File(LogFilePath("Error"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Fatal).WriteTo.File(LogFilePath("Fatal"), rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate))
.CreateLogger(); Log.Information("log");
Log.Error("log");
}
}
}

输出到MSSQL

需要Serilog.Sinks.MSSqlServer包,github详解路径:https://github.com/serilog/serilog-sinks-mssqlserver

参考链接:https://www.cnblogs.com/lonelyxmas/p/11980881.html

using Serilog;
using Serilog.Events;
using Serilog.Sinks.MSSqlServer;
using System;
using System.Collections.ObjectModel;
using System.Data; namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{ string connectionString = @"Server=....";string tableNameA = "LogsA";
string tableNameB = "LogsB";
string tableNameC = "LogsC";
static void Write()
{
Log.Information("测试信息");
Log.Error("Error");
Log.Write(LogEventLevel.Error, new Exception("错误"), "致命错误");
}; //A:默认配置
//autoCreateSqlTable为true 时 会自动创建日志表
Log.Logger = new LoggerConfiguration().WriteTo.MSSqlServer(connectionString, tableNameA, autoCreateSqlTable: true).CreateLogger();
Write(); //B:移除列
var options = new ColumnOptions();
options.Store.Remove(StandardColumn.Properties);
options.Store.Remove(StandardColumn.MessageTemplate);
Log.Logger = new LoggerConfiguration()
.WriteTo.MSSqlServer(connectionString, tableNameB, columnOptions: options, autoCreateSqlTable: true)
.CreateLogger();
Write(); //C:添加自定义列
options = new ColumnOptions();
options.AdditionalColumns = new Collection<SqlColumn>
{
new SqlColumn { DataType = SqlDbType.NVarChar, DataLength =-1, ColumnName = "IP" },
new SqlColumn { DataType = SqlDbType.NVarChar, DataLength =-1, ColumnName = "IP2" }
};
Log.Logger = new LoggerConfiguration()
.Enrich.WithProperty("IP", "8.8.8.8")
.Enrich.WithProperty("IP2", "9.9.9.9")
.WriteTo.MSSqlServer(connectionString, tableNameC, columnOptions: options, autoCreateSqlTable: true)
.CreateLogger();
Write(); Console.WriteLine("Hello World!");
Console.ReadKey(); }
}
}

ASP.NET Core 中使用 Serilog

参考链接:https://www.cnblogs.com/MaleDeer/p/10797509.html

在Program.cs程序启动时注入Serilog 加载配置

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Serilog; namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{ Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File($"{AppContext.BaseDirectory}00_Logs\\log.log", rollingInterval: RollingInterval.Day)
.CreateLogger(); try
{
Log.Information("Starting up");
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Application start-up failed");
}
finally
{
Log.CloseAndFlush();
}
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog();
}
}

或者

using System;using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Serilog; namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseSerilog((hostingContext, loggerConfiguration) =>
{
loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.File($"{AppContext.BaseDirectory}00_Logs\\log.log", rollingInterval: RollingInterval.Day)
.WriteTo.Console();
});
});
}
}

使用 Serilog 时,直接使用 ILogger 即可,因为此服务项目应该是默认注入了,此处需要依赖关系注入知识。如你不了解依赖关系注入,请看 微软官方文档。

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; namespace WebApplication1.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ILogger<ValuesController> _logger; public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
} // GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
_logger.LogInformation("test info");
return new string[] { "value1", "value2" };
}
}
}

相关链接

 
鸣谢:
https://www.cnblogs.com/RainFate/p/12073662.html
  

.net core 序列日志Serilog的更多相关文章

  1. 如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出

    这是该系列的第一篇文章:在ASP.NET Core 3.0中使用Serilog.AspNetCore. 第1部分-使用Serilog RequestLogging来简化ASP.NET Core的日志输 ...

  2. .NET Core集成Seq+Serilog实现日志中心

    .NET Core集成Seq+Serilog实现日志中心 一,下载安装Seq https://datalust.co/download/all,版本很多,大家随便挑,开发版个人免费,商业版多账号需要收 ...

  3. .NET Core的日志[2]:将日志输出到控制台

    对于一个控制台应用,比如采用控制台应用作为宿主的ASP.NET Core应用,我们可以将记录的日志直接输出到控制台上.针对控制台的Logger是一个类型为ConsoleLogger的对象,Consol ...

  4. .NET Core的日志[1]:采用统一的模式记录日志

    记录各种级别的日志是所有应用不可或缺的功能.关于日志记录的实现,我们有太多第三方框架可供选择,比如Log4Net.NLog.Loggr和Serilog 等,当然我们还可以选择微软原生的诊断框架(相关A ...

  5. .Net core的日志系统

    .net core是内置了日志系统的,本文这里简单的介绍一下它的基本用法.如下是一个简单的示例: var service = new ServiceCollection() .AddLogging(l ...

  6. 如何在 ASP.Net Core 中使用 Serilog

    记录日志的一个作用就是方便对应用程序进行跟踪和排错调查,在实际应用上都是引入 日志框架,但如果你的 日志文件 包含非结构化的数据,那么查询起来将是一个噩梦,所以需要在记录日志的时候采用结构化方式. 将 ...

  7. .NET Core的日志[5]:利用TraceSource写日志

    从微软推出第一个版本的.NET Framework的时候,就在“System.Diagnostics”命名空间中提供了Debug和Trace两个类帮助我们完成针对调试和跟踪信息的日志记录.在.NET ...

  8. .NET Core的日志[4]:将日志写入EventLog

    面向Windows的编程人员应该不会对Event Log感到陌生,以至于很多人提到日志,首先想到的就是EventLog.EventLog不仅仅记录了Windows系统自身针对各种事件的日志,我们的应用 ...

  9. .NET Core的日志[3]:将日志写入Debug窗口

    定义在NuGet包"Microsoft.Extensions.Logging.Debug"中的DebugLogger会直接调用Debug的WriteLine方法来写入分发给它的日志 ...

  10. .NET Core开发日志——Entity Framework与PostgreSQL

    Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以Po ...

随机推荐

  1. C# 学习async/await(个人理解)

    await : 等待的意思 async:异步(非同步) 当我们方法内部   存在await的时候,就返回出去 执行下一步 ,等await后面的方法执行完毕 在执行await下面的方法 一.我们先看正常 ...

  2. Redis-05持久化

    1 Redis持久化 RDB(Redis DataBase) AOF(Append Only File) 2 RBD 2.1 基本说明 在指定的时间间隔内将内存中的数据集快照写入磁盘文件,它恢复时将快 ...

  3. C++练习5 对引用进行初始化

    1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 const int cInt = 3;//定义常量cInt并 ...

  4. Unreal 各种指针类型是怎么回事

    引言 读完本篇文章,你会了解为何UE中C++作为其开发语言,使用的指针,为何各式各样. 你需要对UE有所了解,如果不了解也没关系,也可以看下这篇文章,就当了解一下最复杂的应用的系统指针设计是如何. 可 ...

  5. 基于jib-maven-plugin快速构建微服务docker镜像

    一.说明 本文介绍基于 Maven 插件 jib-maven-plugin 实现快速构建 Spring Boot 程序镜像,并推送到远程仓库中,且 无需安装 Docker 环境 . Jib 是 Goo ...

  6. Nginx基础02:配置文件nginx.conf(Part1)

    我们使用Nginx主要是通过其配置文件nginx.conf来实现的.按照一定的规则,编写特定的指令,可以帮助我们实现对Web服务的控制!所以,学习Nginx的用法,几乎就是学习nginx.conf! ...

  7. CF1781D 解题乱弹

    abc1057510554 老师说,搞这种数论题,就可以在 CF 上 number theory 板刷一个 1300-1900 就可以了. 然后发现连 1800 的题都做不出来,我可以退役力 QAQ ...

  8. CyNix: 1

    CyNix: 1 目录 CyNix: 1 1 信息收集 1.1 端口扫描 1.2 后台目录扫描 1.2.1 目录分析 2 GetShell 2.1 赋予id_rsa文件600权限,否则会报错,无法连接 ...

  9. 下载、编译AspNetCore 的全过程

    1. clone 源码 下载新的 git clone --recursive https://github.com/dotnet/aspnetcore 如果之前clone过,但是没有使用 --recu ...

  10. MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(3)-系统数据集合设计

    前言 前几章教程我们把ToDoList系统的基本框架搭建好了,现在我们需要根据我们的需求把ToDoList系统所需要的系统集合(相当于关系型数据库中的数据库表).接下来我们先简单概述一下这个系统主要需 ...