Question: In my application, I work on several thousand of document a day. I'd like, in some cases some logs, one log by document. Then I'd like for a specific target change the output filename (and only the filename) at runtime.

Around the web I found how to create a target by programming me I'd like just update a the filename by programming. I tried the code below. The error I receive is "LayoutRender cannot be found 'logDirectory'.

Any idea ?

Thanks,

```
var target = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");
target.FileName = "${logDirectory}/file2.txt";

LoggingConfiguration config = new LoggingConfiguration();
var asyncFileTarget = new AsyncTargetWrapper(target);
config.AddTarget("logfile", asyncFileTarget);

LogManager.Configuration = config;

```

The config file is :

```
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <variable name="logDirectory" value="C:/MyLogs"/>
    <targets>
      <target name="logfile" xsi:type="File" layout="${date:format=dd/MM/yyyy HH\:mm\:ss.fff}|${level}|${stacktrace}|${message}" fileName="${logDirectory}/file.txt" />
    </targets>

    <rules>
      <logger name="*" minlevel="Info" writeTo="logfile" />
    </rules>    
  </nlog>

```

Answer: 
If not needing to change the LogDirectory at runtime, then you can do this:

```
target.FileName = "${var:logDirectory}\\file2.txt");

```

If needing to modify the logDirectory at runtime, then use the GDC:

<https://github.com/NLog/NLog/wiki/Gdc-layout-renderer>

```
NLog.GlobalDiagnosticsContext.Set("logDirectory","C:\Temp\");

```

Then you can use the following layout:

```
target.FileName = "${gdc:item=logDirectory}\\file2.txt";

```
[I happen to have written an answer that fits your question as well](https://stackoverflow.com/questions/37327129/nlog-dynamically-change-filename-using-nlog-config/52734579#52734579).

In essence, instead of trying to *rewrite* the configuration, you'd be better off simply creating a configuration that allows you to dynamically choose the filename you want.

---

An adapted example for your use case:

```
Logger myLog = LogManager.GetLogger(name);
LogLevel level = LogLevel.Error;
string message = "This is an error message!";

```

You turn this information into a `LogEventInfo` object:

```
LogEventInfo logEvent = new LogEventInfo(level , myLog.Name, message);

```

You can then add properties to this event (the string indexes are free to choose): 

```
logEvent.Properties["CustomFileName"] = "mycustomfilename";

```

And then you write to the log:

```
myLog.Log(logEvent);

```

---

The interesting thing here is that in your NLog configuration, **you can use this custom property in any field that the Nlog documentation refers to as a "Layout" value**. 

You use `${event-properties:item=CustomFileName}` in the layout to access the property. For example:

```
<target xsi:type="File" 
        name="file" 
        fileName="${basedir}/logs/${event-properties:item=CustomFileName}.log"
        layout="${message}" />

```

Following the posted example, this message will be logged in the `mycustomfilename.log` file. This enables you to dynamically switch your targeted file as you please by setting the `logEvent.Properties["CustomFileName"]` value to whatever filename you want to use.

*Note that you can further optimize this, and e.g. only be able to choose part of the file name.*

The additional benefit is that you only need **one target and one rule** in your config file to make this work.