Implement a custom logging provider in .NET-JSON and CSV Logging

Introduction

In modern software development, effective logging is crucial for monitoring and debugging applications. While many logging frameworks are available, sometimes you need a custom solution tailored to your specific requirements. In this blog post, we’ll walk you through creating a custom logger in C# that supports both JSON and CSV log formats. Whether you want structured JSON logs for easy analysis or a simple CSV file for auditing purposes, this custom logger has you covered.

Table of Contents:

  1. Prerequisites
  2. Setting Up the Custom Logger
  3. Logging in JSON Format
  4. Logging in CSV Format
  5. Conclusion

1. Prerequisites:

Before we dive into the code, make sure you have the following prerequisites in place:

  • .NET Core or .NET 5+ installed on your system.
  • A code editor (e.g., Visual Studio, Visual Studio Code).
  • Basic knowledge of C# and the .NET ecosystem.

2. Setting Up the Custom Logger:

We’ll start by creating a custom logger that allows you to specify the log output format and, if needed, the CSV file path. The CustomLogger class will handle the actual logging.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.IO;

public class CustomLogger : ILogger
{
    private readonly string _categoryName;
    private readonly LogOutputFormat _logOutputFormat;
    private readonly string _csvFilePath;
    private readonly object _csvLock = new object();

    public CustomLogger(string categoryName, LogOutputFormat logOutputFormat = LogOutputFormat.JSON, string csvFilePath = null)
    {
        _categoryName = categoryName;
        _logOutputFormat = logOutputFormat;
        _csvFilePath = csvFilePath;
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        // Implement if needed
        return null;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        // Implement custom logic to determine if the log level should be enabled
        return true; // Change this condition as needed
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        // Implement custom logic to process and write log messages
        if (!IsEnabled(logLevel))
        {
            return;
        }

        var logEntry = new LogEntry
        {
            Timestamp = DateTime.UtcNow,
            LogLevel = logLevel.ToString(),
            Category = _categoryName,
            Message = formatter(state, exception),
            Exception = exception?.ToString()
        };

        string logOutput;

        switch (_logOutputFormat)
        {
            case LogOutputFormat.JSON:
                logOutput = JsonConvert.SerializeObject(logEntry, Newtonsoft.Json.Formatting.Indented);
                break;

            case LogOutputFormat.CSV:
                logOutput = $"{logEntry.Timestamp},{logEntry.LogLevel},{logEntry.Category},{logEntry.Message},{logEntry.Exception}";
                break;

            default:
                logOutput = "Unsupported log output format";
                break;
        }

        if (_logOutputFormat == LogOutputFormat.CSV)
        {
            if (!string.IsNullOrWhiteSpace(_csvFilePath))
            {
                lock (_csvLock)
                {
                    // Append log entry to the CSV file
                    File.AppendAllText(_csvFilePath, logOutput + Environment.NewLine);
                }
            }
            else
            {
                Console.WriteLine("CSV log file path is not configured.");
            }
        }
        else
        {
            // Output the log message to the console (or other custom target)
            Console.WriteLine(logOutput);
        }
    }

    private class LogEntry
    {
        public DateTime Timestamp { get; set; }
        public string LogLevel { get; set; }
        public string Category { get; set; }
        public string Message { get; set; }
        public string Exception { get; set; }
    }
}

public enum LogOutputFormat
{
    JSON,
    CSV
}

3. Logging in JSON Format:

With the custom logger in place, you can easily log messages in JSON format. Here’s how you can do it:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

class Program
{
    static void Main(string[] args)
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging(builder =>
            {
                builder.AddProvider(new CustomLoggerProvider());
            })
            .BuildServiceProvider();

        var logger = serviceProvider.GetRequiredService<ILogger<Program>>();

        // Example: Log a message with JSON format
        using (logger.BeginScope("TransactionScope"))
        {
            logger.LogInformation("Transaction started.");
            logger.LogInformation("Transaction completed.");
        }
    }
}

4. Logging in CSV Format:

If you prefer logging in CSV format, you can create a separate logger instance and specify the CSV file path. Here’s an example:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

class Program
{
    static void Main(string[] args)
    {
        // Create a CSV logger instance
        var csvLogger = new CustomLogger("CsvLogger", LogOutputFormat.CSV, "c:\\temp\\log.txt");

        // Example: Log a message with CSV format
        csvLogger.LogInformation("CSV log entry 1");
        csvLogger.LogInformation("CSV log entry 2");
    }
}

5. Conclusion:

In this blog post, we’ve demonstrated how to create a flexible custom logger in C# that supports both JSON and CSV log formats. Whether you need structured JSON logs for analysis or simple CSV logs for auditing, this custom logger provides the flexibility to suit your needs.

By following the steps outlined in this post, you can integrate this custom logger into your C# applications and enhance your logging capabilities.

Custom logging solutions offer you the freedom to tailor your logging strategy to your application’s unique requirements. In this tutorial, we’ve created a custom logger in C# that supports JSON and CSV log formats, providing you with the tools needed for effective application monitoring and debugging.

Have questions or suggestions? Feel free to leave a comment below!

Keywords:

  • Custom logger in C#
  • JSON and CSV logging
  • Logging in C#
  • .NET Core logging
  • Structured logging
  • Custom logging solutions
Next Post Previous Post
No Comment
Add Comment
comment url