Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NLog doesn't seem to be logging in ClickOnce environment but works in dev

I am performing logging in my application via NLog. I am trying to gather some logs to diagnose an odd issue I am having on only one machine. In my NLog.Config I have the following configuration:

<?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">

  <targets>
    <target name="logfile" xsi:type="File" fileName="${specialfolder:dir=PollingLogs:file=log.txt:folder=MyDocuments}" />
  </targets>

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

When I run on my development machine I am getting a log.txt file created in my documents folder, with all logging happening correctly. However, when I deploy the application out with ClickOnce however, no log.txt file is being created (that I can find at least). No errors occur, and my app runs as normal, but nothing is happening.

I am stumped at how to even debug this issue. Does anyone have any insight they can share to help me get NLog to work correctly in a clickonce environment?

As a reference, the NLog reference in my project is set to copy local.

like image 933
KallDrexx Avatar asked Sep 13 '11 18:09

KallDrexx


3 Answers

I know this is slightly late but there's another solution described here: Configure log4net or NLog with XML from code although it's answering another question.

I had the same problem described by KallDrexx. I'm not happy with multiple NLog config files floating about (multiple projects in the same solution) so created an NLogHelper class which has a method return the configuration:

    public static XmlLoggingConfiguration SetNlogConfiguration()
    {
        var sr = new StringReader(NlogXmlConfigString1());
        var xr = XmlReader.Create(sr);
        var config = new XmlLoggingConfiguration(xr, null);
        return config;
    }

A separate method just returns the xml string, in my case:

    private static string NlogXmlConfigString1()
    {
        return  @"<nlog xmlns='http://www.nlog-project.org/schemas/NLog.xsd\'
                       xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance\'>
                  <targets>
                       <target name='logfile' xsi:type='File' fileName='${specialfolder:file=My_Logger.txt:folder=Desktop}' />
                  </targets>

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

Finally, I just set the configuration in the relevant class constructor:

    NLog.LogManager.Configuration = NlogHelper.Helper.SetNlogConfiguration();

Obviously it can be refactored and items like log file name can be passed as parameters if required. The configuration xml can just be replaced with whatever your configuration is. Also seems to offer the possibility of easily specifying multiple configurations that are selected at run-time.

I like it because I find it gives me greater control over the NLog configuration in code and during deployment.

like image 67
JamesT Avatar answered Nov 13 '22 09:11

JamesT


I found the answer to this issue when your NLog.config would not be copied to your program if installed using ClickOnce.

You need to select the NLog.config file in your Project using Solution Explorer and set its Properties as follows:

Build Action: Content

Copy to Output Directory: Copy always

Now when you deploy using ClickOnce the files should be copied over as well! :)

like image 41
John Avatar answered Nov 13 '22 10:11

John


To debug this use Sysinternal ProcessMon (free). It can show you among other things the files accesses tried/made of a process...

For this kind of Log I would recommend using ApplicationData or CommonApplicationData or LocalApplicationData from Environment.SpecialFolder and not MyDocuments ...

like image 38
Yahia Avatar answered Nov 13 '22 10:11

Yahia