采用这个简单的NLog示例配置:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="file.txt" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
如何将其设置为仅在调试时记录,而不是在生产中运行时?
编辑:
使事情变得更具挑战性:我的NLog配置文件是集中的,在所有应用程序/服务/站点上共享。所以我想避免改变每个项目,只需修改配置文件。
我在这看到三种解决方案。
1)使用配置文件及其transformations。目前,Web应用程序支持转换(我在谈论VS2012)。对于桌面应用,您需要安装额外的extension。
2)使用两个目标,一个用于开发(我假设在您的情况下调试=开发),第二个用于生产。在运行时,您需要通过removing the other保留实际的一个。
UPDATE
3)如果您不想更改项目,可以根据自定义布局渲染器将custom conditions应用于记录器(请参阅how to make a custom layout renderer的示例)。在您的情况下,布局渲染器应返回执行程序集的当前构建配置(调试或释放)。因此,条件将如下所示:
<rules>
<logger name="*" writeTo="logfile">
<filters>
<when condition="equals('${buildConfiguration}','Release')" action="Ignore" />
</filters>
</logger>
</rules>
其中$ {buildConfiguration}是您的自定义布局渲染器。
PS并且别忘了把这个
<extensions>
<add assembly="NameOfMyAssemblyThatContainsMyLayoutRenderer" />
</extensions>
到nlog.config,以便NLog知道布局渲染器。
一个简单的解决方案是拥有一个NLog.config
文件(其内容将被覆盖 - 您稍后会看到),以及每个解决方案配置/环境的一个NLog配置文件(比方说,NLog.debug.config
和NLog.release.config
)。例如:
然后配置Pre-build event command line
以复制与当前活动配置对应的配置文件:
您应该粘贴的完整命令:
del "$(ProjectDir)NLog.config"
if "$(ConfigurationName)"=="Debug" (
copy "$(ProjectDir)NLog.debug.config" "$(ProjectDir)NLog.config"
) else (
copy "$(ProjectDir)NLog.release.config" "$(ProjectDir)NLog.config"
)
如果DEBUG是当前的活动配置/环境,这会将NLog.debug.config
复制到NLog.config
(有效地覆盖它),否则它将复制NLog.release.config
。
较短的版本看起来像这样(注意文件命名差异):
del "$(ProjectDir)NLog.config"
copy "$(ProjectDir)NLog.$(ConfigurationName).config" "$(ProjectDir)NLog.config"
另一件需要注意的事情是,在编译期间,编译器将抛出有关与NLog相关的重复声明的各种警告。原因是编译器将为NLog找到2个(或更多)不同的配置文件,它们的声明将发生冲突。为了解决这个问题,你必须更改每个额外NLog配置文件的Properties
,以使构建操作不复制它们。例如:
最后,您可能不希望复制公共/共享目标|规则,以避免在多个文件中更改它们。为此,您可以将这些公共/共享部分移动到另一个文件并使用<include />。
我的答案基于@neleus上面的回答,但仍需要几个小时才能完成某些工作。这是完整的指南,包括。如何设置LayoutRenderer
。对于NLog.config
,您需要:
<extensions>
<add assembly="AssemblyName" />
</extensions>
<target xsi:type="AsyncWrapper" name="asyncProd">
<target xsi:type="File" name="logfileProc" fileName="${basedir}/logs/${buildConfiguration}.log"/>
</target>
<logger name="*" minlevel="Info" writeTo="asyncProd">
<filters>
<when condition="equals('${buildConfiguration}','Debug')" action="Ignore" />
</filters>
</logger>
上面的目标仅适用于NLog的新手,因此他们可以更快地运行。在文件名中使用自定义LayoutRenderer有助于调试,因为您可以在生成的文件中看到它的输出。
然后创建一个名为BuildConfigLayoutRenderer
的类,我改编自neleus'link
[LayoutRenderer("buildConfiguration")]
[ThreadAgnostic]
public class BuildConfigLayoutRenderer : LayoutRenderer {
private String buildconfig;
private String GetBuildConfig() {
if (buildconfig != null) {
return buildconfig;
}
#if DEBUG
buildconfig = "Debug";
#else
buildconfig = "Release";
#endif
return buildconfig;
}
protected override void Append(StringBuilder builder, LogEventInfo logEvent) {
builder.Append(GetBuildConfig());
}
}
重要的是传递给LayoutRendererAttribute
的字符串。它们需要与您注册的内容匹配(需要在代码中尽早发生; main())和NLog.config
。
LayoutRenderer.Register<BuildConfigLayoutRenderer>("buildConfiguration");
现在${buildConfiguration}
将工作。您还可以将其用于更多构建配置,但您需要记住添加忽略该规则的过滤器。我也尝试了相反的意思,即在规则中使用action="Log"
来减少所需的过滤器数量。后来我意识到这是无意义的,因为默认是使用记录器...所以你必须忽略它。