.Net Core 3.0 使用 Serilog 把日志记录到 SqlServer
Serilog简介
Serilog是.net中的诊断日志库,可以在所有的.net平台上面运行。Serilog支持结构化日志记录,对复杂、分布式、异步应用程序的支持非常出色。Serilog可以通过插件的方式把日志写入到各种终端,控制台、文本、Sqlserver、ElasticSearch,Serilog支持终端的列表:https://github.com/serilog/serilog/wiki/Provided-Sinks 。
Serilog日志写入SqlServer
一、Sink LoggerConfiguration
connectionString 数据库连接字符串schemaName 数据库所有者,默认dbotableName 记录日志的表名autoCreateSqlTable 是否自动创建表,如果设置为ture,则在Serilog启动时检测数据库是否有对应的表,没有则创建columnOptions 日志表中的列定义restrictedToMinimumLevel 记录日志的最小levelbatchPostingLimit 单次批量处理中提交的最大日志数量period 进行批量提交的间隔formatProvider 提供特定的格式化处理,https://github.com/serilog/serilog/wiki/Formatting-Output#format-providers
Serilog为我们定义了一套标准列,默认情况下会生成如下列,当然我们也可以自定义列
StandardColumn.Id 自增IdStandardColumn.Message 日志内容StandardColumn.MessageTemplate 日志模板StandardColumn.Level 等级StandardColumn.TimeStamp 记录时间StandardColumn.Exception 异常信息StandardColumn.Properties 日志事件属性值
删除标准列:
columnOptions.Store.Remove(StandardColumn.MessageTemplate);
添加自定义列:
columnOptions.AdditionalColumns = new Collection<SqlColumn>
{
new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = , ColumnName = "IP" }
};
完整LoggerConfiguration示例如下:
var columnOptions = new ColumnOptions();
columnOptions.Store.Remove(StandardColumn.MessageTemplate);//删除标准列
columnOptions.Properties.ExcludeAdditionalProperties = true;//排除已经自定义列的数据
columnOptions.AdditionalColumns = new Collection<SqlColumn>//添加自定义列
{
new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = , ColumnName = "IP" }
}; Log.Logger = new LoggerConfiguration()
.WriteTo.MSSqlServer(
connectionString: Configuration["Serilog:ConnectionString"],
tableName: Configuration["Serilog:TableName"],
batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入数据库条数
period: TimeSpan.FromSeconds(),//执行时间间隔
restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"),
columnOptions: columnOptions,
autoCreateSqlTable: true
).CreateLogger();
上面的配置也可以全部从配置文件读取:
{
"Serilog": {
"Using": [ "Serilog.Sinks.MSSqlServer" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "NamedConnectionString",
"schemaName": "EventLogging",
"tableName": "Logs",
"autoCreateSqlTable": true,
"restrictedToMinimumLevel": "Warning",
"batchPostingLimit": ,
"period": "0.00:00:30",
"columnOptionsSection": {
"disableTriggers": true,
"clusteredColumnstoreIndex": false,
"primaryKeyColumnName": "Id",
"addStandardColumns": [ "LogEvent" ],
"removeStandardColumns": [ "MessageTemplate"],
"additionalColumns": [
{
"ColumnName": "IP",
"DataType": "varchar",
"DataLength":
}
],
"id": { "nonClusteredIndex": true },
"properties": {
"columnName": "Properties",
"excludeAdditionalProperties": true,
"dictionaryElementName": "dict",
"itemElementName": "item",
"omitDictionaryContainerElement": false,
"omitSequenceContainerElement": false,
"omitStructureContainerElement": false,
"omitElementIfEmpty": true,
"propertyElementName": "prop",
"rootElementName": "root",
"sequenceElementName": "seq",
"structureElementName": "struct",
"usePropertyKeyAsElementName": false
},
"timeStamp": {
"columnName": "Timestamp",
"convertToUtc": true
},
"logEvent": {
"excludeAdditionalProperties": true,
"excludeStandardColumns": true
},
"message": { "columnName": "message" },
"exception": { "columnName": "exception" }
}
}
}
]
}
}
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration["Serilog"]);//需要引用Microsoft.Extensions.Configuration
二、Logger使用
1、直接使用Serilog提供的静态类Log
Log.Information(“message”);
2、使用serilog-extensions-logging 替换.net core默认日志Microsoft.Extensions.Logging,注入Serilog
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.CaptureStartupErrors(true)//捕捉启动异常
.UseSetting("detailedErrors", "true")//指定程序应用程序会显示详细的启动错误信息
.UseStartup<Startup>()
.ConfigureLogging(builder =>
{
builder.ClearProviders();
builder.AddSerilog();
});
});
private readonly ILogger logger; public TestController(ILogger<TestController> logger)
{
this.logger = logger;
} logger.Information("Message")
三、怎么把数据写入自定义列
Serilog并没有提供 Log.Debug(Message,IP)方法,在我们日常开发中可能会有如下几种需求:
1、设置全局Property
例如我需要记录当前程序服务器的ip,或者我需要记录当前服务的名称,需要一个共用的字段。那么我们可以在LoggerConfiguration的时候设置一个全局的Property,即在相同的LoggerConfiguration下面每条日志都可以共用,我们可以这样配置
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("IP", GetIP())
.WriteTo.MSSqlServer(
connectionString: Configuration["Serilog:ConnectionString"],
tableName: Configuration["Serilog:TableName"],
batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入数据库条数
period: TimeSpan.FromSeconds(),//执行时间间隔
restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"),
columnOptions: columnOptions,
autoCreateSqlTable: true
).CreateLogger();
2、设置ForContext写入Property
例如我需要记录当前类,需要在记录日志的时候设置ForContext
Log.ForContext("Calss", GetType().FullName).Information("message");
这里只是一个例子,其实serilog已经自动帮我们记录了Calss的信息,在Properties中可以找到SourceContext节点,里面就记录了相关的命名空间和类
四、对日志进行过滤
如果系统日志太多,我们很难快速找到有用的信息,所以很多时候我们会对日志进行过滤
1、通过MinimumLevel进行过滤
设置MinimumLevel的等级进行过滤,Serilog中Level有Verbose,Debug,Information,Warning,Error,Fatal几个等级,Serilog只记录当前等级及比当前等级高的日志。
2、通过Override进行过滤
原理是serilog会记录SourceContext,里面包含了命名空间和类的信息,这里我们把SourceContext包含“Microsoft”的信息过滤掉,只记录Error及Error级别以上的信息,配置如下:
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("IP", GetIP())
.MinimumLevel.Override("Microsoft", LogEventLevel.Error)
.WriteTo.MSSqlServer(
connectionString: Configuration["Serilog:ConnectionString"],
tableName: Configuration["Serilog:TableName"],
batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入数据库条数
period: TimeSpan.FromSeconds(),//执行时间间隔
restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"),
columnOptions: columnOptions,
autoCreateSqlTable: true
).CreateLogger();
3、通过Filter进行过滤
通过Filter可以过滤Properties中的值,比如一般我们会对数据库的错误比较重视,希望把数据库错误单独放在一个表中,这时需要用到Filter,我们把SourceContext中包含数据访问层命名空间的信息提取出来
string namespace = "DAL";//数据访问层命名空间 Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("IP", GetIP())
.MinimumLevel.Override("Microsoft", LogEventLevel.Error)
.WriteTo.Logger(lc => lc.Filter.ByIncludingOnly(Matching.WithProperty(namespace))
.WriteTo.MSSqlServer(
connectionString: Configuration["Serilog:ConnectionString"],
tableName: Configuration["Serilog:DBErrorTableName"],
batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入数据库条数
period: TimeSpan.FromSeconds(),//执行时间间隔
columnOptions: columnOptions,
autoCreateSqlTable: true))
.WriteTo.Logger(lc => lc.Filter.ByExcluding(Matching.WithProperty(namespace))
.WriteTo.MSSqlServer(
connectionString: Configuration["Serilog:ConnectionString"],
tableName: Configuration["Serilog:DefaultTableName"],
batchPostingLimit: Configuration.GetValue<int>("Serilog:BatchPostingLimit"),//批量插入数据库条数
period: TimeSpan.FromSeconds(),//执行时间间隔
columnOptions: columnOptions,
autoCreateSqlTable: true))
.CreateLogger();
五、Enricher
Enricher 的作用主要是增加记录的信息,比如Enrich.WithThreadId(),可以记录线程信息,Enrich.WithProperty()可以增加属性信息
自定义Enricher 可以参数这篇文章:https://www.cnblogs.com/weihanli/p/custom-serilog-enricher-to-record-more-info.html
参考资料
https://github.com/serilog/serilog
https://www.cnblogs.com/Leo_wl/p/7643400.html
https://www.cnblogs.com/Leo_wl/p/10943285.html
.Net Core 3.0 使用 Serilog 把日志记录到 SqlServer的更多相关文章
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
EF Core使用SQL调用返回其他类型的查询 假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...
- ASP.NET Core 2.0 使用NLog实现日志记录
1.安装NuGet包 1.Install-Package NLog.Web.AspNetCore 2.Install-Package NLog 在csproj中编辑: <PackageRefer ...
- 如何从Serilog请求日志记录中排除健康检查终结点
这是在ASP.NET Core 3.X中使用Serilog.AspNetCore系列文章的第四篇文章:. 第1部分-使用Serilog RequestLogging减少日志详细程度 第2部分-使用Se ...
- ASP.NET Core 1.0 中使用 Log 日志配置
https://github.com/aspnet/Logging https://docs.asp.net/en/latest/fundamentals/logging.html ASP.NET C ...
- 在 ASP.NET Core 中使用 Serilog 进行日志记录
目录 从 NuGet 安装 Serilog 在 Main函数 中配置 Serilog 在项目中使用 Serilog 进行日志输出 从 NuGet 安装 Serilog 核心的包是 Serilog 和 ...
- ASP.NET Core 2.0系列学习笔记-NLog日志配置文件
一.新建ASP.NET Core 2.0 MVC项目,使用NuGet在浏览中搜索:NLog.Web.AspNetCore,如下图所示: 二.在项目的根目录下新建一个xml类型的nlog.config文 ...
- .net core 2.0使用NLog写日志文件
原文地址:传送门 之前也看了 linezero 大佬写的教程,但是总是没有成功写入日志文件.按照 曲廉卿 的已成功,以下正文: 最近研究了一下NLog的使用方式,简单的入了一下门. 实现的功能,对于不 ...
- .Net Core中间件和过滤器实现错误日志记录
1.中间件的概念 ASP.NET Core的处理流程是一个管道,中间件是组装到应用程序管道中用来处理请求和响应的组件. 每个中间件可以: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的下 ...
- .NET Worker Service 添加 Serilog 日志记录
前面我们了解了 .NET Worker Service 的入门知识[1] 和 如何优雅退出 Worker Service [2],今天我们接着介绍一下如何为 Worker Service 添加 Ser ...
随机推荐
- ICollection IEnumerable/IEnumerator IDictionaryEnumerator yield
Enumerable和IEnumerator接口是.NET中非常重要的接口,二者区别: 1. IEnumerable是个声明式的接口,声明实现该接口的类就是“可迭代的enumerable”,但并没用说 ...
- IDAE 将外部jar打入本地maven仓库
方式1:dependency 本地jar包 <dependency> <groupId>com.hope.cloud</groupId> <!--自定义--& ...
- python:将网页图片保存到本地
1.requests库介绍 在python中,有一个非常好用的网络请求库requests,使用它可以发起网络请求,并获取网页返回的内容.同时,也可以进行网页图片下载 requests是使用Apache ...
- Idea导入Web项目并发布到Tomcat
Idea导入现有的Web项目并发布到Tomcat,发现Tomcat没有自动发布 问题: 导入一个Web项目时,idea并没有把他当成web,所以需要自己修改项目结构 1.导入项目 打开 File-&g ...
- Java 8 - 行为参数化
前言: 以下内容来源于java8实战一书,我将里面学习的内容做一个整理,方便没空读书的小伙伴快速入门实战java8 正文: 假设一个果农收获了一园的苹果,他需要你根据他的条件筛选出满意的苹果 首先我们 ...
- mock和axios常见的传参方式
第一次接手项目,传参方式还有些吃力,因此做一下总结. 首先我们需要会看swagger中的接口.里面写了某个接口需要接收什么样的值,前端怎么传递这个值 在mock中的传参方式: mock中传参的方式有两 ...
- vue cli 4.0.5 的使用
vue cli 4.0.5 的使用 现在的 vue 脚手架已经升级到4.0的版本了,前两日vue 刚发布了3.0版本,我看了一下cli 4 和cli 3 没什么区别,既然这样,就只总结一下vue cl ...
- 【java基础】为什么重写toString()方法?
不得不说,有很多java初学者写java实体类的时候,并没有真正理解重写toString() 方法,可能是口头知道也可能是跟风随带添加toString() 方法,并没有真正理解其意义,如果真要被问起来 ...
- vue学习之插槽
插槽 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性. 个人理解:我感觉插槽就是父组件控制插槽 ...
- NOIp2017 列队(线段树)
嘛..两年前的题目了,想起第一次参加提高组还骗了一个省二回来呢...跟同学吹了好久的... 离退役又近了一骗博客啊.. 闲聊结束. 照常化简:给定一个1-n*m编号的矩阵,每次删除一个位置,然后左边向 ...