NLog - 仅在调试时记录

时间:2014-11-10 14:57:48

标签: nlog

采用这个简单的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配置文件是集中的,在所有应用程序/服务/站点上共享。所以我想避免改变每个项目,只修改配置文件。

5 个答案:

答案 0 :(得分:13)

一个简单的解决方案是拥有一个NLog.config文件(其内容将被覆盖 - 稍后会看到),以及每个解决方案配置/环境中的一个NLog配置文件(比方说,NLog.debug.configNLog.release.config)。例如:

All needed NLog config files

然后配置Pre-build event command line以复制与当前活动配置对应的配置文件:

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,以使构建操作不会复制它们。例如:

NLog.debug.config Properties

不要重复自己

最后,您可能不想复制公共/共享目标|规则,以避免在多个文件中更改它们。为此,您可以将这些公共/共享部分移动到另一个文件并使用<include />

答案 1 :(得分:7)

我在这里看到三种解决方案。

1)使用配置文件及其transformations。目前,Web应用程序支持转换(我在谈论VS2012)。对于桌面应用,您需要安装其他extension

2)使用两个目标,一个用于开发(我假设在你的情况下调试=开发),第二个用于生产。在运行时,您需要通过removing the other保留实际值。

<强>更新

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知道布局渲染器。

答案 2 :(得分:3)

我的答案基于上面的@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>

上述目标仅适用于Nbee新手,因此它们的运行速度更快。在文件名中使用自定义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"以减少所需的过滤器数量。后来我意识到这是无稽之谈,因为默认设置是使用记录器...因此您必须忽略它。

答案 3 :(得分:0)

这个答案nLog forum对我们有用。

以下内容转载以防万一。

您可以做的是拥有两个NLog.config文件:

NLog.config

和NLog.Debug.config

在您的代码中,您可以接近主要方法的地方:

#if调试

LogManager.Configuration =新 XmlLoggingConfiguration(“ NLog.Debug.config”);

#endif

现在,如果大多数配置相同,则可以使用 包含文件-将htat常见的所有内容(目标等)放入 NLog.common.config并使用

进行引用

NLog.debug.config:

<include file="NLog.common.config" />
<logger name="*" minLevel="Trace" writeTo="debug" />
<logger name="*" minLevel="Info"  writeTo="viewer" final="true" />

NLog.release.config:

<include file="NLog.common.config" />

<!-- Release  rules -->
<logger name="*" minlevel="Info"  writeTo="file" />
<logger name="*" minLevel="Error" writeTo="event" />

让我知道是否有帮助。

Jarek

答案 4 :(得分:0)

如果在运行时允许少量代码,则可以执行以下操作:

String line = value.toString();

然后在启动时执行此操作:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <variable name="myLogLevel" value="Off" />
    <targets>
        <target name="logfile" xsi:type="File" fileName="file.txt" />
    </targets>

    <rules>
        <logger name="*" minlevel="${var:myLogLevel}" writeTo="logfile" />
    </rules>
</nlog>

另请参阅:https://github.com/nlog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules