使用 Serilog 持久化 EventType [英] Persisting EventType with Serilog

查看:61
本文介绍了使用 Serilog 持久化 EventType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在 Serilog 中使用 EventType 功能,如关于 此处.

I'm having trouble getting the EventType feature working in Serilog, as blogged about here.

我正在使用以下 Nuget 包:

I am using the following Nuget packages:

  • Serilog 2.8
  • Serilog.Settings.Configuration 3.0.1
  • Serilog.Sinks.File 4.0.0
  • Serilog.Sinks.MSSqlServer 5.1.2

首先,我创建了一个 EventTypeEnricher:

First up, I created an EventTypeEnricher:

public class EventTypeEnricher : ILogEventEnricher
{
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        var crypto = new SimpleCrypto.PBKDF2();
        var hash = crypto.Compute(logEvent.MessageTemplate.Text);
        var numericHash = BitConverter.ToUInt32(Encoding.UTF8.GetBytes(hash), 0);
        var eventId = propertyFactory.CreateProperty("EventType", numericHash);
        logEvent.AddPropertyIfAbsent(eventId);
    }
}

这似乎有效(稍后会详细介绍,但在该方法的末尾,可以观察到在 EventId 变量中添加了一个带有 EventType 值的属性调试时).

This seems to work (more on that later, but at the end of that method, a property is added with an EventType value in the EventId variable can be observed while debugging).

我创建了一个添加此丰富器的扩展方法:

I created an extension method which adds this enricher:

    public static LoggerConfiguration WithEventType(this LoggerEnrichmentConfiguration enrichmentConfiguration)
    {
        if (enrichmentConfiguration == null) throw new ArgumentNullException(nameof(enrichmentConfiguration));
        return enrichmentConfiguration.With<EventTypeEnricher>();
    }

然后我在配置 Logger 时使用它:

I then use that when I configure the Logger:

        Log.Logger = new LoggerConfiguration()
            .Enrich.WithEventType()
            .ReadFrom.Configuration(configuration)
            .CreateLogger();

我去写这样的错误:

logger.Write(LogEventLevel.Error,
    contextFeature.Error,
    MessageTemplates.LogEntryDetailMessageTemplate,
    new LogEntryDetail
    {
        Exception = contextFeature.Error,
        Message = "Bad Stuff",
        Timestamp = DateTime.UtcNow,
        MessageTemplate = MessageTemplates.LogEntryDetailMessageTemplate,
        Severity = LogEventLevel.Error
    });

我的 Serilog appsettings 部分如下:

My Serilog appsettings section is as follows:

  "Serilog": {
    "Using": [ "Serilog.Sinks.File", "Serilog.Sinks.MSSqlServer", "MyAssembly" ],
    "Enrich": [ "EventTypeEnricher" ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "Logs//Errorlog.log",
          "fileSizeLimitBytes": 1073741824,
          "retainedFileCountLimit": 30,
          "rollingInterval": "Day",
          "rollOnFileSizeLimit": true
        },
        "restrictedToMinimumLevel": "Verbose"
      },
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "Data Source=(local);Initial Catalog=ADb;User Id=Serilog;Password=securepwd;",
          "tableName": "ErrorLogs",
          "autoCreateSqlTable": false,
          "period": 30,
          "columnOptionsSection": {
            "disableTriggers": true,
            "clusteredColumnstoreIndex": false,
            "primaryKeyColumnName": "Id",
            "addStandardColumns": [ "LogEvent" ],
            "removeStandardColumns": [ "Properties" ],
            "additionalColumns": [
              {
                "ColumnName": "EventType",
                "DataType": "int",
                "AllowNull": true
              }
            ],
            "id": { "nonClusteredIndex": true },
            "level": {
              "columnName": "Level",
              "storeAsEnum": false
            },
            "timeStamp": {
              "columnName": "Timestamp",
              "convertToUtc": true
            },
            "logEvent": {
              "excludeAdditionalProperties": true,
              "excludeStandardColumns": true
            },
            "message": { "columnName": "Message" },
            "exception": { "columnName": "Exception" },
            "messageTemplate": { "columnName": "MessageTemplate" }
          }
        },
        "restrictedToMinimumLevel": "Verbose"
      }
    ]
  }

我的数据库表是这样的:

My database table looks like this:

CREATE TABLE [dbo].[ErrorLogs](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [EventType] [int] NULL,
    [Message] [nvarchar](max) NULL,
    [MessageTemplate] [nvarchar](max) NULL,
    [Level] [nvarchar](128) NULL,
    [TimeStamp] [datetime] NOT NULL,
    [Exception] [nvarchar](max) NULL,
    [Properties] [nvarchar](max) NULL,
    [LogEvent] [nvarchar](max) NULL,
 CONSTRAINT [PK_ErrorLogs] PRIMARY KEY NONCLUSTERED 

尽管自定义扩充器中的代码正在运行,但数据库中的 EventType 列始终为空.

The EventType column in the database is always null, despite the code in the custom enricher running.

它也不会写入文件接收器.

It is not written to the file sink either.

谁能看到我做错了什么或遗漏了什么?

Can anyone see what I am doing wrong or missing?

干杯

推荐答案

更新到 Serilog.Sinks.MSSqlServer 版本 5.1.3 修复了当前稳定版本 5.1.2 的问题代码> 未阅读所有 columnOptionsSection 部分

Updating to Serilog.Sinks.MSSqlServer version 5.1.3 fixed the issue as current stable version 5.1.2 not reading all columnOptionsSection section

Install-Package Serilog.Sinks.MSSqlServer -Version 5.1.3

以下更新的配置将解决您的问题,因为您错过了 EventType 字段的表映射

And below updated configuration will fix your issue as you miss table mapping for EventType field

"Serilog": {
  "Using": [ "Serilog.Sinks.File", "Serilog.Sinks.MSSqlServer", "MyAssembly" ],
  "Enrich": [ "WithEventType" ],
  "MinimumLevel": {
    "Default": "Information",
    "Override": {
      "Microsoft": "Warning",
      "System": "Warning"
    }
  },
  "WriteTo": [
    {
      "Name": "File",
      "Args": {
        "path": "Logs//Errorlog.log",
        "fileSizeLimitBytes": 1073741824,
        "retainedFileCountLimit": 30,
        "rollingInterval": "Day",
        "rollOnFileSizeLimit": true
      },
      "restrictedToMinimumLevel": "Verbose"
    },
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "Data Source=(local);Initial Catalog=ADb;User Id=Serilog;Password=securepwd;",
        "tableName": "ErrorLogs",
        "autoCreateSqlTable": false,
        "columnOptionsSection": {
          "disableTriggers": true,
          "clusteredColumnstoreIndex": false,
          "primaryKeyColumnName": "Id",
          "addStandardColumns": [ "LogEvent" ],
          "additionalColumns": [
            {
              "ColumnName": "EventType",
              "DataType": "int",
              "AllowNull": true
            }
          ],
          "id": {
            "columnName": "Id",
            "nonClusteredIndex": true
          },
          "eventType": {
            "columnName": "EventType"
          },
          "message": {
            "columnName": "Message"
          },
          "messageTemplate": {
            "columnName": "MessageTemplate"
          },
          "level": {
            "columnName": "Level",
            "storeAsEnum": false
          },
          "timeStamp": {
            "columnName": "TimeStamp",
            "convertToUtc": true
          },
          "exception": {
            "columnName": "Exception"
          },
          "properties": {
            "columnName": "Properties"
          },
          "logEvent": {
            "columnName": "LogEvent"
          }
        }
      }
    }
  ]
}

和Logger配置如下

And Logger configuration as below

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration)
    .CreateLogger();

这篇关于使用 Serilog 持久化 EventType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆