JSNLog 的 NLog 自定义目标
NLog Custom Target for JSNLog
我目前正在开发一个应用程序,它使用 NLog 进行 .NET 日志记录,并使用 JSNLog 将日志从 Javascript 发送到 NLog 进行日志记录。这些日志存储在 SQL 数据库中。
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 列,而将 Message、StackTrace 和 InnerException 列留空。这使得阅读日志变得更加困难。
我希望能够解析 JSNLog 调用发送的 JSON 并将其发送到适当的 NLog 变量,即:
JL("databaseLogger").fatalException({
"Message": "Uncaught Exception",
"InnerException": errorMsg,
}, errorObj);
将导致 Message 和 InnerException 列包含在 JSON 中发送的数据。解析不是问题,因为我知道该怎么做,但我不确定如何拦截对 NLog 的调用,因此我可以在将 JSON 正确发送到 NLog 之前解析它。
我研究过编写一个 custom NLog target,这似乎并不难,但我不确定如何将解析后的 JSON 正确传递给 Nlog?
编辑 #1:为@Julian 更新了 NLog.config
这是我的新 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>
在这种情况下,创建一个 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) 并更新您的配置以写入包装器而不是包装目标。
我目前正在开发一个应用程序,它使用 NLog 进行 .NET 日志记录,并使用 JSNLog 将日志从 Javascript 发送到 NLog 进行日志记录。这些日志存储在 SQL 数据库中。
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 列,而将 Message、StackTrace 和 InnerException 列留空。这使得阅读日志变得更加困难。
我希望能够解析 JSNLog 调用发送的 JSON 并将其发送到适当的 NLog 变量,即:
JL("databaseLogger").fatalException({
"Message": "Uncaught Exception",
"InnerException": errorMsg,
}, errorObj);
将导致 Message 和 InnerException 列包含在 JSON 中发送的数据。解析不是问题,因为我知道该怎么做,但我不确定如何拦截对 NLog 的调用,因此我可以在将 JSON 正确发送到 NLog 之前解析它。
我研究过编写一个 custom NLog target,这似乎并不难,但我不确定如何将解析后的 JSON 正确传递给 Nlog?
编辑 #1:为@Julian 更新了 NLog.config
这是我的新 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>
在这种情况下,创建一个 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) 并更新您的配置以写入包装器而不是包装目标。