以编程方式配置 NLog
Configuring NLog programmatically
我有 NLog 的工作配置。我用 NLog.config
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="e:\InternalLog.txt" throwExceptions="true">
<targets>
<target name="database" xsi:type="Database">
<connectionStringName>DB.Log</connectionStringName>
<commandText>
insert into dbo.Log (
Logged, Level, Message, Username, Url, Logger, CallSite, Exception, Stacktrace, remoteAddress
) values (
@Logged, @Level, @Message, @Username, @Url, @Logger, @CallSite, @Exception, @Stacktrace, @RemoteAddress
);
</commandText>
<parameter name="@logged" layout="${date}" />
<parameter name="@level" layout="${level}" />
<parameter name="@message" layout="${message}" />
<parameter name="@username" layout="${identity}" />
<parameter name="@url" layout="${aspnet-request:serverVariable=HTTP_URL}${aspnet-request:queryString}" />
<parameter name="@remoteAddress" layout="${aspnet-request:serverVariable=REMOTE_ADDR}:${aspnet-request:serverVariable=REMOTE_PORT}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@callSite" layout="${callsite}" />
<parameter name="@exception" layout="${exception:format=tostring}" />
<parameter name="@stacktrace" layout="${stacktrace:format=DetailedFlat}" />
</target>
</targets>
<rules>
<logger name="*" writeTo="database" />
</rules>
</nlog>
而且效果很好。但现在我需要以编程方式配置 NLog。所以我试试
var config = new LoggingConfiguration();
var dbTarget = new DatabaseTarget {
ConnectionString = connectionString,
DBProvider = "sqlserver",
Name = "database",
CommandText =
@"insert into dbo.Log (
Logged, Level, Message, Username, Url, Logger, CallSite, Exception, Stacktrace, remoteAddress
) values(
@Logged, @Level, @Message, @Username, @Url, @Logger, @CallSite, @Exception, @Stacktrace, @RemoteAddress
);"
};
dbTarget.Parameters.Add(new DatabaseParameterInfo("@logged", "${date}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@level", "${level}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@message", "${message}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@username", "${identity}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@url", "${aspnet-request:serverVariable=HTTP_URL}${aspnet-request:queryString}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@remoteAddress", "${aspnet-request:serverVariable=REMOTE_ADDR}:${aspnet-request:serverVariable=REMOTE_PORT}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@logger", "${logger}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@callSite", "${callsite}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@exception", "${exception:format=tostring}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@stacktrace", "${stacktrace:format=DetailedFlat}"));
config.AddTarget("database", dbTarget);
var rule = new LoggingRule("*", dbTarget);
config.LoggingRules.Add(rule);
LogManager.Configuration = config;
InternalLogger.LogFile = internalLogFile;
内部记录器工作正常,但普通记录器不工作。我在配置中遗漏了什么?
您还需要在 C# 中注册 NLog.Web,这是 ${aspnet-request}
等所需要的
var extensionAssembly = Assembly.LoadFrom("nlog.web");
ConfigurationItemFactory.Default.RegisterItemsFromAssembly(extensionAssembly);
当使用 XML 配置文件时,会使用自动加载(.NET Core 中还没有)。
这个问题也应该在内部日志中可见。
据我了解NLog的源代码,如果你在LoggingRule
的构造中没有提供最低日志级别,LogLevel.Trace
将不会被用作最低日志级别。但我预计它会。实际上,这似乎是源代码中的错误:没有 EnableLoggingForLevels
调用 (all LoggingRule have EnableLoggingForLevels call but this)。所以,我的问题的修复只是构造函数中的一个参数:
var rule = new LoggingRule("*", LogLevel.Trace, dbTarget);
而不是
var rule = new LoggingRule("*", dbTarget);
现在所有异常都将被记录下来,代码工作正常。
我有 NLog 的工作配置。我用 NLog.config
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="e:\InternalLog.txt" throwExceptions="true">
<targets>
<target name="database" xsi:type="Database">
<connectionStringName>DB.Log</connectionStringName>
<commandText>
insert into dbo.Log (
Logged, Level, Message, Username, Url, Logger, CallSite, Exception, Stacktrace, remoteAddress
) values (
@Logged, @Level, @Message, @Username, @Url, @Logger, @CallSite, @Exception, @Stacktrace, @RemoteAddress
);
</commandText>
<parameter name="@logged" layout="${date}" />
<parameter name="@level" layout="${level}" />
<parameter name="@message" layout="${message}" />
<parameter name="@username" layout="${identity}" />
<parameter name="@url" layout="${aspnet-request:serverVariable=HTTP_URL}${aspnet-request:queryString}" />
<parameter name="@remoteAddress" layout="${aspnet-request:serverVariable=REMOTE_ADDR}:${aspnet-request:serverVariable=REMOTE_PORT}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@callSite" layout="${callsite}" />
<parameter name="@exception" layout="${exception:format=tostring}" />
<parameter name="@stacktrace" layout="${stacktrace:format=DetailedFlat}" />
</target>
</targets>
<rules>
<logger name="*" writeTo="database" />
</rules>
</nlog>
而且效果很好。但现在我需要以编程方式配置 NLog。所以我试试
var config = new LoggingConfiguration();
var dbTarget = new DatabaseTarget {
ConnectionString = connectionString,
DBProvider = "sqlserver",
Name = "database",
CommandText =
@"insert into dbo.Log (
Logged, Level, Message, Username, Url, Logger, CallSite, Exception, Stacktrace, remoteAddress
) values(
@Logged, @Level, @Message, @Username, @Url, @Logger, @CallSite, @Exception, @Stacktrace, @RemoteAddress
);"
};
dbTarget.Parameters.Add(new DatabaseParameterInfo("@logged", "${date}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@level", "${level}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@message", "${message}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@username", "${identity}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@url", "${aspnet-request:serverVariable=HTTP_URL}${aspnet-request:queryString}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@remoteAddress", "${aspnet-request:serverVariable=REMOTE_ADDR}:${aspnet-request:serverVariable=REMOTE_PORT}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@logger", "${logger}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@callSite", "${callsite}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@exception", "${exception:format=tostring}"));
dbTarget.Parameters.Add(new DatabaseParameterInfo("@stacktrace", "${stacktrace:format=DetailedFlat}"));
config.AddTarget("database", dbTarget);
var rule = new LoggingRule("*", dbTarget);
config.LoggingRules.Add(rule);
LogManager.Configuration = config;
InternalLogger.LogFile = internalLogFile;
内部记录器工作正常,但普通记录器不工作。我在配置中遗漏了什么?
您还需要在 C# 中注册 NLog.Web,这是 ${aspnet-request}
等所需要的
var extensionAssembly = Assembly.LoadFrom("nlog.web");
ConfigurationItemFactory.Default.RegisterItemsFromAssembly(extensionAssembly);
当使用 XML 配置文件时,会使用自动加载(.NET Core 中还没有)。
这个问题也应该在内部日志中可见。
据我了解NLog的源代码,如果你在LoggingRule
的构造中没有提供最低日志级别,LogLevel.Trace
将不会被用作最低日志级别。但我预计它会。实际上,这似乎是源代码中的错误:没有 EnableLoggingForLevels
调用 (all LoggingRule have EnableLoggingForLevels call but this)。所以,我的问题的修复只是构造函数中的一个参数:
var rule = new LoggingRule("*", LogLevel.Trace, dbTarget);
而不是
var rule = new LoggingRule("*", dbTarget);
现在所有异常都将被记录下来,代码工作正常。