Logging in Asp.Net Core

nservicebus

(Toni Wenzel) #1

The logging is not usable in ASP.NET Core projects because it can’t be added within the ConfigureServices method.

Example:
I add the endpoint configuration within the ConfigureServices method in order to add the endpoint instance to the DI container.

public void ConfigureServices(IServiceCollection services)
{
  var endpointConfiguration = new EndpointConfiguration("xy");
  // ...

  var logFactory = NServiceBus.Logging.LogManager.Use<MicrosoftLogFactory>();
  var endpointInstance = Endpoint.Start(endpointConfiguration).GetAwaiter().GetResult();
  services.AddSingleton<IMessageSession>(endpointInstance);
  services.AddSingleton(logFactory);
}

The logging is added within the Configure method

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  var logFactory = app.ApplicationServices.GetRequiredService<MicrosoftLogFactory>();
  logFactory.UseMsFactory(factory);
  //..
  app.UseMvc();
}

Now I get following exception
Exception: Call MicrosoftLogFactory.UseMsFactory() prior to starting endpoint.

The problem ist, that I can’t get access to the ILoggerFactory in the ConfigureServices.


(Toni Wenzel) #2

The only workaround at moment seems to be:

var logFactory = NServiceBus.Logging.LogManager.Use();

// Adds the message bus logging to the logger factory.
// this is a workaround for https://github.com/SimonCropp/NServiceBus.MicrosoftLogging/issues/1
var serviceProvider = services.BuildServiceProvider();
logFactory.UseMsFactory(serviceProvider.GetRequiredService<Logging.ILoggerFactory>());

var endpointInstance = Endpoint.Start(endpointConfiguration).GetAwaiter().GetResult();


(Daniel Marbach) #3

Hi Toni

Yeah, that is one of the downsides when you start the endpoint instance where the service collection is available. I did that as a workaround as well in the Service Fabric Webinar because I required access to the StatelessServiceContext, see https://github.com/danielmarbach/service-fabric-webinar/blob/master/stateful-queues/Front_Stateful/NServiceBusServiceCollectionExtensions.cs#L24-L25

Another draw back is that the entry point ConfigureServices cannot be made asynchronous, that’s why the start of the endpoint has to be done with GetAwaiter().GetResult(). An alternative option if you don’t like the workaround you described is to register some provider or message session decorator that gets you access to the message session and asynchronously initializes the endpoint on the first call. This provider could then have a constructor dependency to ILoggerFactory. Obviously, this has then the drawback that any wrong configuration on endpoint start will only be seen when the first request comes in and not during the bootstrapping part.

Regards
Daniel