serilog / serilog-expressions

An embeddable mini-language for filtering, enriching, and formatting Serilog events, ideal for use with JSON or XML configuration.
Apache License 2.0
190 stars 17 forks source link

Basic string quoting does not work #93

Closed xnoreq closed 1 year ago

xnoreq commented 1 year ago

Description No matter if I use {@m:lj} or {@m] in the expression template, template variables with string values are not quoted in the resulting formatted string.

The json-formatting flag is also ignored.

Reproduction

            using var l1 = new LoggerConfiguration().WriteTo.Console(new ExpressionTemplate("[{@t:HH:mm:ss} {@l:u3}] {@m:lj}\n{@x}")).CreateLogger();
            l1.Error("Test {A} {@B} {C}", "A", new { X = 1}, 3);

            using var l2 = new LoggerConfiguration().WriteTo.Console(new ExpressionTemplate("[{@t:HH:mm:ss} {@l:u3}] {@m}\n{@x}")).CreateLogger();
            l1.Error("Test {A} {@B} {C}", "A", new { X = 1 }, 3);

            using var l3 = new LoggerConfiguration().WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:j}{NewLine}{Exception}", theme: Serilog.Sinks.SystemConsole.Themes.ConsoleTheme.None).CreateLogger();
            l3.Error("Test {A} {@B} {C}", "A", new { X = 1 }, 3);

Expected behavior The value of A is quoted in the output.

Actual behavior

[18:21:29 ERR] Test A {"X":1} 3
[18:21:29 ERR] Test A {"X":1} 3
[18:21:29 ERR] Test "A" {"X": 1} 3

Relevant package, tooling and runtime versions Serilog 2.12.0 Expressions 3.4.1 Sinks.Console 4.1.0

nblumhardt commented 1 year ago

Hi! There isn't any plan or intention to implement this style of output in Serilog.Expressions - @m is rendered using :lj by default, and no other formats are supported.

If you're trying to match the original Console() output it's probably best to stick with outputTemplate as in your third example, at this point.

Hope this helps, Nick

xnoreq commented 1 year ago

In the real world I'm also using a substring of SourceContext in the template, which is not possible with OutputTemplateRenderer.

nblumhardt commented 1 year ago

If you have to match an existing format, your best bet here is to register a custom function to format the message the old way; e.g.:

public static class MyFunctions
{
    public static LogEventPropertyValue? QuotedMessage(LogEvent evt)
    {
        return new ScalarValue(evt.MessageTemplate.Render(evt.Properties));
    }
}

And:

var myFunctions = new StaticMemberNameResolver(typeof(MyFunctions));
var expr = SerilogExpression.Compile(
    "[{@t:HH:mm:ss} {@l:u3}] {QuotedMessage()}\n{@x}"",
    nameResolver: myFunctions);

(May need some testing/syntax checking :-))