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

710 views Asked by At

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

There are 2 answers

0
Rolf Kristensen On BEST ANSWER

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

1
Kevin Lu-MSFT On

What are the other ways this can be done?

You could use the Replace Token task from Replace Tokens Extension.

Here are my steps, you could refer to them:

Nlog configuration:

<targets>
    <target name="logfile" xsi:type="File" fileName="#{variable}#/#{shortdate}#.log />
    <target name="logconsole" xsi:type="Console" />
</targets>

Replace Token task sample:

- task: replacetokens@3
  inputs:
    rootDirectory: 'Folder Path'
    targetFiles: '**/*.config'
    encoding: 'auto'
    writeBOM: true
    actionOnMissing: 'warn'
    keepToken: false
    tokenPrefix: '#{'
    tokenSuffix: '}#'
    useLegacyPattern: false
    enableTelemetry: true

Variable:

enter image description here

Then the variables in Nlog configuration will be replaced.

enter image description here