Skip to content

Logging Troubleshooting

Rolf Kristensen edited this page May 31, 2026 · 56 revisions

Possible causes

When no log output is produced, the issue may originate in NLog configuration, the application, or the runtime environment. Common causes include:

  • NLog cannot find the configuration file. Ensure NLog.config has:
    • Build Action = Content
    • Copy to Output Directory = Copy if newer
  • The configuration file contains invalid XML or NLog configuration errors.
  • Logging rules do not match the logger name or log level.
  • The logging code is never executed.
  • The application exits before logs are flushed. Call NLog.LogManager.Shutdown() during application shutdown to flush pending events.
  • The logging target fails at runtime (e.g., missing file permissions).
  • Log output is written to an unexpected location.
  • A different configuration is used at deployment time (overriding the expected NLog.config).
  • Environment differences (hosting, container, or filesystem) compared to local development.

Troubleshooting steps

These steps help isolate the problem area: configuration loading → initialization → rule matching → target writing → application execution


1. Verify configuration file loading

Ensure NLog.config xml-file is located in the application’s base directory, as the primary location of the multiple file location scanned by NLog at startup.

  • Ensure NLog.config has:
    • Build Action = Content
    • Copy to Output Directory = Copy if newer
  • On Linux, file name must be nlog.config (all lowercase as case-sensitive)
  • Some NuGet packages may modify Web.config or App.config and override logging configuration
  • Do NOT use the deprecated NLog.Config NuGet-package, which may overwrite or reset configuration during deployment.
  • Verify that the deployed configuration matches the expected version.

2. Enable configuration exception reporting

NLog will by default suppress any configuration errors, instead of causing the application to fail. But this also means that application will not produce any logging output.

Enabling throwConfigExceptions will make NLog throw exceptions to report any issues detected in the NLog Configuration at startup:

<nlog throwConfigExceptions="true">
    <targets>
        ...
    </targets>
    <rules>
        ...
    </rules>
</nlog>

3. Enable InternalLogger

Enable the NLog InternalLogger and use the output to help diagnose:

  • Configuration loading issues
  • Logger rules decisions
  • Target initialization failures
  • Target writing failures (File permission problems, File path issues, Ex.)
  • Etc.
<nlog internalLogLevel="Debug"
      internalLogFile="c:\temp\nlog-internal.txt"
      internalLogToConsole="true"
      throwConfigExceptions="true">
    <targets>
        ...
    </targets>
    <rules>
        ...
    </rules>
</nlog>

4. Enable InternalLogger early in startup

If no InternalLogger output appears, then it either NLog.config could not be found or failed to load. It can also be that the InternalLogger was enabled after initial attempt to load the NLog logging configuration.

Try to enable NLog InternalLogger from code at application startup. Ensure it happens before any logger usage (like static Logger objects), as configuration is initially loaded when first Logger is created.

class Program
{
    // Temporarily disable static logger initialization
    // readonly static Logger = LogManager.GetCurrentClassLogger();

    static void Main()
    {
        NLog.Common.InternalLogger.LogLevel = NLog.LogLevel.Debug;
        NLog.Common.InternalLogger.LogToConsole = true;
        NLog.Common.InternalLogger.LogFile = @"c:\temp\nlog-internal.txt";

        var logger = LogManager.GetLogger("foo");
        logger.Info("Program started");

        LogManager.Shutdown();
    }
}

5. Simplify logging rules

Reduce logging rule complexity to eliminate matching issues, by adding catch-all rule that matches all loggers and all levels at the beginning of your <rules> section:

<nlog throwConfigExceptions="true">
  <targets>
    <target name="file" type="File" fileName="C:/Logs/log.txt" />
    <target name="console" type="Console" />
  </targets>

  <rules>
    <logger name="*" minLevel="Trace" writeTo="file,console" />
  </rules>
</nlog>

If still no logs appear:

  • Verify that the logging call is actually executed in the application code.
  • Ensure explicit flush is made before application shutdown, in case NLog target is having delays in network communication. Ex. by calling NLog.LogManager.Shutdown().
  • If using file-target then make sure to use absolute file-path as more predictable.

6. Enable runtime exception reporting (last resort)

Enable runtime exception propagation only for diagnostics:

NLog.LogManager.ThrowExceptions = true;

⚠️ Use only ThrowExceptions = true for troubleshooting and unit-testing. Should never be kept enabled in production, as it can cause application runtime crashes. Different from throwConfigExceptions="true" that only enables configuration verification at startup.

class Program
{
    static void Main()
    {
        NLog.LogManager.ThrowExceptions = true; // TODO Remove after troubleshooting

        NLog.Common.InternalLogger.LogLevel = LogLevel.Debug;
        NLog.Common.InternalLogger.LogToConsole = true;
        NLog.Common.InternalLogger.LogFile = @"c:\temp\nlog-internal.txt";

        var logger = LogManager.GetLogger("foo");
        logger.Info("Program started");

        LogManager.Shutdown();
    }
}

Other tools and techniques

External tools can help determine whether the issue is inside NLog or the environment:

These help distinguish between "NLog not writing" vs "Operating System prevented writing".


Key questions to guide troubleshooting

Focus on observable behavior:

  • Is the configuration loaded?
  • Is the logger initialized?
  • Is the logging call executed?
  • Is the log event routed?
  • Is the target writing successfully?

Answering these typically identifies the failing component quickly.

Clone this wiki locally