.Net Core 3.0 使用 Serilog 把日志记录到 SqlServer

Serilog简介

Serilog是.net中的诊断日志库,能够在全部的.net平台上面运行。Serilog支持结构化日志记录,对复杂、分布式、异步应用程序的支持很是出色。Serilog能够经过插件的方式把日志写入到各类终端,控制台、文本、Sqlserver、ElasticSearch,Serilog支持终端的列表:https://github.com/serilog/serilog/wiki/Provided-Sinks 。html

Serilog日志写入SqlServer

1、Sink LoggerConfiguration

  • connectionString  数据库链接字符串
  • schemaName  数据库全部者,默认dbo
  • tableName  记录日志的表名 
  • autoCreateSqlTable  是否自动建立表,若是设置为ture,则在Serilog启动时检测数据库是否有对应的表,没有则建立 
  • columnOptions  日志表中的列定义
  • restrictedToMinimumLevel  记录日志的最小level 
  • batchPostingLimit  单次批量处理中提交的最大日志数量
  • period  进行批量提交的间隔
  • formatProvider 提供特定的格式化处理,https://github.com/serilog/serilog/wiki/Formatting-Output#format-providers

Serilog为咱们定义了一套标准列,默认状况下会生成以下列,固然咱们也能够自定义列git

  • StandardColumn.Id  自增Id 
  • StandardColumn.Message  日志内容 
  • StandardColumn.MessageTemplate 日志模板
  • StandardColumn.Level  等级 
  • StandardColumn.TimeStamp  记录时间
  • StandardColumn.Exception  异常信息
  • StandardColumn.Properties 日志事件属性值

删除标准列:github

columnOptions.Store.Remove(StandardColumn.MessageTemplate);

添加自定义列:web

columnOptions.AdditionalColumns = new Collection<SqlColumn> { new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 32, 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 = 32, 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(5),//执行时间间隔
                   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": 100, "period": "0.00:00:30", "columnOptionsSection": { "disableTriggers": true, "clusteredColumnstoreIndex": false, "primaryKeyColumnName": "Id", "addStandardColumns": [ "LogEvent" ], "removeStandardColumns": [ "MessageTemplate"], "additionalColumns": [ { "ColumnName": "IP", "DataType": "varchar", "DataLength": 32 } ], "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

2、Logger使用

一、直接使用Serilog提供的静态类Log

Log.Information(“message”);

二、使用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")

 

3、怎么把数据写入自定义列

Serilog并无提供 Log.Debug(Message,IP)方法,在咱们平常开发中可能会有以下几种需求:异步

一、设置全局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(5),//执行时间间隔
                   restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"), columnOptions: columnOptions, autoCreateSqlTable: true ).CreateLogger();

二、设置ForContext写入Property

例如我须要记录当前类,须要在记录日志的时候设置ForContextide

Log.ForContext("Calss", GetType().FullName).Information("message");

这里只是一个例子,其实serilog已经自动帮咱们记录了Calss的信息,在Properties中能够找到SourceContext节点,里面就记录了相关的命名空间和类ui

4、对日志进行过滤

若是系统日志太多,咱们很难快速找到有用的信息,因此不少时候咱们会对日志进行过滤

一、经过MinimumLevel进行过滤

设置MinimumLevel的等级进行过滤,Serilog中Level有Verbose,Debug,Information,Warning,Error,Fatal几个等级,Serilog只记录当前等级及比当前等级高的日志。

二、经过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(5),//执行时间间隔
                   restrictedToMinimumLevel: Configuration.GetValue<LogEventLevel>("Serilog:MinimumLevel"), columnOptions: columnOptions, autoCreateSqlTable: true ).CreateLogger();

三、经过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(5),//执行时间间隔
 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(5),//执行时间间隔
 columnOptions: columnOptions, autoCreateSqlTable: true)) .CreateLogger(); 

5、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

相关文章
相关标签/搜索