John
John

Reputation: 351

Injecting existing logger in the Hosted Service

I am having the project in .net core 3.1. I have configured to use the SeriLog as logger.

One of the service MqttComunicationClient is having logger injected to constructor which is using the serilog configuration. Here ILogger is Microsoft.Extensions.Logging

public MqttCommunicationClient(
            IMqttCommunicationConfiguration mqttConfiguration,
            ILogger logger,
            )
        {
            this.mqttConfiguration = mqttConfiguration;
            this.logger = logger;            
        }

From the Init method of this class I am initializing the custom written MQTT API.

public void Initialize()
        {
            var mqttClientId = $"{DefaultClientIdPattern}{Environment.MachineName}";

            serviceHost = Host.CreateDefaultBuilder()
                  .UseMQTTApi(opt =>
                  {                          
                      opt.UserName = "test";
                      opt.Password = "test";
                  })
                  .ConfigureServices(services =>
                  {
                      services.AddSingleton(logger);                           
                  })
                  .ConfigureHostConfiguration(c => { c.Build(); })
                  .Start();

            managedMqttClient = serviceHost.Services.GetRequiredService<IManagedMqttClient>();
        }

My MQTT Api is having the Handlers which will be triggered on the message received on specified topic.

One of the handler is having following constructor.

public ConnectionStatusHandler(
         ILogger<ConnectionStatus> logger,
         IDeviceCommunications deviceCommunications)         
        {
            this.logger = logger;
            this.deviceCommunications = deviceCommunications;
        }

Now the issue is when I debug my MqttComunicationClient the logger is configured as the SeriLog. As per the requirment and configuration logger.LogInformation() used inside this class is logging to the log file.

enter image description here

When the ConnectionStatusHandler is called the logger changes to the Microsoft.Extensions.Logging.Logger Logger.

enter image description here

The logger used in ConnectionStatusHandler class is only logging to the console and not in the file.

How can I pass on the same serilog configured logger object from MqttComunicationClient to the ConnectionStatusHandler ? Do I need some additional settings? I am a new to this so any help is appreciated.

Edits Code which is configuring the serilog as logger

public IServiceProvider CreateServiceProvider(string basePath)
  {
     var configuration = GetConfiguration(basePath);
     
     var logger = CreateLogger(configuration);
     var services = new ServiceCollection();
     services.AddSingleton(logger);
     return services.BuildServiceProvider();
  }

protected virtual ILogger CreateLogger(IConfiguration configuration)
  {
     return LogBuilder.CreateLogger(null, configuration);
  }
  
// Serilog configured here
public static ILogger CreateLogger(string categoryName, IConfiguration configuration, Action<string> selfLogAction = null)
  {
     var serilogLogger = new LoggerConfiguration()
                           .ReadFrom.Configuration(configuration)
                           .CreateLogger();

     using (var serilogLoggerProvider = new SerilogLoggerProvider(serilogLogger))
     {
        var logger = serilogLoggerProvider.CreateLogger(categoryName);

        if (selfLogAction != null)
        {
           Serilog.Debugging.SelfLog.Enable(selfLogAction);
        }

        return logger;
     }
  } 

// This method reads the configuration from the config json file.
protected virtual IConfiguration GetConfiguration(string basePath)
  {
     StringBuilder configLog = null;
     var mainConfiguration = new ConfigurationBuilder()
        .SetBasePath(basePath)
        .AddJsonFile("mytest.config.json")
        .Build();
     var builder = new ConfigurationBuilder();
     return BuildConfiguration(builder, mainConfiguration, basePath, configLog)
        .Build();
  }
  

Upvotes: 2

Views: 3497

Answers (1)

Tim
Tim

Reputation: 2707

It looks like your code is currently setting up requests for ILogger (untyped) to resolve to Serilog, but Host.CreateDefaultBuilder() is setting up ILogger<T> to work with Microsoft's Logger.

I'd recommend using Serilog.Extensions.Hosting to handle your Serilog registration, that way you can just add UseSerilog() to your hostbuilder and be done.

Upvotes: 1

Related Questions