【问题标题】:NLog - Only log while debuggingNLog - 仅在调试时记录
【发布时间】:2020-12-17 04:49:42
【问题描述】:

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

【问题讨论】:

  • 您的应用程序是什么类型的?对于网络应用程序,最好的方法是使用web.config transformations
  • 该解决方案应该适用于 Web 和桌面应用程序。

标签: nlog


【解决方案1】:

一个简单的解决方案是拥有一个 NLog.config 文件(其内容将被覆盖 - 您稍后会看到),以及每个解决方案配置/环境的一个 NLog 配置文件(例如,NLog.debug.configNLog.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 />

【讨论】:

  • 我们的 NLog.config 绑定到源代码控制,所以我们所有的团队成员都需要检查所有项目中的所有 NLog 文件?或者有没有办法让 NLog 使用 NLog.debug.config 代替?
  • 您不需要版本NLog.config,只需为每个环境(调试、发布等)配置文件。如果您愿意,可以将NLog.config 附加到.gitignore
  • 错误的唯一正确解决方案是 jweyrich 提供的解决方案。但是,您还可以做更多的事情。而不是删除和复制和弄乱原始 NLog.config 的预构建任务,创建 NLog.Debug.config 和 NLog.Release.config 然后添加一个构建后事件:复制“$(ProjectDir)NLog.$(ConfigurationName ).config" "$(TargetDir)NLog.config" 这将覆盖 NLog.config,但您的源代码管理仍然会很开心并且完好无损,因为原始 NLog.config 不会被覆盖,只是在输出目录中。
  • 当项目是面向 Windows 和 Linux 的多平台 .NET Core 时,此解决方案变得更加复杂。
  • @Davatar,使用 Post-build 事件的缺点是它在发布项目时不起作用。如果部署得到解决,我更喜欢你的方法。有什么想法吗?
【解决方案2】:

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

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

【讨论】:

  • 两种解决方案都可以,但需要大量的工作和时间(我没有)。我想避免更改每个项目,只修改配置文件(有关详细信息,请参阅已编辑的问题)。
  • 我在帖子中添加了新的解决方案。
  • 刚刚测试过这个。像魅力一样工作!
  • 自定义布局渲染器对于这个特定示例的外观如何。我不明白关于它的 NLog 文档。 +1 如果您也可以将其添加到您的答案中。
【解决方案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>

上面的目标仅适用于 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" 以减少所需的过滤器数量。后来我意识到这是无意义的,因为默认是使用记录器......所以你必须忽略它。

【讨论】:

    【解决方案4】:

    这个答案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" />
    

    如果有帮助,请告诉我。

    贾雷克

    【讨论】:

      【解决方案5】:

      如果在运行时允许使用少量代码,则可以这样做:

      <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>
      

      然后在启动时这样做:

      if (IsDebugMode)
      {
          LogManager.Configuration.Variables["myLogLevel"] = "Debug";
          LogManager.ReconfigExistingLoggers();
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-24
        相关资源
        最近更新 更多