CreateLogger() was previously called and can only be called once

Viewed 861

I get the following exception:

CreateLogger() was previously called and can only be called once.

I don't know when CreateLogger() was called twice.

My Configuration like this:

   public static void Main(string[] args)
        {
            try
            {
                var host = CreateHostBuilder(args).Build();
                Log.Information("Starting host...");
                host.Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly."); //HERE IS THE EXCEPTION: CreateLogger() was previously called and can only be called once.
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseSerilog((provider, context, loggerConfig) =>
                    {
                        loggerConfig.Configure(provider, Configuration);
                    });
                });

My extension Method in called library:

  public static void Configure(this LoggerConfiguration loggerConfig,
        IServiceProvider provider, IConfiguration config)
        {
            var sqlserverConnectionString = config["ConnectionStrings:S1"];
            var sqlserverLogTable = config["Logging:S2"];
            var rollingFileName = config["Logging:S3"];

            var sinkOpts = new MSSqlServerSinkOptions();
            sinkOpts.TableName = sqlserverLogTable;
            sinkOpts.AutoCreateSqlTable = true;
            var columnOpts = new ColumnOptions();
            columnOpts.Store.Remove(StandardColumn.Properties);
            columnOpts.Store.Add(StandardColumn.LogEvent);
            columnOpts.LogEvent.DataLength = 2048;
            columnOpts.PrimaryKey = columnOpts.TimeStamp;
            columnOpts.TimeStamp.NonClusteredIndex = true;


            loggerConfig
                .ReadFrom.Configuration(config)
                .Enrich.FromLogContext()
                .Enrich.WithMachineName()
                .Enrich.WithAssemblyName()
                .Enrich.WithAssemblyVersion()
                .Enrich.WithAspnetcoreHttpcontext(provider, GetContextInfo)
                .WriteTo.File(rollingFileName)
               .WriteTo.MSSqlServer(
                    connectionString: sqlserverConnectionString,
                    sinkOptions: sinkOpts,
                    columnOptions: columnOpts
                ).CreateLogger();
        }
2 Answers

The UseSerilog calls CreateLogger internally... So either:

  • Do not call CreateLogger yourself and let UseSerilog do it for you
  • Use a different overload for UseSerilog where you give it the ILogger that you create yourself

@C. Augusto Proiete already explained in short... and this is some detail if your want to take a look.

Your code get execute at line 183, cause useReload variable should be null as if you doesn't do anything to the logger, the variable reloadable should be false, as it originally evaluate as ReloadableLogger reloadable = Log.Logger as ReloadableLogger; (what is behind the screen that's not showing directly on that file)

Related