NLog 不从属性中打印对象?
NLog not printing object from properties?
我有以下 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;
test 已按应有的方式写入文件,因此将简单的 class 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);
然后 NLog 将知道 LogEvent 属性 "CallInformation"
可以安全地序列化,因为 @
.
如果你心情不好,不想属性包含在LogEvent消息中,那么你可以这样做:
var logEvent = new LogEventInfo(LogLevel.Trace, _comLogger.Name, "CommunicationLogger is logging");
logEvent.Properties["CallInformation"] = callInfo;
_comLogger.Log(logEvent);
然后在格式选项中指定特殊属性:
<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 自己的序列化程序)之外,您还可以为 callInfo
-对象覆盖 ToString()
,然后在那里执行自定义序列化。另一种选择是使 callInfo
-object 实现 IFormattable
并提供带有 LogEventInfo 的自定义 IFormatProvider
。
我有以下 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;
test 已按应有的方式写入文件,因此将简单的 class 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);
然后 NLog 将知道 LogEvent 属性 "CallInformation"
可以安全地序列化,因为 @
.
如果你心情不好,不想属性包含在LogEvent消息中,那么你可以这样做:
var logEvent = new LogEventInfo(LogLevel.Trace, _comLogger.Name, "CommunicationLogger is logging");
logEvent.Properties["CallInformation"] = callInfo;
_comLogger.Log(logEvent);
然后在格式选项中指定特殊属性:
<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 自己的序列化程序)之外,您还可以为 callInfo
-对象覆盖 ToString()
,然后在那里执行自定义序列化。另一种选择是使 callInfo
-object 实现 IFormattable
并提供带有 LogEventInfo 的自定义 IFormatProvider
。