Config Transformation on NLog does not work

前端 未结 10 1715
悲&欢浪女
悲&欢浪女 2021-02-05 09:15

I have a web project (ASP.NET MVC 4 project) that has a number of configurations stored in Web.Config and in NLog.config files.

I have

相关标签:
10条回答
  • 2021-02-05 09:51

    To solve this issue I had to:

    1) Avoid the use of nlog.config

    2) Create nlog section inside web.config and move the contents of nlog.config to web.config to be able the use the web.config transformation feature with one file. To further instructions please take a look at: NLog configuration instructions

    3) Remove xmlns attributes from the nlog node. There seems to be a bug that messes everything during the web.config transformation. You can safely remove the following nodes:

    xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    

    4) I couldn't find a way to transform just a single target under nlog/targets node. To change the connection string of my logger, I had to copy the whole xml node, using a xdt:Transform="Replace" on the parent node like the following:

    <nlog
          throwExceptions="true"
          internalLogLevel="Trace"
          internalLogFile="..\..\..\Logs\nlog-app.log" 
          xdt:Transform="Replace">
    <!--(copy and paste all nlog configuration here)-->
    </nlog>
    
    0 讨论(0)
  • 2021-02-05 09:57

    Working example when nlog is in web.config - making maximal use of variables to minimise required transformations

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <variable name="SystemName" value="MyApp" />
        <variable name="LogPath" value="c:\log\${SystemName}" />
        <variable name="Layout" value="${longdate}|${level:upperCase=true}|t${threadid}|${logger}| ${message} ${exception:format=message,stacktrace}|${event-properties:item=ir-objects}" />
    
        <targets>
          <wrapper-target xsi:type="AsyncWrapper" name="file-info">
            <target xsi:type="File" createDirs="true" fileName="${LogPath}\${SystemName}.web.info.log" archiveAboveSize="31457280" archiveNumbering="Sequence" maxArchiveFiles="5" archiveEvery="Day" layout="${Layout}" />
          </wrapper-target>
    
        </targets>
    
        <rules>
          <logger name="*" minlevel="Info" writeTo="file-info" />
        </rules>
      </nlog>
    </configuration>
    

    Transform file:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd">
      <nlog:nlog>
        <nlog:variable name="LogPath" value="D:\logs\uat\${SystemName}"  xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
      </nlog:nlog>
    </configuration>
    

    The trick is to namespace all the nlog elements - nlog, variable

    0 讨论(0)
  • 2021-02-05 09:59

    I ended up changing all of my publishing profiles (.pubxml files). I have added the following to my testing publishing profile as an example:

    <Target Name="NLogTransform" AfterTargets="PipelineCopyAllFilesToOneFolderForMsdeploy">
    <Message Text="NLog file transform according to NLog.WebDeploy - TEST.config" Importance="high" />
    <TransformXml Source="NLog.config"
                  Transform="NLog.WebDeploy - TEST.config"
                  Destination="$(_PackageTempDir)\NLog.config" />
    </Target>
    

    Do notice though this only works for publishing profiles that make use of MsDeploy (aka web deploy). For publishing on a local folder use this target CopyAllFilesToSingleFolderForPackage.

    0 讨论(0)
  • 2021-02-05 10:00

    The accepted answer did not work for me.

    I wanted to have internal logging locally, but not on production. It turns out you need to include the namespace in the root configuration node.

    What worked for me: web.config:

    <configuration>
      <configSections>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
      </configSections>
    
      <nlog autoReload="true" internalLogLevel="Trace" internalLogFile="internalLog.txt" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
      <!--nlog config stuff-->
      </nlog>
    </configuration>
    

    web.config.Release

    <?xml version="1.0"?>
      <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" xmlns:nlg="http://www.nlog-project.org/schemas/NLog.xsd">
       <nlg:nlog xdt:Transform="RemoveAttributes(internalLogLevel,internalLogFile)" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">>
       </nlg:nlog>
      </configuration>
    

    Found the solution here: https://www.jayway.com/2011/11/14/web-config-transformations-and-xml-namespaces/

    0 讨论(0)
  • 2021-02-05 10:01

    Update - Adding a "key" attribute to the config and transformation files along with "Transform" and "Locator" attributes to the lines that change in the transformation file works in a standalone NLog.config file as follows:

    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          autoReload="true"
          throwExceptions="false">
        <targets async="true">
          <target name="MyLogFile"
                  xsi:type="File"
                  keepFileOpen="false"
                  fileName="C:/File/Logs/Example.${shortdate}.log"
                  archiveFileName="C:/File/Logs/Example.${shortdate}.{#}.log"
                  archiveEvery="Day"
                  archiveNumbering="Rolling"
                  maxArchiveFiles="30"
                  layout="${Date:universalTime=false:format=o}, ${logger}, ${Level}, ${Message:jsonEncode=true} ${onexception:${newline}'Exception\: ${Exception:format=tostring:jsonEncode=true}', 'StackTrace\:${stacktrace:topFrames=12:jsonEncode=true}'}">
          </target>
        </targets>
        <rules>
            <logger key="logRule" name="*" minlevel="Trace" writeTo="MyLogFile" />
        </rules>
    </nlog>
    

    Transform file:

    <?xml version="1.0" encoding="utf-8"?>
    <nlog xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"
      xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="false">
      <rules>
        <logger key="logRule" name="*" minlevel="Info" writeTo="MyLogFile" xdt:Transform="Replace" xdt:Locator="Match(key)" />
      </rules>
    </nlog>
    
    0 讨论(0)
  • 2021-02-05 10:05

    It appears that I am quite late on this, but I have found that it is necessary for the NLog.config file to have the following:

    <?xml version="1.0" encoding="utf-8"?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd">
    ...
    ...
    </nlog>
    

    And the NLogTransform.config file (or whatever name it may have) to have the following:

    <?xml version="1.0"?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    ...
    ...
    </nlog>
    

    Here is some sample code to test the NLog transformation:

    var tmpConfigFile = new FileInfo("C:\\NLogs\\NLog.config");
    var transformFile = new FileInfo("C:\\Transforms\\NLogTransform.config");
    
    if (transformFile.Exists) {
        var xmlTransformableDocument = new XmlTransformableDocument();
        xmlTransformableDocument.Load(tmpConfigFile.FullName);
        var xmlTransformation = new XmlTransformation(transformFile.FullName);
        xmlTransformation.Apply(xmlTransformableDocument);
        xmlTransformableDocument.Save(tmpConfigFile.FullName);
    }
    
    0 讨论(0)
提交回复
热议问题