Implementing Log4Net Logging in .NET Core Applications

Overview

This guide covers integrating log4net logging into .NET Core applications, from basic setup to advanced implementation patterns.

Getting Started

Prerequisites

Install the required NuGet packages for logging functionality:

Microsoft.Extensions.Logging.Log4Net.AspNetCore
log4net

Configuring the Application

Enable log4net in the aplication startup file:

builder.Logging.AddLog4Net();

Log Configuration File

Create a log4net.config file in your project root:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
    <appender name="ConsoleOutput" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
        </layout>
    </appender>
    
    <appender name="FileOutput" type="log4net.Appender.RollingFileAppender">
        <file value="logs/" />
        <appendToFile value="true" />
        <param name="MaxSizeRollBackups" value="10"/>
        <param name="maximumFileSize" value="3MB" />
        <param name="RollingStyle" value="Date" />
        <param name="DatePattern" value=""app_"yyyyMMdd".log"" />
        <param name="StaticLogFileName" value="false" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
        </layout>
    </appender>
    
    <root>
        <level value="ALL"/>
        <appender-ref ref="ConsoleOutput" />
        <appender-ref ref="FileOutput" />
    </root>
</log4net>

Configuraton Details

  • ConsoleOutput: Writes logs to the debug console
  • FileOutput: Writes logs to rotating files in the logs directory
  • MaxSizeRollBackups: Retains up to 10 backup files
  • maximumFileSize: Each log file limited to 3MB
  • DatePattern: Log files named by date format (app_20230431.log)

Global Exception Handling

Create a custom exception filter for capturing unhandled exceptions:

public class GlobalExceptionFilter : ExceptionFilterAttribute
{
    private readonly ILogger<GlobalExceptionFilter> _log;

    public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> log)
    {
        _log = log;
    }

    public override void OnException(ExceptionContext context)
    {
        var exception = context.Exception;
        _log.LogError(exception, "Unhandled exception occurred: {Message}", exception.Message);
        context.ExceptionHandled = true;
    }
}

Advanced Logging Implementation

Domain Models

public class AuditLog
{
    public int Id { get; set; }
    public string ActionName { get; set; }
    public string ControllerName { get; set; }
    public string UserId { get; set; }
    public DateTime ExecutedAt { get; set; }
    public string RequestMethod { get; set; }
    public string RequestPath { get; set; }
    public int StatusCode { get; set; }
    public string Details { get; set; }
}

Database Integration with EF Core

public class AppDbContext : DbContext
{
    public DbSet<AuditLog> AuditLogs { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<AuditLog>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.Property(e => e.ExecutedAt).HasDefaultValueSql("GETUTCDATE()");
        });
    }
}

Audit Service Implementation

public interface IAuditService
{
    Task RecordActionAsync(string action, string controller, string userId, string method, string path, int statusCode, string details);
}

public class AuditService : IAuditService
{
    private readonly AppDbContext _db;
    private readonly ILogger<AuditService> _logger;

    public AuditService(AppDbContext db, ILogger<AuditService> logger)
    {
        _db = db;
        _logger = logger;
    }

    public async Task RecordActionAsync(string action, string controller, string userId, string method, string path, int statusCode, string details)
    {
        var entry = new AuditLog
        {
            ActionName = action,
            ControllerName = controller,
            UserId = userId,
            RequestMethod = method,
            RequestPath = path,
            StatusCode = statusCode,
            Details = details,
            ExecutedAt = DateTime.UtcNow
        };

        try
        {
            _db.AuditLogs.Add(entry);
            await _db.SaveChangesAsync();
            _logger.LogInformation("Audit entry recorded for {User}", userId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to record audit entry");
        }
    }
}

Action Filter for Request Tracking

public class RequestAuditFilter : IActionFilter
{
    private readonly IAuditService _auditService;
    private readonly ILogger<RequestAuditFilter> _logger;

    public RequestAuditFilter(IAuditService auditService, ILogger<RequestAuditFilter> logger)
    {
        _auditService = auditService;
        _logger = logger;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogDebug("Executing {Controller}.{Action}", 
            context.RouteData.Values["controller"], 
            context.RouteData.Values["action"]);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        var userId = context.HttpContext.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "anonymous";
        
        _auditService.RecordActionAsync(
            context.RouteData.Values["action"]?.ToString(),
            context.RouteData.Values["controller"]?.ToString(),
            userId,
            context.HttpContext.Request.Method,
            context.HttpContext.Request.Path,
            context.Result is ObjectResult result ? result.StatusCode ?? 200 : 200,
            context.Exception?.Message
        ).Wait();
    }
}

Registering Filters Globally

builder.Services.AddControllers(options =>
{
    options.Filters.Add<RequestAuditFilter>();
    options.Filters.Add<GlobalExceptionFilter>();
});

Tags: Log4Net .NET Core C# logging ASP.NET Core

Posted on Tue, 18 Aug 2026 16:28:38 +0000 by dupreelove