NLog - Only log while debugging

谁都会走 提交于 2019-12-05 15:14:25

I see three solutions here.

1) Using config file and its transformations. For the moment the transformations are supported for web applications (Im talking about VS2012). For desktop app you need to install additional extension.

2) Use two targets, one for development (I assume debugging=development in your case) and the second for production. At runtime you need to leave actual one by removing the other.

UPDATE

3) If you don't want to alter the projects it is possible to apply custom conditions to the logger depending on custom Layout Renderer (see example of how to make a custom layout renderer). In your case the layout renderer should return current Build Configuration (Debug or Release) of executing assembly. As a result the condition will look like this:

<rules>
    <logger name="*" writeTo="logfile">
        <filters>
            <when condition="equals('${buildConfiguration}','Release')" action="Ignore" />
        </filters>
    </logger>
</rules>

where ${buildConfiguration} is your custom layout renderer.

PS And dont forget to put this

<extensions>
    <add assembly="NameOfMyAssemblyThatContainsMyLayoutRenderer" />
</extensions>

to the nlog.config so NLog knows about the layout renderer.

A simple solution would be to have a NLog.config file (whose contents will be overriden - you'll see later), plus one NLog config file per solution configuration/environment (let's say, NLog.debug.config and NLog.release.config). For example:

Then you configure a Pre-build event command line to copy the config file corresponding to the current active configuration:

The complete command you should paste there:

del "$(ProjectDir)NLog.config"

if "$(ConfigurationName)"=="Debug" (
  copy "$(ProjectDir)NLog.debug.config" "$(ProjectDir)NLog.config"
) else (
  copy "$(ProjectDir)NLog.release.config" "$(ProjectDir)NLog.config"
)

This will copy NLog.debug.config to NLog.config (effectively overriding it) if DEBUG is the current active configuration/environment, otherwise it will copy NLog.release.config.

A shorter version would look like this (note the file naming diference though):

del "$(ProjectDir)NLog.config"
copy "$(ProjectDir)NLog.$(ConfigurationName).config" "$(ProjectDir)NLog.config"

Another thing to note is that during compilation the compiler will throw various warnings about duplicate declarations related to NLog. The reason is that the compiler will find 2 (or more) distinct configuration files for NLog and their declarations will collide. In order to fix that you have to change the Properties of each of your extra NLog configuration files to make the build action not copy them. For example:

Do not repeat yourself

Lastly, you may not want to duplicate common/shared targets|rules|whatnot to avoid having to change them in multiple files. To achieve that, you can move these common/shared parts to another file and use <include />.

penCsharpener

I have based my answer on @neleus answer above but it still took me hours to get something working. Here is the completed guide incl. how to set up the LayoutRenderer. For the NLog.config you need:

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

The target above is only for newbees to NLog so they have something running more quickly. Using the custom LayoutRenderer in the filename helps with debugging as you can see it's output in the file that is produced.

Then create a class called BuildConfigLayoutRenderer which I adapted from 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());
    }
}

Important is the string passed into the LayoutRendererAttribute. They need to match with what you register (needs to happen as early as possible in your code; main()) and the NLog.config.

LayoutRenderer.Register<BuildConfigLayoutRenderer>("buildConfiguration");

Now ${buildConfiguration} will work. You can also use this for even more build configurations but you need to remember to add the filter that ignores that rule. I also tried the opposite, meaning to have action="Log" in the rule to reduce the number of filters needed. Later I realised that is non-sense because the default is to use the logger... so you have to ignore it.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!