使用Serilog将消息模板用于消息属性

时间:2018-10-29 00:19:31

标签: serilog

我已采用Serilog来满足我的日志记录需求。 我(尽力)遵循SOLID原则,因此采用了Steven's adapter,这是一个很好的实现。

在大多数情况下,这很棒。我有一个名为LogEntryDetail的类,其中包含某些属性:

class LogEntryDetail
{
    public string Message {get;set;}
    public string MessageTemplate {get;set;}
    public string Properties {get;set;}

    // etc. etc.
}

我将这样记录LogEntryDetail:

    public void Log(LogEntryDetail logEntryDetail)
    {
        if (ReferenceEquals(null, logEntryDetail.Layer))
        {
            logEntryDetail.Layer = typeof(T).Name;
        }

        _logger.Write(ToLevel(logEntryDetail.Severity), logEntryDetail.Exception, logEntryDetail.MessageTemplate, logEntryDetail);
    }

我正在使用MSSqlServer接收器(Serilog.Sinks.MSSqlServer)进行错误记录,一切都很好。

我有一个性能记录器,将其插入请求管道。对于此记录器,我不想将每个属性都保存在LogEntry对象中。我只想将Message属性保存在我创建的表的Message列中。

因此,通常,当您在serilog记录器上调用write并传递一个复杂的对象时,“消息”列将包含整个对象,序列化为JSON。

我想知道是否可以通过某种方式将MessageTemplate指定为 {Message} {@ Message} 之类的东西,所以数据库中的“消息”列仅包含存储在Message对象的LogEntryDetail属性中的字符串。其他任何属性都是多余的,浪费了存储空间。

当我将MessageTemplate指定为 {Message} 时,Message属性包含LogEntryDetail类型的全名(包括名称空间)。

我感觉自己很亲密,只是在理解Serilog的MessageTemplate功能时缺少了一些小东西。

1 个答案:

答案 0 :(得分:0)

我将在这里解释我为获得两全其美所做的努力。似乎我们这里有一个古老的开发人员难题,即牺牲库的特定功能以符合SOLID原则。我们以前通过存储库抽象之类的东西已经看到了这一点,这使得无法利用它们抽象的某些ORM的细粒度功能。

所以,我的SerilogAdapter看起来像这样:

public async Task InitMbi()

如果MessageTemplate是代表整个对象的一个​​,则将记录该消息。否则,可以使用自定义MessageTemplate并可以记录Message属性以及AdditionalInfo属性(字典)。

我们至少从Serilog中挤出了另外一件事,这是它的优点之一-使用不同消息模板的能力日志,并通过消息模板搜索日志。

请务必告诉我是否可以做得更好!