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,具有熟悉的级别,如DebugInformationWarningError
  • 可发现的 C# 配置语法和可选的XMLJSON配置支持
  • 启用时高效,关闭日志记录级别时开销极低
  • 一流的 .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. socket模块实现网络编程及struct模块解决黏包问题

    目录 一.socket模块 1.简介 2.基于文件类型的套接字家族 3.基于网络类型的套接字家族 二.socket代码简介 三.socket代码优化 1.聊天内容自定义 2.让聊天循环起来 3.用户输 ...

  2. ResponseBodyAdvice处理返回数据

    package com.xf.config; import org.slf4j.MDC; import org.springframework.core.MethodParameter; import ...

  3. 一种无损更换iPhone手机铃声方案(无需数据线)

    iPhone用户手机铃声更换的方案,现在网上已经很多方法,包括使用某思助手.通过iTunes等进行更换,后者现在在MacOS系统中已经不支持.注意️:此文章针对与MacOS系统与IOS搭配使用.Win ...

  4. elasticsearch之日期类型有点怪

    一.Date类型简介 elasticsearch通过JSON格式来承载数据的,而JSON中是没有Date对应的数据类型的,但是elasticsearch可以通过以下三种方式处理JSON承载的Date数 ...

  5. K3S 系列文章-5G IoT 网关设备 POD 访问报错 DNS 'i/o timeout'分析与解决

    开篇 <K3s 系列文章> <Rancher 系列文章> 问题概述 20220606 5G IoT 网关设备同时安装 K3S Server, 但是 POD 却无法访问互联网地址 ...

  6. K8S发布应用步骤详解

    前言 首先以SpringBoot应用为例介绍一下k8s的发布步骤. 1.从代码仓库下载代码,比如GitLab: 2.接着是进行打包,比如使用Maven: 3.编写Dockerfile文件,把步骤2产生 ...

  7. 钓鱼攻击之:Flash 网页钓鱼

    钓鱼攻击之:Flash 网页钓鱼 目录 钓鱼攻击之:Flash 网页钓鱼 1 准备资料 2 具体钓鱼流程 3 生成后门并捆绑flash的安装程序 4 处理WEB站点过程 1 准备资料 Flash网站克 ...

  8. Vulhub 漏洞学习之:Couchdb

    Vulhub 漏洞学习之:Couchdb 目录 Vulhub 漏洞学习之:Couchdb 1 Couchdb 垂直权限绕过漏洞(CVE-2017-12635) 1.1 漏洞利用过程 2 Couchdb ...

  9. LeetCode-688 骑士在棋盘上的概率

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/knight-probability-in-chessboard 题目描述 在一个 n x n 的 ...

  10. pat乙级1022 D进制的A+B

    #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #de ...