diff --git a/src/Serilog.Expressions/Expressions/BuiltInProperty.cs b/src/Serilog.Expressions/Expressions/BuiltInProperty.cs
index d6892d8..c306662 100644
--- a/src/Serilog.Expressions/Expressions/BuiltInProperty.cs
+++ b/src/Serilog.Expressions/Expressions/BuiltInProperty.cs
@@ -25,4 +25,6 @@ static class BuiltInProperty
public const string Properties = "p";
public const string Renderings = "r";
public const string EventId = "i";
+ public const string TraceId = "tr";
+ public const string SpanId = "sp";
}
\ No newline at end of file
diff --git a/src/Serilog.Expressions/Expressions/Compilation/Linq/LinqExpressionCompiler.cs b/src/Serilog.Expressions/Expressions/Compilation/Linq/LinqExpressionCompiler.cs
index e20c2c6..389aaa1 100644
--- a/src/Serilog.Expressions/Expressions/Compilation/Linq/LinqExpressionCompiler.cs
+++ b/src/Serilog.Expressions/Expressions/Compilation/Linq/LinqExpressionCompiler.cs
@@ -206,6 +206,10 @@ protected override ExpressionBody Transform(AmbientNameExpression px)
BuiltInProperty.Message => Splice(context => new ScalarValue(Intrinsics.RenderMessage(formatter, context))),
BuiltInProperty.Exception => Splice(context =>
context.LogEvent.Exception == null ? null : new ScalarValue(context.LogEvent.Exception)),
+ BuiltInProperty.TraceId => Splice(context =>
+ context.LogEvent.TraceId == null ? null : new ScalarValue(context.LogEvent.TraceId.Value)),
+ BuiltInProperty.SpanId => Splice(context =>
+ context.LogEvent.SpanId == null ? null : new ScalarValue(context.LogEvent.SpanId.Value)),
BuiltInProperty.Timestamp => Splice(context => new ScalarValue(context.LogEvent.Timestamp)),
BuiltInProperty.MessageTemplate => Splice(context => new ScalarValue(context.LogEvent.MessageTemplate.Text)),
BuiltInProperty.Properties => Splice(context =>
diff --git a/src/Serilog.Expressions/Expressions/Runtime/Coerce.cs b/src/Serilog.Expressions/Expressions/Runtime/Coerce.cs
index 27d67f8..b6a3af7 100644
--- a/src/Serilog.Expressions/Expressions/Runtime/Coerce.cs
+++ b/src/Serilog.Expressions/Expressions/Runtime/Coerce.cs
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Serilog.Events;
@@ -77,6 +78,18 @@ public static bool String(LogEventPropertyValue? value, [MaybeNullWhen(false)] o
str = sv.Value.ToString()!;
return true;
}
+
+ if (sv.Value is ActivityTraceId traceId)
+ {
+ str = traceId.ToHexString();
+ return true;
+ }
+
+ if (sv.Value is ActivitySpanId spanId)
+ {
+ str = spanId.ToHexString();
+ return true;
+ }
}
str = default;
diff --git a/src/Serilog.Expressions/Serilog.Expressions.csproj b/src/Serilog.Expressions/Serilog.Expressions.csproj
index 59ad15d..e153087 100644
--- a/src/Serilog.Expressions/Serilog.Expressions.csproj
+++ b/src/Serilog.Expressions/Serilog.Expressions.csproj
@@ -14,15 +14,17 @@
Apache-2.0
https://github.com/serilog/serilog-expressions
git
+ README.md
-
+
+
diff --git a/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv b/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv
index ec85ec1..7c0a43b 100644
--- a/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv
+++ b/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv
@@ -304,3 +304,12 @@ undefined() = undefined() ci ⇶ undefined()
'test' like '%' ⇶ true
'test' like '' ⇶ false
'' like '' ⇶ true
+
+// Built-ins
+
+@m ⇶ 'Hello, World!'
+@mt ⇶ 'Hello, {Name}!'
+tostring(@x) like 'System.DivideByZeroException%' ⇶ true
+@l ⇶ 'Warning'
+@sp ⇶ 'bb1111820570b80e'
+@tr ⇶ '1befc31e94b01d1a473f63a7905f6c9b'
diff --git a/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs b/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs
index 896efd3..6a95839 100644
--- a/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs
+++ b/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs
@@ -1,7 +1,9 @@
+using System.Diagnostics;
using System.Globalization;
using Serilog.Events;
using Serilog.Expressions.Runtime;
using Serilog.Expressions.Tests.Support;
+using Serilog.Parsing;
using Xunit;
namespace Serilog.Expressions.Tests;
@@ -15,14 +17,22 @@ public class ExpressionEvaluationTests
[MemberData(nameof(ExpressionEvaluationCases))]
public void ExpressionsAreCorrectlyEvaluated(string expr, string result)
{
- var evt = Some.InformationEvent();
-
- evt.AddPropertyIfAbsent(
- new("User", new StructureValue(new[]
+ var evt = new LogEvent(
+ new DateTimeOffset(2025, 5, 15, 13, 12, 11, 789, TimeSpan.FromHours(10)),
+ LogEventLevel.Warning,
+ new DivideByZeroException(),
+ new MessageTemplateParser().Parse("Hello, {Name}!"),
+ new []
{
- new LogEventProperty("Id", new ScalarValue(42)),
- new LogEventProperty("Name", new ScalarValue("nblumhardt")),
- })));
+ new LogEventProperty("Name", new ScalarValue("World")),
+ new LogEventProperty("User", new StructureValue(new[]
+ {
+ new LogEventProperty("Id", new ScalarValue(42)),
+ new LogEventProperty("Name", new ScalarValue("nblumhardt")),
+ }))
+ },
+ ActivityTraceId.CreateFromString("1befc31e94b01d1a473f63a7905f6c9b"),
+ ActivitySpanId.CreateFromString("bb1111820570b80e"));
var frFr = CultureInfo.GetCultureInfoByIetfLanguageTag("fr-FR");
var testHelpers = new TestHelperNameResolver();