2017-10-06 104 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