NLog file not writing - c#

I've been trying to build an app that will use NLog to log a file. The code is really basic, but not seeming to work. Anyone have any ideas? I've set the correct things to "copy always" as well, like in this question. NLog doen't work on IIS
Code below.
MAIN (Including using statements to show I am actually using them)
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
class Program
{
static void Main(string[] args)
{
var logger = LogManager.GetCurrentClassLogger();
logger.Debug("xxxx");
}
NLog.Config
<?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="file" xsi:type="File"
layout="${longdate} ${logger} ${message}"
fileName="${basedir}/log/logfile.txt" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.2.1.0" newVersion="3.2.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Check whether your process has write access to the ${basedir} location. Also, if your application is running from a special folder, make sure the process is running elevated.

Are you getting a valid logger back from the GetCurrentClassLogger call?
Have you tried turning on Internal Debugging as shown here:
https://github.com/NLog/NLog/wiki/Internal-Logging
This should point you in the correct direction as to why your log files are not being created

If you are trying to debug from Visual studio, try to run VS in elevated account ( run as administrator ) and then start debugging. This way NLog will have enough permissions to create log file.
Also use createDirs=true for each target section in nlog config file to automatically create missing folders in the log file path that is provided in the target section.

Related

NLog.config seems not to be taken into account

I would like to modify my NLog configuration, but I have the impression that my modifications are not taken into account.
According to this URL, the NLog configuration can be found:
In the file applicationname.exe.config. In my case, this file only contains the following NLog related lines:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Modules" />
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="..." culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
applicationname.exe.nlog in application’s directory (there is no such file).
NLog.config in application’s directory. This file exists and contains the following entries:
<?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" autoReload="true">
<targets>
<target name="logfile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target xsi:type="File" layout="${longdate} | ${threadid} | ${logger} | ${message} ..." fileName="${basedir}/Logs/${shortdate}.tralala.${level}.log" />
</target>
<target name="console" xsi:type="Console" />
</targets>
The way the logger is loaded in the application is as follows:
using NLog;
...
private static readonly Logger log = LogManager.GetCurrentClassLogger();
My logfiles are always of the form "${basedir}/Logs/${shortdate}.log" instead of the mentioned "${basedir}/Logs/${shortdate}.tralala.${level}.log", so I have the impression my NLog.config file is not taken into account (or I'm working with the wrong target).
Which one is it and how can I work in order to be able to take my configuration into account?
Oh, for your information, I'm working on a Windows-10 computer, this is the name of my NLog.config file as shown in my Linux subsystem (in order to ensure the case sensitivity):
WSL Linux Prompt> ls -ltra | grep "NLog.config"
-rwxrwxrwx 1 user group 742 Mar 3 13:22 NLog.config
Edit:
By the way: is there a way to configure NLog in order to start every logging session with some information about the used configuration?
Edit: internal log results:
When I enable internal logging, this is what I get:
2022-03-17 10:25:52.8775 Debug Targets for Test by level:
2022-03-17 10:25:52.8775 Debug Trace =>
2022-03-17 10:25:52.8775 Debug Debug => Console LogFile Other_Application
2022-03-17 10:25:52.8775 Debug Info => Console LogFile Other_Application
2022-03-17 10:25:52.8775 Debug Warn => Console LogFile Other_Application
2022-03-17 10:25:52.8775 Debug Error => Console LogFile Other_Application
2022-03-17 10:25:52.8775 Debug Fatal => Console LogFile Other_Application
As you can see, no filePath or so, I have no idea where NLog gets its configuration from.

Assembly probing private path in new csproj format

I've recently finished converting a WPF project to the new csproj format which is much leaner.
However I have one missing piece left, adding a probing path for the assemblies, something that used to exist in the old app.config file. With this missing my application just doesn't find the required dlls.
The way I have this set up is with a Post-build event that clears and moves items to a bin folder:
SET folder=bin
rmdir "$(TargetDir)%folder%" /s /q
mkdir "$(TargetDir)%folder%"
move "$(TargetDir)*.dll" "$(TargetDir)%folder%\"
I've tried adding some entries to the .csproj file but to no avail. I believe this is more for compiling the application:
<PropertyGroup>
<ReferencePath>bin</ReferencePath>
</PropertyGroup>
<PropertyGroup>
<AssemblySearchPaths>
$(AssemblySearchPaths);
$(ReferencePath);
</AssemblySearchPaths>
</PropertyGroup>
I guess my main question, should I still have an app.config, or is there a better .csproj approach available?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin"/>
</assemblyBinding>
</runtime>
</configuration>
My application will work if I include it, but I'd like to know if I can simplify this, or do this in a better way in general.

ASP.NET MVC WebConfig with linked config file causes exception

I have a large ASP.NET MVC project with a data access layer that uses Entity Framework. As well, I have a Windows service project (in a different solution) that makes use of the same DAL project. I have my Web.config/App.config setup so that the connection strings are loaded from a separate connection.config file that is in a shared location. The connection configuration is linked (Add Existing Item > Add As Link) in both projects with Build Action = Content and the Copy To Output Directory = Copy if newer.
The Windows service project runs with no issues, I can see the service connecting to my database correctly. However the ASP.NET MVC project throws an excpetion saying Unable to open configSource file 'connection.config'. (C:\Path\To\My\web.config line 9).
I checked that the connection.config file is copied to output directory. I also tried making a copy of the connection.config file in the ASP.NET project (instead of linking it) and this runs just fine. Why does linking the file suddenly cause an exception?
My files below for reference
App.config (Windows service)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings configSource="connection.config" />
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
[...]
<connectionStrings configSource="connection.config" />
[...]
</configuration>
connection.config
<?xml version="1.0"?>
<connectionStrings>
<clear />
<add name="MyConnection" connectionString="Data Source=./localhost;Initial Catalog=MyBatabase;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>
Edit
I came across this answer that works, however I'm concerned how this would affect the application in release mode or when it's deployed. As well I still don't understand why having the file linked has a different behavior than when it's copied in.

NLog does not create a log file

I am trying to add logging to an application running on mobile device with Windows Mobile 6.1. � .NET Compact framework 3.5. using NLog.
I have the appropriate version of the NLog distribution installed.
However no log files are being created.
Here is my NLog.config file:
<?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=".\Neolant.ASRM.Terminal.log" layout="${longdate}|${level}|${message}|${exception}" autoFlush="true"/>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>
And here is the test code I was using:
public static void Main()
{
try
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
var logger = NLog.LogManager.GetLogger("UpperLevel");
logger.Info("test test test.");
try
{
throw new Exception("Unexpected!");
}
catch (Exception e)
{
var logger = NLog.LogManager.GetLogger("UpperLevel");
logger.WarnException("An exception occured.", e);
}
throw new Exception("Suddenly!");
}
finally
{
NLog.LogManager.Flush();
}
}
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
var logger = NLog.LogManager.GetLogger("UpperLevel");
logger.FatalException("Application closed due to exception.", unhandledExceptionEventArgs.ExceptionObject as Exception);
NLog.LogManager.Flush();
}
I had this problem turned out that my log file was not being copied to my build directory. The NLog github page had the answer. (I've reformatted the paragraph a little for better readability.)
https://github.com/NLog/NLog/wiki/Logging-troubleshooting
NLog cannot find the configuration file. This can happen when the NLog.config file is configured with Build Action = None or Copy to Output Directory = Do not copy in Visual Studio.
Set Build Action = Content and "Copy to Output Directory = Copy if newer to fix this)
The log file was being created - but not in the application directory.
Using ${basedir} layout renderer as part of the file name proved to be a solution.
from nlog troubleshooting guide
Please check Nlog.config file properties: Copy to output directory should be Copy always
Please view image link https://i.stack.imgur.com/AlUG5.png
In case the response marked as answer is not all that clear you can check the example
<targets>
<target xsi:type="Console" name="console"
layout="${longdate}|${level}|${message}" />
<target xsi:type="File" name="ErrorLog" fileName="${basedir}/error.txt"
layout="${longdate}
Trace: ${stacktrace}
${message}" />
<target xsi:type="File" name="AccessLog" fileName="${basedir}/access.txt"
layout="${shortdate} | ${message}" />
</targets>
Taken from here using AppData location in NLog
My issue was permission related, the log file needs to allow the process to write to it, without write permissions you'll get no file.
Here's how to fix it for websites in IIS:
Right click on your folder in windows explorer and select properties
Choose the security tab
Click edit
Click add
In the textbox type 'IIS AppPool\YourAppPoolName' replace YourAppPoolName with the actual name of the application pool your site runs under
Click Check names
Click OK
Security footnote:
From a security aspect the best practice is to use ApplicationPoolIdentity as it is a dynamically created, unprivileged account.
more reading here: https://learn.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities
From the nlog troubleshooting guide:
https://github.com/NLog/NLog/wiki/Logging-troubleshooting
If you know that your config file is definitely being found, temporarily replace the section of your NLog.config file with the following and try it.
This rule will match any logger you've created, and if it works, it will put a log.txt file in the 'base directory' - which is the 'bin' directory for your test instance e.g. if you're running in debug mode, you'll see log.txt in your bin > debug folder. (This isn't explained very clearly in the troubleshooting guide).
If this works then you know that the problem is with your rules:
<nlog throwExceptions="true">
<targets>
<target name="file" type="File" fileName="${basedir}/log.txt" />
</targets>
<rules>
<logger name="*" minLevel="Trace" writeTo="file" />
</rules>
</nlog>
I found that only name="file" worked for the target - other values didn't
Adding the throwExceptions="true" as above will also ensure that you get useful error messages when you're debugging.
In my case, I've missed the rules after defining the rules works like a charm
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
<!-- add your logging rules here -->
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
<logger name="*" minlevel="Debug" writeTo="f" />
-->
</rules>
Spent a lot of time on this issue. This was my problem. I was using a Setup project to install a Windows Service with an MSI. I had to manually add NLog.config to the output of the installer to make sure it got copied to the install directory of the service
for simple troubleshooting purposes, launch VisualStudio to run as administrator. This will help to sort out permissions to create log files while debugging.
Also use createDirs=true in each of the target section to automatically create missing folders in the file path provided in target section.
I also faced the same issue, finally i have solved it. I had a web application, where i want to implement NLog. Please find the following steps to implement NLog.
Step 1:- Go to NuGet packages manager and install following packages.
Step 2:- Open Web.config and add those following line
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<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"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="D:\projects\NlogWeb\nlog-internal.log">
<targets>
<target name="console" xsi:type="ColoredConsole" layout="${message}" />
<!--Write logs to File-->
<target name="file" xsi:type="File" fileName="D:\projects\NlogWeb\ErrorLogFile.log" layout="--------------------- ${level}(${longdate})${machinename}-------------------- ${newline}
Exception Type:${exception:format=Type}${newline}
Exception Message:${exception:format=Message}${newline}
Stack Trace:${exception:format=Stack Trace}${newline}
Additional Info:${message}${newline}" >
</target>
</targets>
<rules>
<logger name="*" minlevel="trace" writeTo="file" />
</rules>
</nlog>
Step 3:- Now the last configuration to call in your .cs file.
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace NlogWeb
{
public partial class Home : System.Web.UI.Page
{
private static Logger logger = LogManager.GetCurrentClassLogger();
protected void Page_Load(object sender, EventArgs e)
{
try
{
throw new Exception("Divide By Zero Exception", new DivideByZeroException());
}
catch (Exception ex)
{
logger.Error(ex.Message);
}
}
}
}
We have done. Now execute your code and enjoy logging.
To fix this, I had to run my application in administrator mode. I suspect windows had an update that suddenly prevented exe's from creating a (log) file, since the exe could always prevously log without admin rights.
In my case I had to load the NLog.config file manually in the code since it wasn't found automatically. Loading the configuration must be done before logs are generated.
LogManager.LoadConfiguration(#"D:\doe\ConsoleApp2\ConsoleApp2\NLog.config");
After that I got log files and console output.
in my case, a WebAPI application, I solved the problem by giving modify permissions to IIS_IUSRS the modify permission for the website folder C:\inetpub\wwwroot\my_website

NLog not working in release mode

I am using NLog to log the exceptions in my asp.net mvc (C#) application.
NLog is not working in release mode. The same is working when running in debug mode.
What may be the problem? Is there any fix for this?
I was having the same problem as you:
ASP.NET MVC 3
.NET 4
IIS 7
Release Mode
I tried changing directories, and changing permissions to no avail. I even tried enabling the internal logging but even that didn't work! No failures, no exceptions, nothing!
After doing some more investigating, I found the solution. For some reason, NLog wasn't loading the config file AT ALL. I realized this after I programmatically enabled the internal logging. The internal logging reported this:
2012-02-13 11:34:40.3181 Debug Targets for MyMvcController by level:
2012-02-13 11:34:40.3181 Debug Trace =>
2012-02-13 11:34:40.3181 Debug Debug =>
2012-02-13 11:34:40.3181 Debug Info =>
2012-02-13 11:34:40.3181 Debug Warn =>
2012-02-13 11:34:40.3181 Debug Error =>
2012-02-13 11:34:40.3181 Debug Fatal =>
This was basically saying that there were no targets defined for any of the log levels! Definitely not correct!
My NLog configuration file was as simple as it could be (and it was set to Copy to Output Directory):
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<!-- Other XML Sections -->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File" fileName="${basedir}/MyApplication.log" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="file" />
</rules>
</nlog>
</configuration>
I'm still not sure exactly why this was happening, but moving the NLog configuration into the web.config directly resolved the problem.
See also: https://github.com/nlog/NLog/wiki/Configuration-file#configuration-file-format
set up environment variables:NLOG_INTERNAL_LOG_LEVEL and NLOG_INTERNAL_LOG_FILE, rerun your release build then check the log file see what's wrong
For anyone, who is not sure about 'why nlog is not working in prod environment':
Go to Nlog.config file
SET throwExceptions="true" in nlog tag
and start debugging with proper errors.
Good luck.
I think you should provide to your publish directory IIS_IUSRS to Write Permission.
Transfer nlog config to config file of your application (web.config for example), and try again.
Make sure your target file saves within a "/logs/" folder. See below
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
I tried to log into "root/log.log" and was not working, then tried "root/logs/log.log" and worked
Below full config file.
<?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"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log" >
<!-- optional, add some variabeles
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue"/>
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!--
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
-->
<!--
Writing events to the a file with the date in the filename. -->
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<!-- add your logging rules here -->
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"-->
<logger name="*" minlevel="Debug" writeTo="f" />
</rules>
</nlog>
You can activate the NLog InternalLogger from code, so you can rule out the issue with correct deployment of NLog.config:
// enable internal logging to the console
NLog.Common.InternalLogger.LogToConsole = true;
// enable internal logging to a file
NLog.Common.InternalLogger.LogFile = "c:\\nlog-internal.txt"; // On Linux one can use "/home/nlog-internal.txt"
// set internal log level
NLog.Common.InternalLogger.LogLevel = LogLevel.Debug;
// Perform test output, ensure first NLog Logger is created after InternalLogger is enabled.
NLog.LogManager.GetLogger("Test").Info("Hello World");
See also: https://github.com/NLog/NLog/wiki/Internal-Logging
See also: https://github.com/NLog/NLog/wiki/Logging-troubleshooting
Another thing worth checking is the write permission of your log directory and/or files.
Permission error, or any other error, will show up in the internal log if enabled. This is how I set up my NLog.config:
<?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"
autoReload="true"
<!-- setting to True will break your application so be careful -->
throwExceptions="false"
<!-- change level to your preference -->
internalLogLevel="Error" internalLogFile="c:\your-path\nlog-internal.log">
<!-- your NLog settings -->
<!-- ... -->
</nlog>
Assuming you've configured NLog in the right way, like the other answers suggest, Try one of these
Write Permission for your Server
If you are using IIS, give WRITE permission for user IIS_IUSRS for your log folder.
Constructor
public LoggerService() {
_logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
}
The path for nlog.config could be different for you. Mine was on the same folder

Categories