Customizing NLog to Write Logs to a Database and Troubleshooting Configuration Issues

NLog is a flexible logging framework for .NET applications that supports writing logs to various targets such as files, databases, and email. This article focuses on configuring NLog to log custom data into a database and addresses a common issue where changes to NLog.config appear to have no effect.

Using Layout Renderers for Custom Log Data

NLog provides built-in layout renderers like ${longdate} to format log messages. For custom fields—such as user name, operation type, or IP address—you can use the ${event-context} renderer to pass structured data from your application code into the log target.

Database Target Configuration Example

The following XML snippet shows how to configure a database target in NLog.config:

<target xsi:type="Database" name="DbLogger" connectionStringName="DefaultConnection">
  <commandText>
    INSERT INTO ApplicationLogs (UserName, ActionType, ClientIP, LogTime, Details)
    VALUES (@UserName, @ActionType, @ClientIP, @LogTime, @Details);
  </commandText>
  <parameter name="@UserName"     layout="${event-properties:item=UserName}" />
  <parameter name="@ActionType"   layout="${event-properties:item=ActionType}" />
  <parameter name="@ClientIP"     layout="${event-properties:item=ClientIP}" />
  <parameter name="@LogTime"      layout="${event-properties:item=LogTime}" />
  <parameter name="@Details"      layout="${event-properties:item=Details}" />
</target>

Note: In newer versions of NLog (≥4.0), ${event-context} has been replaced with ${event-properties}. Ensure you're using the correct syntax for you're NLog version.

Logging Custom Data from Code

To populate these custom fields, create a LogEventInfo instance and set properties before logging:

var logger = LogManager.GetCurrentClassLogger();

var logEvent = new LogEventInfo
{
    Level = LogLevel.Info,
    TimeStamp = DateTime.UtcNow
};

logEvent.Properties["UserName"] = currentUser;
logEvent.Properties["ActionType"] = "Login";
logEvent.Properties["ClientIP"] = Request.HttpContext.Connection.RemoteIpAddress?.ToString();
logEvent.Properties["LogTime"] = DateTime.Now;
logEvent.Properties["Details"] = "User authenticated successfully";

logger.Log(logEvent);

Avoid instantiating Logger directly with new Logger(), as its constructor is protected.

Why Changes to NLog.config Seem Ignored

A frequent pitfall is modifying NLog.config without triggering a reload. By default, NLog reads the configuration once at application startup. To apply changes during development:

  • Rebuild and restart the application — this ensures the updated config is loaded.
  • Alternatively, enable automatic reloading by setting autoReload="true" in the root <nlog> element:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">

If autoReload doesn’t work, verify that: - The config file’s "Copy to Output Directory" property in Visual Studio is set to "Copy always" or "Copy if newer". - The application has file system permissions to monitor the config file. - You’re not running in a restricted environment (e.g., some cloud hosts disable file watchers).

Tags: NLog .NET C# logging database

Posted on Thu, 02 Jul 2026 16:04:45 +0000 by fluvius