2017-10-06 86 views
1

我目前正在开发一个应用程序,它使用NLog for .NET日志记录和JSNLog将日志从Javascript发送到NLog进行日志记录。这些日志存储在SQL数据库中。NLog JSNLog的自定义目标

SQL数据库有NLog的几个列,如Message,StackTrace,InnerException和AdditionalInfo。然而,当我登录从JSNLog喜欢的事,所以

window.onerror = function (errorMsg, url, lineNumber, column, errorObj) { 
    JL("databaseLogger").fatalException({ 
     "msg": "Uncaught Exception", 
     "errorMsg": errorMsg, "url": url, 
     "line number": lineNumber, "column": column 
    }, errorObj); 

    return false; 
} 

很简单,就是通过NLOG理解为一个简单的字符串日志,而不是一个错误,所以它只是增加了这个巨大的JSON字符串到AdditionalInfo列,并且离开的消息, StackTrace和InnerException列为空。这使得阅读日志变得更加困难。

我想能够解析此JSON由JSNLog呼叫发送,并将其发送到适当的NLOG变量,即:

JL("databaseLogger").fatalException({ 
    "Message": "Uncaught Exception", 
    "InnerException": errorMsg, 
}, errorObj); 

将导致消息和包含数据的InnerException列发送在JSON中。解析不是问题,因为我知道如何做到这一点,但我不知道如何拦截对NLog的调用,因此我可以在将它正确发送到NLog之前解析JSON。

我已经看过编写custom NLog target这似乎并不困难,但我不知道如何将我的解析的JSON正确传递给Nlog吗?


编辑#1:更新NLog.config为@Julian 这里是我的新NLog.config但从新Write功能的日志不会被传递到database目标。

<targets> 
    <target xsi:type="ParseJsonWrapper" 
     name="JSONParser"> 
     <target name="database" 
     xsi:type="Database" 
     connectionStringName="ErrorLog" 
     commandText="exec dbo.InsertLog 
          @level, 
          @callSite, 
          @type, 
          @message, 
          @stackTrace, 
          @innerException, 
          @additionalInfo"> 
     <parameter name="@level" layout="${level}" /> 
     <parameter name="@callSite" layout="${callsite}" /> 
     <parameter name="@type" layout="${exception:format=type}" /> 
     <parameter name="@message" layout="${exception:format=message}" /> 
     <parameter name="@stackTrace" layout="${exception:format=stackTrace}" /> 
     <parameter name="@innerException" 
        layout="${exception:format=:innerFormat=ShortType,Message,Method:MaxInnerExceptionLevel=1:InnerExceptionSeparator=}" /> 
     <parameter name="@additionalInfo" layout="${message}" /> 
     </target> 
    </target> 
    </targets> 

    <rules> 
    <logger levels="Trace,Info,Debug,Error,Warn,Fatal" name="JSLogger" writeTo="JSONParser"/> 
    </rules> 

回答

1

在这种情况下,创建一个TargetWrapper是一个很好的解决方案,因此您可以将它与其他目标结合使用。

的配置将是这样的:

<target xsi:type="ParseJsonWrapper" 
      name="myWrapper"> 
    <target xsi:type="File" ...target properties... /> 
    </target> 

为此,必需的代码:从WrapperTargetBase继承和覆盖Write。例如

using System; 
using NLog.Common; 
/// <summary> 
/// Limits the number of messages written per timespan to the wrapped target. 
/// </summary> 
[Target("ParseJsonWrapper", IsWrapper = true)] 
public class ParseJsonWrapper : WrapperTargetBase 
{ 
    protected override void Write(AsyncLogEventInfo logEvent) 
    { 
     var json = logEvent.LogEvent.Message; 
     // parse json 

     // update log event 
     logEvent.LogEvent.Exception = new Exception("something"); 

     // write to wrapped target 
     WrappedTarget.WriteAsyncLogEvent(logEvent) 
    } 
} 

不要忘记注册您的包装(see here)和更新你的配置写在包装,而不是包装的目标。

+0

谢谢你的回答!我已经注册了我的Wrapper,并且可以看到消息传递给我自定义的'Write'函数,但是一旦我改变LogEvent.Exception来使用JSON中的数据,write函数就结束了,日志永远不会传递给'wrapper'中的'target'。有什么我失踪?我已经更新了OP来包含我的新'NLog.config'。 –

+0

oops,从示例中剥离得太多。您需要调用'WrappedTarget.WriteAsyncLogEvent(logEvent)',我已经更新了示例 – Julian

+0

有关工作示例,另请参见:https://github.com/NLog/NLog/blob/master/src/NLog/Targets/包装/ LimitingTargetWrapper.cs – Julian