我有以下课程:
[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;
test应该按应有的方式写入文件,因此将简单的CallInformation类解析为文件可能存在问题。
我已经检查了内部日志中的NLog,但在那里找不到任何错误。
NLog需要告知,LogEvent属性对于反射和序列化是安全的。正常的做法是这样的:
_compLogger.Trace("CommunicationLogger is logging {@CallInformation}", callInfo);
然后,NLog将知道由于"CallInformation"
,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
P.S。除了使用@
(激活NLog自己的串行器)外,您还可以为ToString()
对象覆盖callInfo
,然后在该对象中执行自定义序列化。另一种选择是使callInfo
对象实现IFormattable
,并提供带有LogEventInfo的自定义IFormatProvider
。