You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note the use of `{Items[0]}`: "holes" in expression templates can include any valid expression.
99
+
Note the use of `{Cart[0]}`: "holes" in expression templates can include any valid expression over properties from the event.
97
100
98
101
Newline-delimited JSON (for example, replicating the [CLEF format](https://github.com/serilog/serilog-formatting-compact)) can be generated
99
102
using object literals:
@@ -109,7 +112,7 @@ using object literals:
109
112
110
113
The following properties are available in expressions:
111
114
112
-
***All first-class properties of the event**— no special syntax: `SourceContext` and `Items` are used in the formatting example above
115
+
***All first-class properties of the event**— no special syntax: `SourceContext` and `Cart` are used in the formatting examples above
113
116
*`@t` - the event's timestamp, as a `DateTimeOffset`
114
117
*`@m` - the rendered message
115
118
*`@mt` - the raw message template
@@ -149,7 +152,7 @@ A typical set of operators is supported:
149
152
* Accessors `a.b`
150
153
* Indexers `a['b']` and `a[0]`
151
154
* Wildcard indexing - `a[?]` any, and `a[*]` all
152
-
* Conditional `if a then b else c` (all branches required)
155
+
* Conditional `if a then b else c` (all branches required; see also the section below on _conditional blocks_)
153
156
154
157
Comparision operators that act on text all accept an optional postfix `ci` modifier to select case-insensitive comparisons:
155
158
@@ -195,6 +198,64 @@ Functions that compare text accept an optional postfix `ci` modifier to select c
195
198
StartsWith(User.Name, 'n') ci
196
199
```
197
200
201
+
### Template directives
202
+
203
+
#### Conditional blocks
204
+
205
+
Within an `ExpressionTemplate`, a portion of the template can be conditionally evaluated using `#if`.
206
+
207
+
```csharp
208
+
Log.Logger=newLoggerConfiguration()
209
+
.WriteTo.Console(newExpressionTemplate(
210
+
"[{@t:HH:mm:ss} {@l:u3}{#if SourceContext is not null} ({SourceContext}){#end}] {@m}\n{@x}"))
211
+
.CreateLogger();
212
+
213
+
// Produces log events like:
214
+
// [21:21:45 INF] Starting up
215
+
// [21:21:46 INF (Sample.Program)] Firing engines
216
+
```
217
+
218
+
The block between the `{#if <expr>}` and `{#end}` directives will only appear in the output if `<expr>` is `true` - in the example, events with a `SourceContext` include this in parentheses, while those without, don't.
219
+
220
+
It's important to notice that the directive requires a Boolean `true` before the conditional block will be evaluated. It wouldn't be sufficient in this case to write `{#if SourceContext}`, since no values other than `true` are considered "truthy".
221
+
222
+
The syntax supports `{#if <expr>}`, chained `{#else if <expr>}`, `{#else}`, and `{#end}`, with arbitrary nesting.
223
+
224
+
#### Repetition
225
+
226
+
If a log event includes structured data in arrays or objects, a template block can be repeated for each element or member using `#each`/`in` (newlines, double quotes and construction of the `ExpressionTemplate` omitted for clarity):
227
+
228
+
```
229
+
{@l:w4}: {SourceContext}
230
+
{#each s in Scope}=> {s}{#delimit} {#end}
231
+
{@m}
232
+
{@x}
233
+
```
234
+
235
+
This example uses the optional `#delimit` to add a space between each element, producing output like:
236
+
237
+
```
238
+
info: Sample.Program
239
+
=> Main => TextFormattingExample
240
+
Hello, world!
241
+
```
242
+
243
+
When using `{#each <name> in <expr>}` over an object, such as the built-in `@p` (properties) object, `<name>` will be bound to the _names_ of the properties of the object.
244
+
245
+
To get to the _values_ of the properties, use a second binding:
246
+
247
+
```
248
+
{#each k, v in @p}{k} = {v}{#delimit},{#end}
249
+
```
250
+
251
+
This example, if an event has three properties, will produce output like:
The syntax supports `{#each <name>[, <name>] in <expr>}`, an optional `{#delimit}` block, and finally an optional `{#else}` block, which will be evaluated if the array or object is empty.
258
+
198
259
## Recipes
199
260
200
261
**Trim down `SourceContext` to a type name only:**
0 commit comments