Is there an list of Contextual Information (ie ${longdate}, ${level}, ${message}) online? I want to set the log file in a folder the user's AppData\Local. Is it maybe ${appdatalocal}? And how would I access the file to send as an email attachment maybe like
message.Attachments.Add("${appdatalocal}\somefolder\Application.log")
?
views:
56answers:
1See this link for a list of LayoutRenderers supported by NLog. Note that some of these layout renderers have been added in NLog 2.0 (which was just released as a beta in September). There are some LayoutRenderers that let you specify "special" folders (like My Documents, My Music, etc). There is also a LayoutRenderer that can retrieve tha value of an environment variable. You can use LayoutRenderers to define the filename:
${basedir}/${shortdate}.log
or
${environment:variable=TEMP}/${processname}.log
As far as accessing the resulting filename programmatically, I'm not sure how to do that, although I do have an idea...
You could configure a MethodCallTarget (see the documentation at the link above - or, even better, see the NLog help file) with the same layout as the layout you use to define the filename. Define a single logger rule in the NLog.config file (or app.config if you configure inline) that logs to that target. Write the static method, LogMethod, that will be called by the MethodCallTarget. Write another static method, GetFilename, on the same class that returns a string. GetFilename simply logs a message using the logger that is configured to write to the MethodCallTarget. NLog calls LogMethod. Inside of LogMethod you will receive the fully formatted message. Since you configured the layout to be the same as the filename layout (i.e. only the parameters necessary to compute the filename), the value of the message that is logged should be the path to the file. Since LogMethod must be a static method (NLog requirement), you don't have much choice where the "filename" is stored. I just put in a static string variable.
Something like this (based on samples in the NLog help file under MethodCallTarget):
public class Example
{
private static filename;
//
// This is the method that NLog will call when you log with the logger that is configured
// to write to the MethodCallTarget
//
public static void LogMethod(string level, string message)
{
filename = message;
}
public static string GetLogFile()
{
Logger logger = LogManager.GetLogger("filenamelogger");
filenamelogger.Info("logging a message just to get the result");
return filename;
}
}
Configure something like this:
<variable fn="${basedir}/${processname}.log" />
<targets>
<target name="m" xsi:type="MethodCall" className="Example, MethodCall"
methodName="LogMethod">
<parameter layout=${fn} />
</target>
<target name="f" xsi:type="File"
layout="${longdate} ${loggername} ${level} ${message}"
fileName="${fn}">
</target>
</targets>
<rules>
<logger name="filenamelogger" minlevel="Debug" writeTo="m" final="true" />
<logger name="*" minlevel="Debug" writeTo="f" />
</rules>
Obviously this is not thread safe, but it does show a way to get the result of a layout.