31

I'm trying to configure Serilog for a .NET Core project. Here's what I have in my appsettings.json:

 "Serilog": 
{
    "MinimumLevel": "Verbose",
    "Enrich": ["FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId"],
    "WriteTo": [
      { "Name": "RollingFile",
        "Args": {
          "pathFormat": "C:/Logfiles/testapp/log-{Date}.json",
          "textFormatter": "JsonFormatter",
          "fileSizeLimitBytes": 2147483648,
          "retainedFileCountLimit": 5
        }
      }
    ]
  }

The problem I see is that JsonFormatter is not picked up, and instead I get entries using the default text formatter. I tried using "formatter": "JsonFormatter", but got the same result.

It all works fine if I configure Serilog in code:

var jsonSink = new RollingFileSink(config["Logger:FilePath"], new JsonFormatter(), 2147483648, 5);

var logger = new Serilog.LoggerConfiguration().WriteTo.Sink(jsonSink);

Here is the relevant section of my project.json:

"Serilog": "2.2.1",
"Serilog.Extensions.Logging": "1.1.0",
"Serilog.Sinks.Literate": "2.0.0",
"Serilog.Sinks.Seq": "2.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Serilog.Enrichers.Thread": "2.0.0",
"Serilog.Enrichers.Process": "2.0.0",
"Serilog.Sinks.ColoredConsole": "2.0.0",
"Serilog.Settings.Configuration": "2.2.0"
GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Alexander
  • 1,317
  • 1
  • 12
  • 12

5 Answers5

23

The formatter argument needs to be a fully-qualified type name. Try:

"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101
  • Thanks @Nicholas Blumhardt, unfortunately I'm still getting the same result... Any chance of adding this example to the documentation? – Alexander Nov 30 '16 at 05:41
  • Hi @Alexander - did you change the parameter name from `textFormatter` to `formatter`? – Nicholas Blumhardt Nov 30 '16 at 21:30
  • 2
    Yes @Nicholas Blumhardt, here's how the updated config looks like: { "Name": "RollingFile", "Args": { "pathFormat": "C:/Logfiles/testapp/log-{Date}.json", "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog", "fileSizeLimitBytes": 2147483648, "retainedFileCountLimit": 5 } } – Alexander Nov 30 '16 at 22:37
  • 1
    Are you using the latest (2.2.0) version of Serilog.Settings.Configuration? We recently investigated this for another user who was still using 2.0.0: https://github.com/serilog/serilog-settings-configuration/issues/31 - Cheers! – Nicholas Blumhardt Dec 01 '16 at 03:01
  • yes, I'm using `Serilog.Settings.Configuration 2.2.0`, I've updated my question with a relevant section of my `project.json`. – Alexander Dec 01 '16 at 03:24
  • @NicholasBlumhardt, mine is not working either. Please see the answer below. Is there anything that doesn't make sense to you? – Jeremy Ray Brown Dec 29 '16 at 17:07
  • 4
    @NicholasBlumhardt. It is working now. I made the silliest error. I accidentally made the "Serilog" node a subsection of another node in the appsettings.json file. – Jeremy Ray Brown Dec 29 '16 at 17:11
  • @Alexander, the Serilog packages I'm using: (1) `"Serilog": "2.3.0"`, (2) `"Serilog.Extensions.Logging": "1.3.1"`, (3) `"Serilog.Sinks.RollingFile": "3.2.0"`, (4) `"Serilog.Sinks.File": "3.1.1"`, (5) `"Serilog.Settings.Configuration": "2.2.0"` – Jeremy Ray Brown Dec 29 '16 at 17:18
  • 1
    Thanks for the follow-up @JeremyRayBrown – Nicholas Blumhardt Dec 29 '16 at 22:25
17

The following works:

var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "C:\\logs\\log-{Date}.txt"),
                            outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}")
            //.ReadFrom.Configuration(Configuration)
            .CreateLogger();

        Log.Logger.Information("test");

The following also works (only showing CreateLogger portion):

Log.Logger = new LoggerConfiguration()
            //.MinimumLevel.Debug()
            //.WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "C:\\logs\\log-{Date}.txt"),
            //                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}")
            .ReadFrom.Configuration(Configuration)
            .CreateLogger();

The appsettings.json file (relevant section here is Serilog):

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Serilog": {
    "MinimumLevel": "Debug",
    "WriteTo": [
      {
        "Name": "RollingFile",
        "Args": {
          "pathFormat": "C:\\logs\\log-{Date}.txt",
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}"
        }
      }
    ]
  }
}

The NuGet packages in project.json:

  • "Serilog": "2.3.0",
  • "Serilog.Extensions.Logging": "1.3.1",
  • "Serilog.Sinks.RollingFile": "3.2.0",
  • "Serilog.Sinks.File": "3.1.1",
  • "Serilog.Settings.Configuration": "2.2.0"

My target framework is net452.

Jeremy Ray Brown
  • 1,499
  • 19
  • 23
  • 1
    Jeremy Ray Brown, as far as I can see you're not using a Json formatter - this is the bit that I couldn't get working. RollingFile itself works fine. – Alexander Jan 05 '17 at 22:56
  • Okay. Misunderstanding. I will follow up when I use Json Formatter. – Jeremy Ray Brown Jan 18 '17 at 21:27
  • 1
    `Serilog.AspNetCore 3.0.0` now includes all these packages as dependencies, so you only need to explicitly include `Serilog.AspNetCore`. – Yahoo Serious Aug 30 '19 at 07:18
  • 2
    @YahooSerious i had Serilog.AspNetCore package but was not logging in file via appsettings configuration, installing the above packages solved it – Ehsan Sajjad Feb 21 '20 at 12:47
  • Why is `"IncludeScopes": false,` under `"Logging": {`? https://json.schemastore.org/appsettings.json says it has to be under `FormatterOptions` – David Klempfner Sep 14 '21 at 04:10
14

This works fine for me. "RollingFile" is no longer supported, hence "File" and "pathFormat" is just "path"

"Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Debug",
        "System": "Debug"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "===> {Timestamp:HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\Temp\\Logs\\log-appstngs.log",
          "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}",
          "rollOnFileSizeLimit": true,
          "fileSizeLimitBytes": 4194304,
          "retainedFileCountLimit": 10,
          "rollingInterval": "Minute"
        }
      }
    ]
  },
Mujib Khan
  • 206
  • 2
  • 5
4

The folowing configuration works:

"Serilog": {
"Using": [ "Serilog.Sinks.Console" ],
"MinimumLevel": "Information", 
"WriteTo": [
  {
    "Name": "Console",
    "Args": {
      "outputTemplate": "===> {Timestamp:HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
    }
  },
  {
    "Name": "RollingFile",
    "Args": {
      "pathFormat": "Logs\\log-{Date}.json",
      "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
      "fileSizeLimitBytes": 104857600
    }
  }


 ]
}

In Program.cs:

public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
            .AddEnvironmentVariables()
            .Build();    
public static void Main(string[] args)
            {
                Log.Logger = new LoggerConfiguration()
                    .ReadFrom.Configuration(Configuration)
                    .CreateLogger();
    ...
    }

and

public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseConfiguration(Configuration)
                .ConfigureLogging(log => { log.AddSerilog(Log.Logger); })
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

And inject logger to your controller:

public class UsersController : ControllerBase
{
private readonly ILogger<UsersController> _logger;

  public UsersController(ILogger<UsersController> logger)
     {
      _logger = logger;        
     }
     //your code
    }

Example of result which I got:

{
"@t": "2019-04-12T14:03:08.2789776Z",
"@mt": "GetUserMessages()=> ",
"@r": [
    "000117"
],
"Elapsed": 117,
"SourceContext": "MyProject.Web.Controllers.UsersController",
"ActionId": "1b8bc4b9-5858-415b-ab4e-56ba14a5a1ca",
"ActionName": "MyProject.Web.Controllers.UsersController.GetUserMessages (MyProject.Web)",
"RequestId": "0HLLVSDFSA43ES:00000001",
"RequestPath": "/TestAppId/messages",
"CorrelationId": null,
"ConnectionId": "0HLLVSDFSA43ES"
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Dmytro
  • 71
  • 7
  • How did you include extra properties in the json? My log only has the @ properties. – rbasniak Sep 14 '20 at 21:20
  • 1
    @RBasniak first of all you have to check what "MinimumLevel" of logging you use. If you use my configuration - check the object which you want to log. In my example I used special middleware witch collect extra information about request but I can't post this code here. – Dmytro Sep 15 '20 at 09:02
  • --> needs to install packages Serilog.Formatting.Compact and Serilog.Formatting.Compact.CompactJsonFormatter from nuGet – Felipe Augusto Apr 08 '21 at 03:05
1

I realize, this is an old post, but no answer was accepted to date. So, here is what I see as a problem: formatter class was selected, yet its namespace was not specified. Something like the following worked for me:

"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog.Formatting.Json"
Mike O.
  • 61
  • 6