Serilog setup for Asp.Net Core 2.0.1 not producing logs

5

I am trying to set up Serilog as my logger in a multi project solution using Asp.Net Core 2.0.1, EF 2.0.1 and MVC 6.

I have set up Serilog, mostly following the guidelines from this blog post Set up Serilog post

There is a problem with the json in that post, which I've corrected and is shown here

appsettings.json file

{
"ApplicationConfiguration": {
  "ConnectionStrings": {
    "DevelopmentConnection": "Server=(localdb)\\mssqllocaldb;Database=TestingConfigurationNetCoreTwo_Development;Trusted_Connection=True;MultipleActiveResultSets=true"      
  },      
  "ApplicationInfo": {
    "VersionNumber": "1.0.0",
    "Author": "Jimbo",
    "ApplicationName": "CustomTemplate",
    "CreatedOn": "November 20, 2017"
  },
  "Serilog": {
    "Using": [
      "Serilog.Sinks.RollingFile",
      "Serilog.Sinks.Async",
      "Serilog.Sinks.ApplicationInsights",
      "Serilog.Sinks.Console",
      "Serilog.Sinks.Seq"
    ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "Async",
        "Args": {
          "configure": [
            {
              "Name": "RollingFile",
              "Args": { "pathFormat": "Logs/log-{Date}.log" }
           }
          ]
        }
      }
    ],
    "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],
    "Properties": {
      "Application": "CustomTemplate" 
    }
  }
}
}

I have the logger configuration work in the Main method of Program.cs

public static int Main(string[] args)
{
    var currentEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); 

    var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{currentEnv}.json", optional: true)
        .AddEnvironmentVariables()
        .Build();

    //Configure logger
    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(configuration)
        //do this for now
        //TODO:figure out how to add to Serilog config in appsettings.json
        .WriteTo.Seq("http://localhost:5341")
        .CreateLogger();

    Log.Information("Logger created");

    try
    {
        Log.Information("Starting web host");
        BuildWebHost(args).Run();
        return 0;
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "Web Host terminated unexpectedly");
        return 1;
    }
    finally
    {
        Log.CloseAndFlush();
    }
    //BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();

And in my Startup method

services.AddLogging(loggingBuilder =>
            loggingBuilder.AddSerilog(dispose: true));

I was assuming Serilog would create the Logs folder once I ran the application, but no Log folder or logs. I added a Logs folder to both the root of the solution, and the web app project and ran it again. No logs. The blog post author suggested looking in the machines root folder. I looked both in C and OneDrive main folders (Solution Files stored on OneDrive) but there were no logs there either.

I then noticed a stack trace warning

System.IO.FileNotFoundException occurred HResult=0x80070002 Message=The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\Users\OneDrive\TestingConfigurationAspNetCore2\TestMvcApp\bin\Debug\netcoreapp2.0\appsettings.json'. Source= StackTrace: at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload) at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load() at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers) at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()

I was getting this warning before, which is why I added the set bath path method in the configuration set up, because the application was failing at the code line

.AddJsonFile("appsettings.json")

which was fairly obvious because in the bin folder the file isn't called appsettings.json, its called TestMvcApp.runtimeconfig.json.

Once I added .SetBasePath, the code ran through so I put a breakpoint after the configuration setup. The configuration object contains all the settings from my appsettings.json file, so why I am getting that stack trace error? I don't know but I'll bet a dollar it is why there are no logs (no log messages appear in the console either)

Any help on why the stack trace error or why there are no log messages being written to the log file or displayed on the console would be most appreciated.

c#
json
logging
asp.net-core-2.0
serilog
asked on Stack Overflow Nov 27, 2017 by dinotom • edited Nov 27, 2017 by CodeFuller

2 Answers

4

which was fairly obvious because in the bin folder the file isn't called appsettings.json, its called TestMvcApp.runtimeconfig.json.

TestMvcApp.runtimeconfig.json is not your appsettings.json, it's a runtime configuration file as it's clear from the file name.

I bet that your appsettings.json is just not copied to the output directory during the build. To fix that select appsettings.json in Visual Studio Solution explorer, in context menu select properties and set 'Copy to Output Directory' to 'Copy always' or 'Copy if newer':

Also your json configuration has several issues:

  1. Serilog section should not be inside ApplicationConfiguration section. It should be on the same level, i.e top-level section.
  2. You also has suspicious WriteTo section with one sink (RollingFile) inside another (Async). Check here sample json configuration for Serilog.
  3. In order to use all those sinks (Serilog.Sinks.RollingFile, Serilog.Sinks.Console) you should install corresponding sink NuGets: Serilog.Sinks.RollingFile, Serilog.Sinks.Console, etc.

Here is configuration file (with RollingFile sink only) that works fine for me:

{
    "ApplicationConfiguration": {
        "ConnectionStrings": {
            "DevelopmentConnection": "Server=(localdb)\\mssqllocaldb;Database=TestingConfigurationNetCoreTwo_Development;Trusted_Connection=True;MultipleActiveResultSets=true"
        },
        "ApplicationInfo": {
            "VersionNumber": "1.0.0",
            "Author": "Jimbo",
            "ApplicationName": "CustomTemplate",
            "CreatedOn": "November 20, 2017"
        }
    },
    "Serilog": {
        "Using": [
            "Serilog.Sinks.RollingFile"
        ],
        "MinimumLevel": {
            "Default": "Information",
            "Override": {
                "Microsoft": "Warning"
            }
        },
        "WriteTo": [
            {
                "Name": "RollingFile",
                "Args": { "pathFormat": "c:\\log-{Date}.log" }
            }
        ],
        "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
        "Properties": {
            "Application": "CustomTemplate"
        }
    }
}

enter image description here

answered on Stack Overflow Nov 27, 2017 by CodeFuller • edited Nov 27, 2017 by CodeFuller
1

The accepted answer only logged some messages for my project. I'm not sure why. Ondrej Balas's approach worked better for me.

Install these Nuget packages:

  • Serilog
  • Serilog.AspNetCore
  • Serilog.Settings.Configuration
  • Serilog.Sinks.Console
  • Serilog.Sinks.RollingFile

Program.cs needs .UseSerilog() added:

    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>

        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            })
            .UseStartup<Startup>()
            .UseSerilog()
            .Build();

Startup.cs needs a couple of changes

one in the constructor:

    public Startup(IConfiguration configuration)
    {
        Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();

        Configuration = configuration;
    }

another in Configure():

    loggerFactory.AddSerilog();

    if (env.IsDevelopment())
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    }

appsettings.json needs a Serilog config entry in root:

"Serilog": {
    "Using": [ "Serilog.Sinks.Console" ],
    "MinimumLevel": {
        "Default": "Information",
        "Override": {
            "Microsoft": "Warning",
            "System": "Warning"
        }
    },
    "WriteTo": [
        { "Name": "Console" },
        {
            "Name": "RollingFile",
            "Args": {
                "pathFormat": "logs\\log-{Date}.log",
                "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] {Message}{NewLine}{Exception}"
            }
        }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
    "Properties": {
        "Application": "My Application"
    }
}
answered on Stack Overflow Aug 21, 2018 by jaycer • edited Aug 22, 2018 by jaycer

User contributions licensed under CC BY-SA 3.0