Here is a rundown of the situation

  • This is a .Net Core (2.1) application with a console and web front ends. For simplicity this question focuses only on the console end although the web end has the same issues.
  • Serilog is the logger of choice. We use 2 sinks (i.e. output sources): Console and MongoDB
  • Security is a concern - the MongoDB connection string contains the password so it needs to be fetched from a secure source. Here we are using an custom created library to retrieve any sensitive information.
  • My understanding is that Serilog configurations are not mutable (for example, add/configure another sink) after initialization, but can be modified after the fact to some extent with "enrichers". This is an aspect I am unfamiliar with.
  • This solution is using standard .NET dependency injection

What's a better way of setting up Serilog, where a sink has a dependency, in a solution using dependency injection? Examples, patterns, templates are welcome. Most examples I've come across of Serilog with .NET Core DI don't address this situation.

public class Program
    static int Main(string[] args)
        var secrets = new ThirdPartySecretProvider("MyApp.Console");
        var secretWrapper = new ThirdPartySecretProviderWrapper(secrets);
        var loggingConnectionString = GetLoggingConnectionString(secretsWrapper);

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
            .WriteTo.MongoDB(loggingConnectionString, "applicationLogs")


        var serviceCollection = new ServiceCollection();
        ConfigureServices(serviceCollection, secretServerWrapper);
        var serviceProvider = serviceCollection.BuildServiceProvider();

            var logger = serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<Application>();
            var config = serviceProvider.GetRequiredService<IConfiguration>();
            Application app = new Application(logger, config);
            return 0;
        catch (Exception ex)
            Log.Fatal(ex, "Host terminated unexpectedly");
            return 1;


    private static void ConfigureServices(IServiceCollection services, ISecretsWrapper secrets)
        IConfiguration config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", true, true)

        var mongoUsernameRead = config["MongoDB:ReadUsername"];
        var mongoClientRead = new DataAccess.Mongo.MongoClient(mongoUsernameRead, secrets.MongoReadPassword);

        var hadoopRepository = new HadoopRepository(secretServer.HadoopApiKey);

            .AddLogging(configure => configure.AddSerilog(dispose: true))
            .AddSingleton<IFileHelper, FileHelper>()
            .AddSingleton<IRepositoryMongo, RepositoryMongo>()
            .AddSingleton<IServiceMongo, ServiceMongo>()
            .AddSingleton<IBaseHttpClient, BaseHttpClient>()
            // ... additional dependencies omitted

    private static string GetLoggingConnectionString(ISecretsWrapper secrets)
        var mongoUsernameReadWrite = "app_myAppReadWrite";
        var mongoClientLog = new DataAccess.Mongo.MongoClient(mongoUsernameReadWrite, secrets.MongoReadWritePassword);
        return mongoClientLog.MongoConnectionString;


Related examples:

One potential change is to create a simple logger (using Serilogger or other) initially to capture failures before the application proper gets started, then create the desired logger to use for the rest of the application. What are the considerations of this approach?


1 Answer 1


This issue is being discussed on the Serilog integration for ASP.NET Core repository. Nicholas Blumhardt has proposed a draft for a late init sink that would be used like this:

var signalRSink = new LateInitSink();

Log.Logger = new LoggerConfiguration()

Log.Information("Sadly, nobody will get this");

// ... resolve that hub ...
signalRSink.Init(wt => wt.Console());

Log.Information("Ah so nice to be loggin' again");

The final version is not yet implemented. Quoting Nicholas Blumhardt from the aforementioned issue:

Yes, it's still being considered - just a matter of someone finding the time to dig in deeply/write some code. Cheers!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.