【问题标题】:Persisting EventType with Serilog使用 Serilog 持久化 EventType
【发布时间】:2019-03-19 02:11:44
【问题描述】:

我无法让 EventType 功能在 Serilog 中工作,正如有关 here 的博文所述。

我正在使用以下 Nuget 包:

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

首先,我创建了一个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 值的属性调试时)。

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

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

然后我在配置 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 部分如下:

  "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"
      }
    ]
  }

我的数据库表如下所示:

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 列始终为空。

它也没有写入文件接收器。

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

干杯

【问题讨论】:

  • 它是 .net 核心应用程序吗?
  • @wael 是的,是的。

标签: serilog


【解决方案1】:

更新到 Serilog.Sinks.MSSqlServer 版本 5.1.3 将问题修复为当前稳定版本 5.1.2 未阅读所有 columnOptionsSection 部分

Install-Package Serilog.Sinks.MSSqlServer -Version 5.1.3

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

"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 配置如下

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

【讨论】:

  • 我升级并试了一下,但完全丢失了所有日志记录。我不得不降级。至少在稳定版本中,在我的应用程序中,它会记录除 EventType 之外的所有内容。可能需要向项目作者记录 GIT 票证。
  • @onefoots 你会按照我的回答更新你的应用设置吗?并确保先删除旧表
  • 我做到了,是的。不幸的是,它没有创建表。
  • @onefoots 将在程序启动时使用Serilog.Debugging.SelfLog.Enable(msg =&gt; Debug.WriteLine(msg)); 来启用 serilog 调试以检查问题所在
  • 道歉。我没有向 Serilog 用户添加创建表权限,因为在我的原始配置中,我没有自动创建表。您所做的更改确实有效,并且 EventTypeId 正在填充。我最好手动创建表,所以我只需要弄清楚如何让该 json 配置正确地与现有表一起使用。不确定这是否在预发布版本中完成。
猜你喜欢
  • 2011-06-11
  • 2021-10-01
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
  • 2013-01-02
  • 2010-12-31
相关资源
最近更新 更多