Closed MichaelIDS closed 1 year ago
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();
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.
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
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 fromRest(true)
that would be most ideal, but I couldn't see any way and appreciate this is a bit of an odd usage situation.