Serilog - 集成到 .NET 应用程序的优秀日志框架
Serilog 是一个可移植的结构化日志框架,用于将诊断日志记录到文件、控制台和 SQL/NoSQL 数据库。
引言
日志记录是一种记录程序执行信息以进行调试和跟踪的方法。日志记录通常涉及将文本消息写入日志文件或将数据发送到监视应用程序。记录的信息让您能够很好地了解已处理的数据、警告、错误等。在实践中,日志记录使开发人员和测试人员能够识别软件问题、监视实时系统并验证输出。
在 .NET 平台上,有多种成熟的日志框架,例如
- Log4Net(https://logging.apache.ac.cn/log4net/)
- nLog(http://nlog-project.org/)
- CommonLogging(http://netcommon.sourceforge.net/)
- ObjectGuy(http://www.theobjectguy.com/dotnetlog/)
- ELMAH(https://code.google.com/p/elmah/)
它们旨在简化开发人员在处理日志方面的工作。所有日志框架的工作原理基本相同:您将其中一个库包含在程序中,并在代码中添加日志记录语句。如果您的应用程序启动并启用了日志记录,日志信息将被发送到配置的日志目标,如日志文件、控制台或数据库。
Serilog 是一个优秀的日志框架,已活跃多年。与其他 .NET 日志库不同,Serilog 是围绕结构化日志数据构建的。该框架的核心思想是日志消息不仅仅是一组 string
。日志消息被保留为结构化数据(JSON),可以以文档形式写入各种输出提供程序。
Serilog 的结构
特点
- 简单的 API,易于扩展
- 结构化数据,以保留数据的语义
- 记录到多种目标
概述
在我们开始之前,让我们快速了解一下将 Serilog 应用于项目是多么容易。请参阅下面的示例
- 基本记录器
using Serilog; namespace SerilogTutorial { public class HelloSerilog { public static void Main(string[] args) { // Create Logger var logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); // Output logs logger.Information("Hello, Serilog!"); } } }
此示例将类似以下的行写入控制台。
2015-10-19 15:39:06 [Information] Hello, Serilog!
- 将参数传递给记录器
// Create Logger var logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); // write structured data logger.Information("Processed {Number} records in {Time} ms", 500, 120);
它写入类似以下的行
2015-10-19 22:24:09 [Information] Processed 500 records in 120 ms
- 创建模板记录器
// Create Logger var logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); // prepare data var order = new {Id = 12, Total = 128.50, CustomerId = 72}; var customer = new {Id = 72, Name = "John Smith"}; // write log message logger.Information("New orders {OrderId} by {Customer}", order.Id, customer);
它打印如下日志
2015-10-19 22:32:43 [Information] New orders 12 by "{ Id = 72, Name = John Smith }"
正如我们所见,Serilog 的强大之处在于它支持处理消息参数和结构化数据。虽然传统的日志库将消息渲染为 string
,但 Serilog 推迟渲染,并将参数与消息模板分开捕获。
Using the Code
现在,让我们深入了解如何将 Serilog 应用于您的项目。以下是基本步骤
- 准备工作
- 安装 Serilog
- 创建记录器
- 配置记录器
- 添加接收器
- 写入日志消息
- 自定义记录器
- 定义日志输出模板
- 指定最小级别
- 安装数据库接收器
准备工作
当然,您需要安装 Visual Studio 并准备好项目。为简化起见,您只需创建一个控制台应用程序。
安装 Serilog
通常,有两种方法可以安装 nuget 包。
方法 1 - 通过 Nuget 包管理器
右键单击您的项目 > 管理 nuget 包 > 搜索 serilog
方法 2 - 通过项目管理器控制台
转到菜单 > 工具 > NuGet 包管理器 > 项目管理器控制台
PM> Install-Package Serilog
创建记录器
记录器是编写日志的基础,用于输出日志消息。要创建记录器,您需要指定两个设置。
配置记录器
您需要创建一个 LoggerConfiguration
对象
添加接收器
接收器是处理日志的地点或目标。接收器可以是控制台、文件或数据存储。接收器使用 WriteTo()
方法进行配置。
现在,您可以构建一个记录器以将事件写入 Console
var logger = = new LoggerConfiguration()
.WriteTo.ColoredConsole()
.CreateLogger();
可以通过链接 WriteTo
方法添加多个额外的接收器
var logger = new LoggerConfiguration()
.WriteTo.ColoredConsole()
.WriteTo.RollingFile(@"C:\Log-{Date}.txt")
.CreateLogger();
写入日志消息
现在记录器已准备就绪。您可以像这样简单地写入日志
log.Debug("Debugging message");
log.Information("Information message");
log.Warning("Warning message");
log.Error("Error message");
log.Fatal("Fatal message");
自定义记录器
为了修改记录器以满足您的需求,您需要调整记录器。
定义日志输出模板
日志消息模板控制接收器如何渲染事件。消息模板是标准 .NET 格式字符串的超集,并且与 string.Format()
方法兼容。此外,它支持 JSON 对象或常规 C# 对象(使用 @
符号)作为参数。
var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;
log.Information("Processed {@Position} in {Elapsed} ms.", position, elapsedMs);
它打印如下日志
09:14:22 [Information] Processed { Latitude: 25, Longitude: 134 } in 34 ms.
指定最小级别
有五个日志级别
信号强度 | 用法 |
Verbose(详细) | 跟踪信息和调试细节;通常仅在特殊情况下启用 |
Debug | 内部控制流和诊断状态转储,以帮助精确定位已识别的问题 |
信息 | 对外部观察者感兴趣或具有相关性的事件;默认启用的最低日志记录级别 |
警告 | 指示潜在问题或服务/功能降级的迹象 |
Error(错误) | 指示应用程序或连接系统内的失败 |
Fatal(致命) | 导致应用程序完全失败的严重错误 |
Serilog 会写入具有最小级别的日志以及更高,并忽略较低级别。例如,指定最小级别为 Debug 将输出除 Verbose 之外的所有日志。
var logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.ColoredConsole()
.CreateLogger();
您还可以覆盖最小级别。例如,我们希望在控制台中显示所有高于 Debug 的日志,但将所有错误日志保存到数据库。为了满足此要求,您可以将全局级别指定为 Debug,并将数据库接收器设置为 Warning 级别。
var logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.ColoredConsole()
.WriteTo.MongoDB("mongo://myserver/logs", minimumLevel: LogEventLevel.Warning)
.CreateLogger();
logger.Information("I am an information log"); // will print in console
log.Error("I am an error log");// will print in console and also store in database
将错误级别日志事件写入文件
var logger = new LoggerConfiguration()
.WriteTo.File("log.txt", LogEventLevel.Error)
.CreateLogger();
logger.Information("I am an information log"); // will not in log file
logger.Error("I am an error log"); // will write to log file
如果未指定 MinimumLevel
,Serilog 将默认使用 Information 级别事件 - Information 及更高级别将被处理。
安装数据库接收器
Serilog 支持内置接收器,包括 Console、File(单个/滚动)和 TextWriter
。为了使 Serilog 能够将日志导出到不同的目标,需要安装其他接收器。
一个典型的情况是将日志写入数据库,您需要安装额外的接收器。例如,使用 SQL Server 数据库作为目标需要安装 SQL Server 接收器。
PM> Install-Package Serilog.Sinks.MSSqlServer
使用 SQL 脚本创建数据库 LogEvents
和表 Logs
if not exists(select * from sys.databases where name='LogEvents')
create database LogEvents;
Go
Use LogEvents;
Go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Logs](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Message] [nvarchar](max) NULL,
[MessageTemplate] [nvarchar](max) NULL,
[Level] [nvarchar](128) NULL,
[TimeStamp] [datetime] NOT NULL,
[Exception] [nvarchar](max) NULL,
[Properties] [xml] NULL,
CONSTRAINT [PK_Logs] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, _
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
该脚本将创建 LogEvents
数据库和 Logs
表
写入 SQL Server 数据库接收器
var logger = new LoggerConfiguration()
.WriteTo.MSSqlServer(@"Server=.;Database=LogEvents;
Trusted_Connection=True;", "Logs")
.CreateLogger();
logger.Information("I am an information log");
logger.Error("Hello, I am an error log");
您将得到:
更多
本文仅涵盖 Serilog 的基本概念。更高级的功能可以在 此处找到。高级主题包括
- 通过 Enricher 添加动态属性
- 添加日志过滤器以过滤掉嘈杂的事件并选择特定的日志
- 添加子记录器以处理复杂的日志记录要求
- 更多接收器,如 MongoDB、Seq、RavenDB、Email 和 Azure DocumentDB。完整列表可以在 此处找到。
历史
- 2015 年 10 月 20 日:发布第一个版本
- 2015 年 10 月 20 日:修正格式