top of page

NLog with ILogger in .Net 6.0 Web API

Updated: Feb 6

In software development, where intricate systems and complex functionalities intertwine, logging stands as a silent sentinel, diligently recording the pulse of applications. From tracking critical errors to monitoring system behavior, effective logging is indispensable for understanding an application's health and diagnosing issues in real-time. In this digital age where every click and keystroke leaves a digital footprint, logging emerges as the guardian of transparency and accountability in software systems.


NLog with ILogger in .Net 6.0 Web API

In the vast landscape of .NET development, developers are presented with a plethora of logging frameworks and utilities to choose from. Among these, NLog and ILogger stand out, offering robust solutions for logging in .NET applications. In this article, we will explore the synergy between NLog and ILogger within the context of .NET 6.0 Web API development, exploring their features, benefits, and integration strategies.


Understanding NLog and ILogger

NLog, an acronym for "Nancy Logger," is an open-source logging framework for .NET and .NET Core applications. Renowned for its simplicity, flexibility, and extensibility, NLog empowers developers to seamlessly integrate logging capabilities into their projects with minimal overhead. Whether it's capturing debug messages during development or logging critical errors in production, NLog offers a comprehensive suite of features tailored to meet diverse logging requirements.



ILogger

ILogger is an integral part of Microsoft's logging abstraction framework, designed to provide a unified logging interface across .NET applications. As a core component of the Microsoft.Extensions.Logging namespace, ILogger serves as a bridge between application code and various logging providers, facilitating seamless integration with different logging frameworks and utilities.


Key Features of NLog:

  1. Rich Configuration Options: NLog provides extensive configuration options, allowing developers to tailor logging behavior according to their specific needs. From defining log output formats to configuring log levels and targets, NLog offers unparalleled flexibility in managing log data.

  2. Versatile Target Support: With support for a wide range of log targets including files, databases, email, and more, NLog enables developers to route log messages to diverse destinations effortlessly. This versatility ensures that log data can be stored, analyzed, and retrieved from various sources as per the application's requirements.

  3. Performance Optimization: NLog is engineered for performance, with optimizations built-in to ensure minimal impact on application performance. Asynchronous logging, buffering, and batching mechanisms mitigate overhead, allowing applications to maintain peak performance even under heavy logging loads.

  4. Exception Handling: NLog excels in exception handling, providing robust mechanisms for capturing and logging exceptions effectively. With configurable exception logging rules and detailed exception information, NLog facilitates thorough error analysis and debugging.

  5. Extensibility: NLog's modular architecture and extensible design make it highly adaptable to evolving logging needs. Developers can leverage custom targets, layouts, and log event handlers to extend NLog's functionality and integrate seamlessly with third-party services and platforms.


Setting It Up

Setting up NLog within a .NET 6.0 Web API project may initially appear daunting, particularly when it comes to choosing the appropriate NuGet package. However, with a bit of guidance, the process becomes much more manageable.


The crucial NuGet package to include in your project is NLog.Web.AspNetCore version 4.14.0. This package provides the necessary functionalities for integrating NLog with your ASP.NET Core application seamlessly.

xmlCopy code
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />

Logging within your application occurs at a higher level, even before executing your Web API. In your Program.cs file, you'll configure NLog and set up the logging environment for your application. Here's a breakdown of the steps involved:


Configure NLog in Program.cs:

using LoggingDotNet6.Helpers; 
using NLog; 
using NLog.Web; 

var logger = NLog.LogManager.Setup() 
		.LoadConfigurationFromAppSettings() 
		.GetCurrentClassLogger(); 
logger.Debug("Initializing main"); 

try 
{ 
	var builder = WebApplication.CreateBuilder(args); 

	// Add services to the container. 
	// Your other service registrations go here. 

	// NLog: Setup NLog for Dependency injection 
	builder.Logging.ClearProviders(); 
	builder.Logging.SetMinimumLevel
			(Microsoft.Extensions.Logging.LogLevel.Trace); 
	builder.Host.UseNLog(); 

	// Register other classes that need the logger 
	builder.Services.AddTransient<GenericHelper>(); 

	var app = builder.Build(); 

	// Configure the HTTP request pipeline. 
	// Other configuration settings go here. 
} 
catch (Exception exception) 
{ 
	// NLog: Catch setup errors 
	logger.Error(exception, "Stopped program because of an exception"); 
	throw; 
} 
finally 
{ 
	// Ensure to flush and stop internal timers/threads before application-exit 
	// (Avoid segmentation fault on Linux) 
	NLog.LogManager.Shutdown(); 
}

In the above setup:

  • NLog.LogManager.Setup() initializes the NLog configuration.

  • LoadConfigurationFromAppSettings() loads the NLog configuration from the application settings.

  • GetCurrentClassLogger() retrieves the logger for the current class.

  • We clear existing logging providers, set the minimum log level to trace, and enable NLog for the host.

  • Other classes requiring logging, like GenericHelper, are registered as transient services.


Utilizing Dependency Injection (DI):

Dependency injection plays a vital role in enabling logging outside of controllers. By registering classes like GenericHelper as transient services, we ensure that the logger can be injected wherever needed within the application.


Logging Beyond Controllers:

Logging outside controllers, as exemplified by the GenericHelper class, enhances code organization and adherence to Test Driven Development (TDD) principles. This practice ensures that controllers remain sleek and focused while the actual business logic resides elsewhere.


Log Output Configuration:

NLog's configuration file, typically named nlog.config, governs the output and formatting of log messages. By defining targets and rules within this XML file, developers can specify where log files are written and how log messages are formatted. In the provided example, logs are directed to files located in the C:\temp folder, with a specific layout defined for each log message.


With these configurations in place, your .NET 6.0 Web API project is equipped with robust logging capabilities, allowing you to efficiently track application behavior and diagnose issues as they arise.


Logging beyond Controller

Logging beyond controllers involves encapsulating logging functionality into separate classes or utilities outside the controller scope. This approach enhances code organization, maintains the Single Responsibility Principle (SRP), and keeps controllers focused solely on handling HTTP requests and coordinating application flow.


Let's consider an example scenario in a .NET 6.0 Web API project:


Suppose we have an OrderController responsible for handling HTTP requests related to orders, such as creating, updating, and deleting orders. Instead of embedding logging directly within the controller methods, we'll create a separate logging utility class named OrderLogger to handle logging-related tasks.


Here's how the OrderLogger class might look:

using NLog; 

namespace LoggingDotNet6.Helpers 
{ 
	public class OrderLogger 
	{ 
		private readonly ILogger<OrderLogger> logger; 
		public OrderLogger(ILogger<OrderLogger> logger) 
		{ 
			_logger = logger; 
		} 

		public void LogOrderCreation(int orderId) 
		{ 
			_logger.LogInformation($"Order with ID {orderId} created successfully."); 
		} 

		public void LogOrderUpdate(int orderId) 
		{ 
			_logger.LogInformation($"Order with ID {orderId} updated successfully."); 
		} 

		public void LogOrderDeletion(int orderId) 
		{ 
			_logger.LogInformation($"Order with ID {orderId} deleted successfully."); 
		} 
		
		// Additional logging methods as needed 
	} 
}

In this example, the OrderLogger class encapsulates logging logic related to order operations. It relies on an injected logger (ILogger<OrderLogger>) provided by the .NET Core logging infrastructure for actual log recording.


Now, let's see how the OrderController can utilize the OrderLogger for logging:

using Microsoft.AspNetCore.Mvc; 
using LoggingDotNet6.Helpers; 

namespace LoggingDotNet6.Controllers 
{ 
	[ApiController] 
	[Route("[controller]")] 
	public class OrderController : ControllerBase 
	{ 
		private readonly OrderLogger orderLogger; 

		public OrderController(OrderLogger orderLogger) 
		{ 
			orderLogger = orderLogger; 
		} 

		[HttpPost] 
		public IActionResult CreateOrder() 
		{ 
			// Logic for creating an order 
	
			_orderLogger.LogOrderCreation(123); // Example order ID 
			return Ok("Order created successfully."); 
		} 

		[HttpPut("{id}")] 
		public IActionResult UpdateOrder(int id) 
		{ 
			// Logic for updating an order 
		
			_orderLogger.LogOrderUpdate(id); 
			return Ok($"Order with ID {id} updated successfully."); 
		} 

		[HttpDelete("{id}")] 
		public IActionResult DeleteOrder(int id) 
		{ 
			// Logic for deleting an order 
			
			_orderLogger.LogOrderDeletion(id); 
			return Ok($"Order with ID {id} deleted successfully."); 
		} 
	} 
}

In this setup:

  • The OrderController remains focused on handling HTTP requests and invoking the appropriate business logic for order operations.

  • Logging responsibilities are delegated to the OrderLogger class, which ensures separation of concerns and better code organization.

  • The controller methods invoke corresponding logging methods from the OrderLogger class to record relevant log events for order-related operations.


Log Output and Files

NLog's configuration file, typically named nlog.config, serves as the cornerstone for defining log output destinations and formatting. This XML-based configuration file provides developers with fine-grained control over how log messages are processed and where they are stored.


Below is an example XML configuration for directing logs to files:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	autoReload="true"> 
	
	<!-- Define targets to write log messages --> 
	<targets> 
		<!-- File Target for all log messages with basic details --> 
<target xsi:type="File" name="allfile" fileName="C:\logs\nlog-${shortdate}.log" layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=tostring}" /> 
	</targets> 

	<!-- Define rules to map loggers to targets --> 
	<rules> 
		<!-- Route all log messages to the 'allfile' target --> 
		<logger name="*" minlevel="Trace" writeTo="allfile" /> 
	</rules> 
</nlog>

In this configuration:

  • The targets section defines the output destinations for log messages. In this case, logs are directed to a file specified by the fileName attribute.

  • The layout attribute defines the format of each log message, including timestamp, log level, logger name, message, and exception details.

  • The rules section specifies how log messages from different loggers are routed to specific targets. In this example, all log messages are routed to the allfile target.


The expected log output format and location can be customized based on the requirements of the application. By configuring NLog's XML file, developers can tailor the logging behavior to suit the needs of their project, ensuring that log messages are captured and stored efficiently for later analysis and debugging.


Conclusion

As we conclude our exploration, it's clear that NLog and ILogger stand as pillars of logging excellence in .NET development. With NLog and ILogger, the path to logging success in .NET 6.0 Web API projects is illuminated, paving the way for resilient and dependable applications in the digital landscape.

bottom of page