我正在编写一份将由我们的运营团队成员使用的应用程序。我想在屏幕上显示NLog正在写入的文件的名称。这将允许他们在必要时查看文件。
我可以对该名称进行硬编码,但我想允许使用NLog.config文件。我希望能够获得正在写入的文件的实际名称。
答案 0 :(得分:3)
在我在互联网上发现的一些评论和反思与Telerik JustDecompile的汇编之间,我能够提出这个解决方案。
当我需要其中一个目标的实际名称时,我可以像这样调用下面的方法
string fileName = GetLogFileName("file");
其中file是nlog.config文件中目标的名称
public string GetLogFileName(string targetName) {
string rtnVal = string.Empty;
if (LogManager.Configuration != null && LogManager.Configuration.GetConfiguredNamedTargets().Count != 0) {
Target t = LogManager.Configuration.FindTargetByName(targetName);
if(t != null){
Layout layout = new Layout((t as NLog.Targets.FileTarget).FileName);
rtnVal = layout.GetFormattedMessage(null);
}
}
return rtnVal;
}
对于NLog的2.1.0.0版本,我必须将代码更改为
public string GetLogFileName(string targetName) {
string rtnVal = string.Empty;
if (LogManager.Configuration != null && LogManager.Configuration.ConfiguredNamedTargets.Count != 0) {
NLog.Targets.Target t = LogManager.Configuration.FindTargetByName(targetName);
if (t != null) {
NLog.Layouts.Layout layout = (t as NLog.Targets.FileTarget).FileName;
rtnVal = layout.Render(LogEventInfo.CreateNullEvent());
}
}
return rtnVal;
}
答案 1 :(得分:2)
您需要编写自定义目标
按照nlog-project.org/wiki/How_to_write_a_Target
下的说明操作然后将其修改为仅限拦截器并添加ActualLogfile属性
[Target("Interceptor")]
public sealed class InterceptTarget : FileTarget
{
public string ActualLogfile { get; set; }
protected override void Write(LogEventInfo logEvent)
{
ActualLogfile = this.FileName.Render(logEvent);
string logMessage = this.Layout.Render(logEvent);
base.Write(logEvent);
}
}
NLog.config应该是这样的:
<nlog>
<targets>
<target name="i"
xsi:type="Interceptor"
fileName="${basedir}\logs\${shortdate}.log" />
</targets>
<rules>
<logger name="*" minLevel="Trace" writeTo="i"/>
</rules>
</nlog>
备注:在ActualLogFile为空之前,应该生成一个非常早期的日志消息(在pgm start)。
答案 2 :(得分:0)
为什么不简单地为任何/所有&lt; target&gt;解析NLog.config?