Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuring Console with empty OutputTemplate overrides the use of a custom formatter #321

Open
LordMike opened this issue Aug 12, 2022 · 1 comment

Comments

@LordMike
Copy link

LordMike commented Aug 12, 2022

I'm trying to make an app that has a default console output format (With an OutputTemplate), but is otherwise overridable by configs (environment variables in my case).

I've made an example app to show my issue. I have a config like this:

{
  "Logging": {
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "OutputTemplate": "My custom template"
        }
      }
    ]
  }
}

I can then use it:

var config = new ConfigurationBuilder()
    .AddJsonFile("config.json")
    .Build();

var logger = new LoggerConfiguration()
    .ReadFrom.Configuration(config, "Logging")
    .CreateLogger();

logger.Information("Hello world");

Which outputs

My custom template

So far so good.
Now I want my users to use environment variables (or something else) to override the configs, and potentially use a custom formatter, like RenderedCompactJsonFormatter. So we add in environment variables to our config builder, and add the following:

Logging__WriteTo__0__Args__formatter__type: Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact

But this doesn't override the OutputTemplate, it still outputs My custom template - if I remove the OutputTemplate from the config json (using the default from the Console sink), the environment variable works - it switches to json rendering.

I've also tried overriding the template with a blank string, like:

Logging__WriteTo__0__Args__OutputTemplate: ""

.. but this just changes the output template to a blank string - it's still used.

From what I read, Microsoft.Extensions.Configuration doesn't support unsetting values, you cannot f.ex. configure a specific key to null, and have it removed from the system. The closest you can get, is overriding a value with a blank string, and have that be a convention to be "unset". For example, this blog post also highlights the issue:

I mentioned overriding with an empty string as a “fake way” to remove configuration. Specifying null as a value, even in JSON config, doesn’t work. It reads the value and uses an empty string as the value instead of null. Further, there’s no XML analogy to null, nor are there such analogies in most other providers.

Given everything in the config system is a key/value string pair, the closest you can get, then, is to set things to empty strings. When you read values, check for String.IsNullOrEmpty() before using the value.

Are there any tips on how I can provide a custom default template, but let users override my config using Microsofts configuration system?

  • Should I focus on skipping my default template, and leave it unset from the beginning?
  • Should I add a PR to this repo, that checks if a value from Microsoft.Extensions.Configuration is String.Empty, and consider it "null" ?
  • Should I add a PR to Serilog, specifically to ignore the settings set and use the formatter if the formatter is set (so it takes precedence)?

I think I'm going with skipping the custom format by default, in order to let users override the formatter - but I think there might be a general issue here :).

@nblumhardt
Copy link
Member

nblumhardt commented Aug 12, 2022

Microsoft.Extensions.Configuration is a bit tricky at times 🤔

Using Serilog.Expressions and an expression template, through the formatter argument:

#281

will let you switch between JSON and plain text output by modifying the same configuration settings (formatter.template).

HTH!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants