Skip to content

ANSI terminal themes; culture-specific formatting #38

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

Merged
merged 10 commits into from
May 31, 2021

Conversation

nblumhardt
Copy link
Member

@nblumhardt nblumhardt commented May 31, 2021

Fixes #8, fixes #19.

Theming is implemented by the TemplateTheme class; built-in themes are TemplateTheme.Code, TemplateTheme.Grayscale, and TemplateTheme.Literate, which were lifted directly from Serilog.Sinks.Console.

Themes can be user-specified, and can inherit from a "base" theme:

var melon = new TemplateTheme(TemplateTheme.Literate, new Dictionary<TemplateThemeStyle, string>
{
    // `Information` is dark green in MEL.
    [TemplateThemeStyle.LevelInformation] = "\x1b[38;5;34m",
    [TemplateThemeStyle.String] = "\x1b[38;5;159m",
    [TemplateThemeStyle.Number] = "\x1b[38;5;159m"
});

using var log = new LoggerConfiguration()
    .WriteTo.Console(new ExpressionTemplate(
        "{@l:w4}: {SourceContext}\n" +
        "{#if Scope is not null}" +
        "      {#each s in Scope}=> {s}{#delimit} {#end}\n" +
        "{#end}" +
        "      {@m}\n" +
        "{@x}",
        theme: melon))
    .CreateLogger();

Produces:

image

(LOL 😁)

Only ANSI escape sequence-based theming is supported (so on Windows, only recent versions of the console will support them, along with Windows Terminal).

Themed message template rendering touched on support for IFormatProvider, so I've rolled in those changes, too.

There's minor API breakage, with optional or nullable IFormatProvider arguments added to the various SerilogExpression factory methods, and optional/nullable TemplateTheme arguments added to the ExpressionTemplate constructors/factory methods.

Fun twist - since the same templating implementation is used for text and JSON output, you can also do this:

image

Perf impact shouldn't be huge, and since more work is brought back to template "compile" time (there are no runtime dictionary lookups), I'm expecting that theming will be slightly faster here than in Serilog.Sinks.Console, but that's for another day.

Tests are also a bit light, but the code paths covered by themed and un-themed output are identical apart from the behavior implemented in the (tiny) Style and StyleReset structs, so I think I can get away with it 😉

Assert.True(parser.TryParse("{x}", out var template, out _));
var avt = Assert.IsType<FormattedExpression>(template);
Assert.Null(avt.Alignment);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test for a small bugfix that's also included - the parser was defaulting alignment to 0/Left, so some unnecessary buffering was performed.

@nblumhardt
Copy link
Member Author

Not anticipating that anyone is going to want to/have the time to review this sprawling PR, so sending it out into the wild via -dev so that some feedback can be collected. 👀 welcome, though :-)

@nblumhardt nblumhardt merged commit 81a525a into serilog:dev May 31, 2021
@nblumhardt nblumhardt mentioned this pull request Jun 2, 2021
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

Successfully merging this pull request may close these issues.

Make the specified format provider (culture) available to runtime operations Console theme support
1 participant