Search code examples
tfsnlogvariable-substitution

Dotnet framework - Nlog configuration change using variable substitution in TFS cd pipeline


I have Nlog configuration in the web config file and I would like to change the file path in the CD pipeline in order to put some dynamic path based on the environment.

Right now the web.config file variable substitution (XML Variable Substitution option) does not support it.

What are the other ways this can be done? I really don't have a choice to go the Web.Config transformation approach.

Any guidance on this will really help.

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  autoReload="true"
  throwExceptions="false"
  internalLogLevel="Error" internalLogFile="c:\Logs\nlog-internal.log">
    <targets name="nlogconfig" async="true">
      <target xsi:type="File" name="name"
         fileName="Path/${shortdate}.log"
         archiveFileName="Path/${shortdate}.{###}.log"
         layout="${longdate} ${uppercase:${level}} ${callsite:className=true:includeSourcePath=true:methodName=true:skipFrames=1:cleanNamesOfAnonymousDelegates=true} ${newline} ${message} ${newline} ${exception:innerFormat=ToString:maxInnerExceptionLevel=2:innerExceptionSeparator=newline:separator=newline:format=ToString,StackTrace}${newline}"
         archiveAboveSize="8388608"
         archiveNumbering="Rolling"
         archiveEvery="Day"
         concurrentWrites="true"
         maxArchiveFiles="100" />
    </targets>
    <rules>
      <logger name="*" minlevel="Debug" writeTo="name" />
    </rules>
  </nlog>

Solution

  • Alternative solution is to deploy an environment-specific override-file next to the default NLog.config.

    Example of environment-specific NLog.override.config:

        <nlog>
            <variable name="LogDirectory" value="D:/Path" />
        </nlog>
    

    Example of NLog.config:

        <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        
          <variable name="LogDirectory" value="${basedir}" /> <!-- Default Value -->
        
          <include file="NLog.override.config" ignoreErrors="true" /> <!-- Override Value -->
        
          <targets async="true">
              <target xsi:type="File" name="name" fileName="${LogDirectory}/${shortdate}.log" />
          </targets>
          <rules>
              <logger name="*" minlevel="Debug" writeTo="name" />
          </rules>
        </nlog>
    

    The deployment-package could include multiple nlog.override.config-files. One for each environment and just deploy the right one based on chosen environment.

    See also: https://github.com/nlog/nlog/wiki/Configuration-file#include-files

    See also: https://github.com/NLog/NLog/wiki/Environment-specific-NLog-Logging-Configuration