【问题标题】:Using Nlog messageGeneratorFunc and structured logging使用 Nlog messageGeneratorFunc 和结构化日志记录
【发布时间】:2019-01-10 05:46:23
【问题描述】:

使用 Log.Info 写出结构化日志记录很酷:

Log.Info("The record {id} has firstname {firstname} and lastname {lastname}",
    record.Id, record.FirstName, record.LastName)

我经常使用 Debug 方法。在我使用 Log.IsDebugEnabled 将它们包装起来但开始使用 messageGeneratorFunc 变体之前:

Log.Debug(() => string.Format("The record {0} has firstname {1} and lastname {2}",
    record.Id, record.FirstName, record.LastName);

我想知道如何通过 messageGeneratorFunc 使用结构化日志记录?

Log.Debug(() => Log.Debug("The record {id} has firstname {firstname} and lastname {lastname}",
    record.Id, record.FirstName, record.LastName

看起来很奇怪...Log.Debug Log.Debug 但当然有效... IsDebugEnabled 的内部检查发生了两次...是否有合适的替代方案或者应该是这样的?

【问题讨论】:

    标签: c# nlog


    【解决方案1】:

    messageGeneratorFunc-delegate 用于重/大对象的专门序列化。未启用 LogLevel 时,NLog 不会调用委托。

    使用 messageGeneratorFunc-delegate 处理简单的消息模板是没有意义的。它实际上只会损害性能,因为它总是需要进行委托捕获,即使没有启用 LogLevel。

    这样更便宜、更快:

    Log.Debug("The record {0} has firstname {1} and lastname {2}",
        record.Id, record.FirstName, record.LastName);
    
    Log.Debug("The record {id} has firstname {firstname} and lastname {lastname}",
        record.Id, record.FirstName, record.LastName);
    

    比这样做(去优化):

    Log.Debug(() => string.Format("The record {0} has firstname {1} and lastname {2}",
        record.Id, record.FirstName, record.LastName);
    

    另见 NLog 教程:Logger should handle string formatting

    【讨论】:

    • 我猜int id 属性在记录对象上的装箱非常小,甚至可能捕获一个通用重载?我没有考虑委托捕获问题。
    • NLog Logger 类实际上具有特殊的泛型方法,因此确保不会发生装箱和分配参数数组(除非使用超过 3 个参数)
    猜你喜欢
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多