3

My app creates a log for the application itself, so record when it was activated, and what happened at an application level.

The application is centered around 'profiles' - the user loads a profile which tells the application where/when/what/how. So I also want to create a log for each profile, to record the progress each time the profile is run.

No problems so far... except that I want the profile log to be stored alongside the profile itself, so this means I need to configure NLog dynamically, so I can tell it the fileTarget path at runtime.

However, I was also wanting to store the standard layouts I want to use, as variables in NLog.config; this seems to be a common enough approach from what I have read.

However, at the following line

fileTarget.Layout = "${myLayout}"

...I get an ArgumentException:

LayoutRenderer cannot be found: 'myLayout'

At the moment, my layout variable is simply:

<variable name="myLayout" value="${message}" />

Is it a case that you can't use variables to specify layout through the API? I would be surprised if that was the case. Or have I gone wrong somewhere?

The solution is simple enough - I can populate fileTarget.Layout with a manually-specified layout, but nevertheless, I'm keen to find out if Plan A could work.

CJM
  • 11,908
  • 20
  • 77
  • 115

2 Answers2

6

I got the latest source code (NLog 3.2.0.0) and figured out a solution that is supported without any changes to NLog. The code below gets the value of a variable. I assume it can also be written to, but I did not try that because I don't need that functionality. That answers the question. The last line evaluates the text in the variable to render any layout renderers that it contains.

var config = (NLog.Config.XmlLoggingConfiguration)LogManager.Configuration;
string dir = config.Variables["logDirectory"];
dir = NLog.Layouts.SimpleLayout.Evaluate(dir);
Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
MarkR
  • 215
  • 3
  • 10
  • `config.Variables["..."]` doesn't return a string. Also why would you assign `dir` in `string dir = ...` and then overwrite it in `dir = ...`? – Howiecamp Aug 13 '18 at 20:46
  • (NLog.Config.XmlLoggingConfiguration)config.Variables is a dictionary of in NLog version 3.2.0.0. I don't know what version you are looking at. dir is used to hold the value of the Variable from NLog. It is then passed back into the NLog.Layouts.SimpleLayout.Evaluate() method because it might contain special folder characters that need expanded and this method does this. I just stored the result of the Evaluate() method back into the same variable. – MarkR Aug 14 '18 at 12:30
2

It's not possible if you're using a compiled binary from NLog's site, mainly because NLog doesn't expose an API for accessing <variable> elements.

You could suggest the author to add this ability, OR if you're really keen about having this ability, then download and modify the source code. private string ExpandVariables(string input) in file XmlLoggingConfiguration.cs is what you'll need to expose.

Good luck.

AVIDeveloper
  • 2,954
  • 1
  • 25
  • 32
  • Meh... modify the the source code or simply store the Layouts in the application's setting file? Given timescales, it's a no-brainer! :) But thanks for the response. – CJM Mar 09 '12 at 22:57
  • I would have made the same choice if I were you (see my reply on something similar [here](http://stackoverflow.com/questions/9523875/how-to-set-nlogs-filename-to-the-process-start-date/9524600#9524600)). – AVIDeveloper Mar 09 '12 at 23:26
  • This answer is no longer accurate. See my answer below. – MarkR Mar 18 '15 at 18:17