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

Can't use #delimit within an #if block inside a #each loop #107

Closed
MichaelIDS opened this issue Nov 16, 2023 · 3 comments · Fixed by #108
Closed

Can't use #delimit within an #if block inside a #each loop #107

MichaelIDS opened this issue Nov 16, 2023 · 3 comments · Fixed by #108
Labels
bug Something isn't working

Comments

@MichaelIDS
Copy link

MichaelIDS commented Nov 16, 2023

Description
I get a syntax error when embedding a #delimit within an #if block inside a #each loop.
I already log a "StackTrace" property when its present using an #if block to log it first. So then wanted to log the rest of the unused properties excluding it.
I have to add the StackTrace as context with an enricher for a number of 3rd party exceptions that exclude the StackTrace from their ToString(), So SeriLog.Exceptions didn't help on this,

Reproduction
My attempted formatter template included:
{#if Rest(true) <> {}}{#each name, value in Rest(true)}{#if name <> 'StackTrace'}{name}: {value}{#delimit},{#end}{#end}\n{#end}

Expected behavior
I hoped I could use the delimit as per https://github.com/serilog/serilog-expressions#repetition
But with my filter on which properties to log.

Relevant package, tooling and runtime versions
Using current stable Serilog nuget releases.
SeriLog Expressions: 4.0.0

Context
I use an enricher to add the StackTrace from these specific exception types as a property. Then use the below full formatter template. Note it does the delimiter manually and so includes a trailing one. Pus it has wrapping brackets around the properties, which makes it a bit messy to read.
"template": "{UtcDateTime(@t):yyyy-MM-dd HH:mm:ss.fff} +00:00 [{@l}] {@m}\n{#if @x is not null}{@x}{#end}{#if Length(@p['StackTrace']) > 0}{@p.StackTrace}\n{#end}{#if Rest(true) <> {}}{{{#each name, value in Rest(true)}{#if name <> 'StackTrace'}{name}: {value}, {#end}{#end}}}\n{#end}"
If there is a better way to approach filtering the results from Rest(true) that would be most ideal, but I couldn't see any way and appreciate this is a bit of an odd usage situation.

@MichaelIDS MichaelIDS added the bug Something isn't working label Nov 16, 2023
@nblumhardt
Copy link
Member

Hi! Thanks for the report.

The delimit block is part of the each expression, it can't be nested under an if block.

But the bug here is that Rest() should be ignoring StackTrace because it's referenced by the template, as @p.StackTrace. The @p prefix is throwing things off. Sending a bug fix now.

The workaround (working version) is:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(new ExpressionTemplate(
        "{UtcDateTime(@t):yyyy-MM-dd HH:mm:ss.fff} +00:00 [{@l}] {@m}\n" +
        "{#if @x is not null}{@x}{#end}" +
        "{#if Length(StackTrace) > 0}{StackTrace}\n{#end}" +
        "{#if Rest(true) <> {}}" +
            "{{" +
            "{#each name, value in Rest()}" +
                "{name}: {value}" +
            "{#delimit}, " +
            "{#end}" +
            "}}\n" +
        "{#end}"))
    .CreateLogger();

@MichaelIDS
Copy link
Author

ah, I had assumed Rest() only applied to properties in the eventLog message, rather than ones used in the template sent to the sink. Or that's how I read the projects documentation at least. So when Rest() is changed updating its documentation would be beneficial.
Very nice library btw.

@MichaelIDS
Copy link
Author

On just checking your example again I see the direct usage of StackTrace and looking over the github documentation again I see the below that I missed/didn't appreciate when doing this the first time. Although there was a lot of back and forth for me at the time trying to find a working solution, so not too surprising really.
This does resolve my #delim issue, thanks 👍
All first-class properties of the event - no special syntax: SourceContext and Cart are used in the formatting examples above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants