0

I am using Serilog in a .Net 5 application, and I am configuring it loading the configuration from appsettings.{env}.json.

In this file I want to specify a different minimum logging level for each sink, and I would like to control it with a LevelSwitch so that I don't need to restart my application only for changing this. To achieve this, I know that restrictedToMinimumLevel can be specified for each sink, but I cannot find an example where it is controlled by a switch. It seems it can only be a string with the logging level, since when I tried to bind it to a switch I got this exception:

System.InvalidOperationException: 'Cannot create instance of type 'Serilog.Events.LogEventLevel' because it is missing a public parameterless constructor.'

Am I missing something? How can I set the minimum logging level for each sink to be easily changed at runtime without restarting my application?

These are my settings:

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "LevelSwitches": {
      "$baseSwitch": "Verbose",
      "$consoleSwitch": "Warning"
    },
    "MinimumLevel": {
      "ControlledBy": "$baseSwitch"
    },
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          //"restrictedToMinimumLevel": "Warning",   ---> this works
          //"restrictedToMinimumLevel": {            ---> this is what I need, but doesn't work
          //  "ControlledBy": "$consoleSwitch"
          //},
          "outputTemplate": "{Timestamp} [{Level:u3}] [{LogSource}]: {Message} {Properties}{NewLine}{Exception}"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "Logs/log.txt"
        }
      }
    ],
    "Enrich": [
      "FromLogContext"
    ]
  }
}

I am open also to other solutions. Thank you.

maradev21
  • 576
  • 2
  • 6
  • 20

1 Answers1

2

The name of the level switch reference should not have the $ prefix. The $ prefix is only for referencing the level switch declared

{
    "Serilog": {
        "LevelSwitches": { "consoleSwitch": "Verbose" }, <<<< No $ prefix
        "WriteTo": [
            {
                "Name": "Console",
                "Args": {
                    "levelSwitch": "$consoleSwitch" <<<<<< $ prefix
                }
            }
        ]
    }
}

Also, the name of the argument for the level switch has to match what's declared in the extension method for the sink. In the case of the Console sink, it's called levelSwitch.

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
  • thank you for your answer, using `levelSwitch` it works as expected. One question: I think that setting the minimum log level and updating it at runtime is some basic stuff that should be somehow available in all the sinks (but maybe this is my idea): why isn't this standardized somehow, to have a common syntax? Is there a reason? – maradev21 Oct 06 '21 at 08:51
  • and for the `$` prefix, I copied the usage from some examples found online, and I can say it works both with and without. Is there a preferred/recommended way to handle them? – maradev21 Oct 06 '21 at 08:53
  • Sinks are developed by different developers and it's up to them to follow a standard naming convention. Not something Serilog can enforce... – C. Augusto Proiete Oct 06 '21 at 12:06
  • The `$` prefix implies a reference to an existing name, so should be used only when your goal is to tell Serilog that you're referencing an existing name – C. Augusto Proiete Oct 06 '21 at 12:08