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
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>
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
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.
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/
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>
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);
}