Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom implementation of ILogger

In my project I often add prefixes to my log messages.

Currently I am doing this with

      logger.LogDebug(prefix + " some message");

I thought it would be a good way to implement a custom logger where I set the prefix and the logger itself attaches it every time it logs something.

So I created my custom logger class and implemented the ILogger interface. But I do not understand how to use the

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)

method to add the prefix (which is a member of the custom logger class).

My full code is:

      public class CustomLogger : ILogger
      {

        private readonly ILogger _logger;
        private string _logPrefix;

        public CustomLogger(ILogger logger)
        {
          _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _logPrefix = null;
        }

        public ILogger SetLogPrefix(string logPrefix)
        {
          _logPrefix = logPrefix;
          return this;
        }

        public IDisposable BeginScope<TState>(TState state)
        {
          return _logger.BeginScope(state);
        }

        public bool IsEnabled(LogLevel logLevel)
        {
          return _logger.IsEnabled(logLevel);
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
          _logger.Log(logLevel, eventId, state, exception, formatter);
        }

      }
like image 334
monty Avatar asked Nov 27 '18 06:11

monty


People also ask

How do I create an instance of ILogger?

CreateLogger<T>(ILoggerFactory) Creates a new ILogger instance using the full name of the given type.

What is an ILogger?

ILogger : This interface provides the Log() method, which can be used to write a log message. ILoggerProvider : Logging providers implement this interface to write the logs to a specific destination. For example, the Console ILoggerProvider writes the logs to the console.

What is the use of ILogger in .NET core?

The ILoggerFactory is the factory interface for creating an appropriate ILogger type instance and also for adding the ILoggerProvider instance. The Logging API includes the built-in LoggerFactory class that implements the ILoggerFactory interface.

Where can custom logging provider and corresponding logger be registered?

Usage and registration of the custom logger. By convention, registering services for dependency injection happens as part of the startup routine of an application. The registration occurs in the Program class, or could be delegated to a Startup class.


1 Answers

I think you should not call a _logger in a custom logger.

It would be a circular call on runtime and the result would be "prefix: prefix: prefix: prefix: prefix: prefix: prefix: prefix: ..."

Simply, you can create a simple logger and implement a log writter such as Console, database writter, log4net, ...

Now first, you should change your custom logger like below:

    public class CustomLogger : ILogger
    {
        private readonly string CategoryName;
        private readonly string _logPrefix;

        public CustomLogger(string categoryName, string logPrefix)
        {
            CategoryName = categoryName;
            _logPrefix = logPrefix;
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return new NoopDisposable();
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return true;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            string message = _logPrefix;
            if (formatter != null)
            {
                message += formatter(state, exception);
            }
            // Implement log writter as you want. I am using Console
            Console.WriteLine($"{logLevel.ToString()} - {eventId.Id} - {CategoryName} - {message}");
        }

        private class NoopDisposable : IDisposable
        {
            public void Dispose()
            {
            }
        }
    }

The second step, create a logger provider:

     public class LoggerProvider : ILoggerProvider
        {     
            public ILogger CreateLogger(string categoryName)
            {                
                return new CustomLogger(categoryName, "This is prefix: ");
            }

            public void Dispose()
            {
            }
        }

The third step, in Configure from Startup.cs:

    loggerFactory.AddProvider(new MicroserviceLoggerProvider());
like image 172
Khai Nguyen Avatar answered Sep 21 '22 14:09

Khai Nguyen