2012-04-03 31 views
7

我正在使用NLog日志框架,并且试图获取任何UDP记录器应用程序中显示的异常和堆栈跟踪信息,例如SentinelLog2Console,但只能获取日志消息部分显示。输出到一个文件的效果很好,因为大多数例子都是这样做的,所以这个问题围绕着使用NLog的网络目标展开。如何在NLog中记录网络目标的异常

如果可以在内部异常和堆栈跟踪上应用自定义格式,但这不是必需的。 Exception.ToString()会走很长的路。

关于示例代码的注意事项:使用Log2Console我发现article关于如何将异常作为单独的日志条目发送。虽然这有效,但我对解决方案并不满意。

实施例的异常记录代码:

Logger Log = LogManager.GetCurrentClassLogger(); 

try 
{ 
    throw new InvalidOperationException("My ex", new FileNotFoundException("My inner ex1", new AccessViolationException("Innermost ex"))); 
} 
catch (Exception e) 
{ 
    Log.ErrorException("TEST", e); 
} 

例NLog.config:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

<targets async="true"> 

    <!-- Send by UDP to Sentinel with NLogViewer protocol --> 
    <target name="network" xsi:type="NLogViewer" address="udp://192.168.1.3:9999" layout="${message}${onexception:inner=${newline}${exception:format=tostring}}" /> 

    <!-- Send message by UDP to Log2Console with Chainsaw protocol --> 
    <target name="network2" xsi:type="Chainsaw" address="udp://192.168.1.3:9998" appinfo="Grocelist"/> 

    <!-- Send exception/stacktrace by UDP to Log2Console with generic network protocol --> 
    <target name="network2ex" xsi:type="Network" address="udp4://192.168.1.3:9998" layout="${exception:format=ToString}" /> 

    <target name="logfile" xsi:type="File" layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${exception:format=tostring}" 
       createDirs="true" 
       fileName="${basedir}/logs/${shortdate}.log" 
       /> 
</targets> 

    <rules> 
    <logger name="*" minlevel="Debug" writeTo="logfile" /> 
    <logger name="*" minlevel="Debug" writeTo="network" /> 
    <logger name="*" minlevel="Debug" writeTo="network2" /> 
    <logger name="*" minlevel="Warn" writeTo="network2ex" /> 
    </rules> 
</nlog> 

某些链接:

编辑: 搜索一些后,这似乎是对NLog结束的限制。最近的补丁显然是在那里:log4jxmlevent does not render Exception

EDIT2: 我重建NLOG补丁,但它似乎并没有哨兵或Log2Console应用提供帮助。我可能必须尝试使用​​log4net来确保这些应用程序确实支持我试图实现的目标。

编辑3: 我目前使用string.Format()来加入并格式化消息和例外文本。这很好,但不是我在这里寻找的。

+0

Github上的NLogViewerTarget的源代码显示布局集{}为空操作,因此您不能覆盖不包含例外的默认值。 – 2016-05-11 20:04:28

回答

1

您是否尝试过Chainsaw的最新开发者快照?它会显示堆栈跟踪和支持log4net的/ UDP附加目的地,并根据NLOG你可以使用它,以及: http://nlog-project.org/wiki/Chainsaw_target

尝试最新的开发快照,有一吨的特点:http://people.apache.org/~sdeboy

+0

我感觉不好,但我似乎无法弄清楚如何在Windows上运行最新的快照?该zip文件只包含一个.bat文件,通过阅读它我无法弄清楚我需要做些什么才能使它工作。 – angularsen 2012-04-04 07:18:33

+0

您需要安装Java运行时。一旦你这样做了,你可以将压缩文件保存到文件系统并解压缩,导航到apache-chainsaw-2.1.0-SNAPSHOT \ bin文件夹并运行chainsaw.bat命令。这应该做到这一点。 – Scott 2012-04-04 18:42:44

1

只需下载和建设最新的(NLog-Build-2.0.0。2007-0-g72f6495)来自GitHub:https://github.com/jkowalski/NLog/tree/ 此问题已由NLog开发人员修复。

+0

您也可以从这里下载编译的二进制文件http://nlog.codeplex.com/releases/view/81084 – gschuager 2012-10-28 18:33:19

3

您还可以扩展NLog以包含网络日志记录的例外情况。

创建一个扩展布局:

[Layout("Log4JXmlEventLayoutEx")]  
public class Log4JXmlEventLayoutEx : Log4JXmlEventLayout 
{ 
    protected override string GetFormattedMessage(LogEventInfo logEvent) 
    { 
     string msg = logEvent.Message + " ${exception:format=Message,Type,ToString,StackTrace}"; 
     msg = SimpleLayout.Evaluate(msg, logEvent);  
     LogEventInfo updatedInfo; 
     if (msg == logEvent.Message) { 
      updatedInfo = logEvent; 
     } else { 
      updatedInfo = new LogEventInfo(
       logEvent.Level, logEvent.LoggerName, 
       logEvent.FormatProvider, msg, 
       logEvent.Parameters, logEvent.Exception); 
     }  
     return base.GetFormattedMessage(updatedInfo); 
    } 
} 

创建使用该布局

[Target("NLogViewerEx")] 
public class NLogViewerTargetEx : NLogViewerTarget 
{ 
    private readonly Log4JXmlEventLayoutEx layout = new Log4JXmlEventLayoutEx();  
    public override Layout Layout { get { return layout; } set {} } 
} 

更新NLog.config目标:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <extensions> 
    <add assembly="Assembly.Name.That.Contains.Extended.Target"/> 
    </extensions> 
    <targets> 
    <target name="logViewer" 
      xsi:type="NLogViewerEx" 
      address="udp://localhost:7071"> 
    </targets> 
... 
</nlog> 
+0

谢谢你这个不错的解决方案! – 2016-07-20 11:43:47

+0

嗨,亚历克斯,是否有可能为两个目标有两个自定义布局? '哨兵'和'文件?我卡住了,它不起作用(https://stackoverflow.com/q/47753773/6229375) - (链接已更新)。 – 2017-12-12 07:29:27

1

在你NLog.config修改目标如下所示。

<target name="file" xsi:type="File" fileName="log.txt" layout="${longdate}:${message} ${exception:format=message,stacktrace:separator=*}" /> 

,你正在寻找的部分是

${exception:format=message,stacktrace:separator=*} 

欲了解更多有关这一下here

+0

这仅用于文件目标,对不对?问题是获取网络目标的异常信息。 – angularsen 2013-04-24 06:06:04

+0

啊,我一定错过了。是的,这是为了输出到文件。 GL获得网络解决方案。 – JabberwockyDecompiler 2013-04-29 13:38:48

2

我有这个问题,并且刚刚更新了我的NLOG NuGet包到2.0.1.2

现在我有例外通过即将Log2Console就好了。

+0

非常感谢您的支持,我将不得不重新访问这些内容并自己尝试!你还可以发布你的配置吗? – angularsen 2013-04-30 17:42:29

2

几年后,这是相当琐碎,尝试添加

includeSourceInfo = “真”

到目标文件,所以它看起来像;

<target name="viewer" 
      xsi:type="NLogViewer" 
      includeSourceInfo="true" 
      address="udp://127.0.0.1:9999" /> 

为您提供源文件,行,类和方法信息。

+0

谢谢,下次再次遇到NLog和UDP时,我会试试这个。 – angularsen 2015-11-16 21:43:24

+0

可悲的是仍然没有简单的方法来获得堆栈跟踪!在Release模式下运行剥离了很多源代码信息..我会避免这种方法更长时间:-) – keithl8041 2015-11-16 21:51:40