c# - NLog无法从属性打印对象?

标签 c# elasticsearch config nlog

我有以下类(class):

[DataContract]
public class CallInformation
{
    [DataMember]
    public string Address { get; set; }
    [DataMember]
    public Boolean IsEmpty { get; set; }
    [DataMember]
    public Boolean IsFaulted { get; set; }
    [DataMember]
    public string Action { get; set; }
    [DataMember]
    public CallOrder CallDirection { get; set; }
    [DataMember]
    public DateTime EventTime { get; set; }
    [DataMember]
    public TimeSpan Duration { get; set; }
    [DataMember]
    public Boolean IsCallback { get; set; }
    [DataMember]
    public string LogSource { get; set; } = "Unknown";

    [DataMember]
    public string Soap { get; set; }
    public string EventTimeDisplay
    {
        get { return EventTime.ToString("HH:mm:ss.fffffff"); }
        set { }
    }
}

这填充了有关客户端服务器应用程序中通信的数据,并且已发送给NLog:
public void LogCommunication(CallInformation callInfo)
        {
            var logEvent = new LogEventInfo(LogLevel.Trace, "CommunicationLogger", "CommunicationLogger is logging");
            logEvent.Properties["CallInformation"] = callInfo;
            _comLogger.Log(logEvent);
        }

如果将其正确放置在属性中还是应该将其放置在参数中?

我需要NLog将其记录到文件中,以便以后可以通过Filebeat,ElasticSearch和Kibana对其进行拾取和搜索。我已经尝试过此NLog配置:
<logger name="CommunicationLogger" minlevel="Trace" writeto="f"></logger>

<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${event-properties:item=CallInformation} ${message}" />

但是它显示的只是CommunicationLogger正在记录日志吗?我怀疑我需要它以某种方式序列化整个对象吗?

问候

编辑1
我试图像这样更改布局:
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${event-properties:item=CallInformation:jsonEncode=true} ${message}" />

这仍然不起作用,但是如果我更改此代码,它将起作用:
logEvent.Properties["CallInformation"] = "test"; //callInfo;

测试按应有的方式写入文件,因此将简单的CallInformation类解析为文件可能存在问题。

我已经检查了内部日志中是否存在NLog,但是在那里找不到任何错误。

编辑2

我试图像这样更改代码:
//var logEvent = new LogEventInfo(LogLevel.Trace, "CommunicationLogger", "ComLog writing.");
            //logEvent.Properties["CallInformation"] = callInfo;
            _comLogger.Log(LogLevel.Trace, "Test to log {@CallInformation}", callInfo);

nlog.config
<target xsi:type="File" 
            name="communicationFileLog" 
            fileName="${basedir}/logs/${shortdate}.log"
            maxArchiveDays="5" 
            maxArchiveFiles="10"
            layout="${event-properties:item=CallInformation:format@} ${message}"  />

日志文件中的结果是这样的:
 Test to log {@CallInformation}
 Test to log {@CallInformation}
 Test to log {@CallInformation}
 Test to log {@CallInformation}
...

最佳答案

需要告知NLog,LogEvent属性对于反射和序列化是安全的。正常的做法是这样的:

_compLogger.Trace("CommunicationLogger is logging {@CallInformation}", callInfo);

然后,由于"CallInformation",NLog将知道LogEvent属性@可以安全地进行序列化。

如果您心情异常,并且不想在LogEvent消息中包含该属性,则可以执行以下操作:
var logEvent = new LogEventInfo(LogLevel.Trace, _comLogger.Name, "CommunicationLogger is logging");
logEvent.Properties["CallInformation"] = callInfo;
_comLogger.Log(logEvent);

然后在Format-option中指定特殊属性:
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${event-properties:item=CallInformation:format=@}" />

另请参阅:https://github.com/NLog/NLog/wiki/How-to-use-structured-logging#output-captured-properties

附言除了使用@(激活NLog自己的序列化程序)之外,您还可以只为ToString() -object覆盖callInfo,然后在此处执行自定义序列化。另一个选择是使callInfo -object实现IFormattable并提供带有LogEventInfo的自定义IFormatProvider

关于c# - NLog无法从属性打印对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61751805/

相关文章:

c# - .NET:为什么 TryParseExact 在 Hmm 和 Hmmss 上失败?

c# - 在 WPF 中对数据绑定(bind)进行单元测试

Elasticsearch : adding temporary field to result with Groovy

php - 子字符串上的elasticsearch聚合

c# - 将 C# 链接起来看起来像 jQuery 是一个好主意吗?

c# - Foreach 上 IEnumerable<> 与 if 条件

c# - 如何在 ElasticSearch 中使用 NEST 指定 index.mapping.ignore_malformed 设置

php - 父级 : Received shutdown signal -- Shutting down the server

lua - 如何使用快捷方式重新加载用 lua 编写的 Neovim 配置?

Java - 如何解析和处理复杂的XML