Skip to content

Commit 0f8ccf2

Browse files
committed
Support TraceId and SpanId output template tokens
1 parent da9c6ca commit 0f8ccf2

File tree

9 files changed

+152
-43
lines changed

9 files changed

+152
-43
lines changed

sample/ConsoleDemo/ConsoleDemo.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFrameworks>netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net452;net462;net472;net48;net5.0</TargetFrameworks>
5+
<TargetFramework>net7.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>

sample/SyncWritesDemo/SyncWritesDemo.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net5.0</TargetFramework>
5+
<TargetFramework>net7.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,50 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Description>A Serilog sink that writes log events to the console/terminal.</Description>
4+
<VersionPrefix>5.0.0</VersionPrefix>
5+
<Authors>Serilog Contributors</Authors>
6+
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net471</TargetFrameworks>
7+
<TargetFrameworks>$(TargetFrameworks);netstandard2.1;netstandard2.0;net5.0;net6.0;net7.0</TargetFrameworks>
8+
<Nullable>enable</Nullable>
9+
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
10+
<SignAssembly>true</SignAssembly>
11+
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
12+
<PackageTags>serilog;console;terminal</PackageTags>
13+
<PackageIcon>icon.png</PackageIcon>
14+
<PackageProjectUrl>https://github.com/serilog/serilog-sinks-console</PackageProjectUrl>
15+
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
16+
<RepositoryUrl>https://github.com/serilog/serilog-sinks-console</RepositoryUrl>
17+
<RepositoryType>git</RepositoryType>
18+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
19+
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
20+
<RootNamespace>Serilog</RootNamespace>
21+
<LangVersion>latest</LangVersion>
22+
<PackageReadmeFile>README.md</PackageReadmeFile>
23+
</PropertyGroup>
224

3-
<PropertyGroup>
4-
<Description>A Serilog sink that writes log events to the console/terminal.</Description>
5-
<VersionPrefix>4.2.0</VersionPrefix>
6-
<Authors>Serilog Contributors</Authors>
7-
<TargetFrameworks>net45;netstandard1.3;netstandard2.0;net5.0</TargetFrameworks>
8-
<LangVersion>8.0</LangVersion>
9-
<Nullable>enable</Nullable>
10-
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
11-
<SignAssembly>true</SignAssembly>
12-
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
13-
<PackageTags>serilog;console;terminal</PackageTags>
14-
<PackageIcon>icon.png</PackageIcon>
15-
<PackageProjectUrl>https://github.com/serilog/serilog-sinks-console</PackageProjectUrl>
16-
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
17-
<RepositoryUrl>https://github.com/serilog/serilog-sinks-console</RepositoryUrl>
18-
<RepositoryType>git</RepositoryType>
19-
<GenerateDocumentationFile>true</GenerateDocumentationFile>
20-
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
21-
<TreatSpecificWarningsAsErrors />
22-
<RootNamespace>Serilog</RootNamespace>
23-
<LangVersion>latest</LangVersion>
24-
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(TargetFramework)' != 'net462' ">
26+
<DefineConstants>$(DefineConstants);RUNTIME_INFORMATION</DefineConstants>
27+
</PropertyGroup>
2528

26-
<PropertyGroup Condition=" '$(TargetFramework)' != 'net45' ">
27-
<DefineConstants>$(DefineConstants);RUNTIME_INFORMATION</DefineConstants>
28-
</PropertyGroup>
29-
30-
<PropertyGroup Condition=" '$(TargetFramework)' == 'net5.0' ">
31-
<DefineConstants>$(DefineConstants);FEATURE_SPAN</DefineConstants>
32-
</PropertyGroup>
29+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net5.0' ">
30+
<DefineConstants>$(DefineConstants);FEATURE_SPAN</DefineConstants>
31+
</PropertyGroup>
32+
33+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
34+
<DefineConstants>$(DefineConstants);FEATURE_SPAN</DefineConstants>
35+
</PropertyGroup>
36+
37+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net7.0' ">
38+
<DefineConstants>$(DefineConstants);FEATURE_SPAN</DefineConstants>
39+
</PropertyGroup>
3340

34-
<ItemGroup>
35-
<PackageReference Include="Serilog" Version="2.10.0" />
36-
<PackageReference Include="Nullable" Version="1.3.0" PrivateAssets="all" />
37-
</ItemGroup>
41+
<ItemGroup>
42+
<PackageReference Include="Serilog" Version="3.1.0-*" />
43+
<PackageReference Include="Nullable" Version="1.3.0" PrivateAssets="all" />
44+
</ItemGroup>
3845

39-
<ItemGroup>
40-
<None Include="..\..\assets\icon.png" Pack="true" Visible="false" PackagePath="" />
41-
</ItemGroup>
46+
<ItemGroup>
47+
<None Include="..\..\assets\icon.png" Pack="true" Visible="false" PackagePath="" />
48+
<None Include="..\..\README.md" Pack="true" Visible="false" PackagePath="" />
49+
</ItemGroup>
4250
</Project>

src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/NewLineTokenRenderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ public override void Render(LogEvent logEvent, TextWriter output)
3737
output.WriteLine();
3838
}
3939
}
40-
}
40+
}

src/Serilog.Sinks.Console/Sinks/SystemConsole/Output/OutputTemplateRenderer.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public OutputTemplateRenderer(ConsoleTheme theme, string outputTemplate, IFormat
5050
{
5151
renderers.Add(new NewLineTokenRenderer(pt.Alignment));
5252
}
53+
else if (pt.PropertyName == OutputProperties.TraceIdPropertyName)
54+
{
55+
renderers.Add(new TraceIdTokenRenderer(theme, pt));
56+
}
57+
else if (pt.PropertyName == OutputProperties.SpanIdPropertyName)
58+
{
59+
renderers.Add(new SpanIdTokenRenderer(theme, pt));
60+
}
5361
else if (pt.PropertyName == OutputProperties.ExceptionPropertyName)
5462
{
5563
renderers.Add(new ExceptionTokenRenderer(theme, pt));
@@ -62,7 +70,7 @@ public OutputTemplateRenderer(ConsoleTheme theme, string outputTemplate, IFormat
6270
{
6371
renderers.Add(new TimestampTokenRenderer(theme, pt, formatProvider));
6472
}
65-
else if (pt.PropertyName == "Properties")
73+
else if (pt.PropertyName == OutputProperties.PropertiesPropertyName)
6674
{
6775
renderers.Add(new PropertiesTokenRenderer(theme, pt, template, formatProvider));
6876
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.IO;
2+
using Serilog.Events;
3+
using Serilog.Parsing;
4+
using Serilog.Sinks.SystemConsole.Rendering;
5+
using Serilog.Sinks.SystemConsole.Themes;
6+
7+
namespace Serilog.Sinks.SystemConsole.Output;
8+
9+
class SpanIdTokenRenderer : OutputTemplateTokenRenderer
10+
{
11+
readonly ConsoleTheme _theme;
12+
readonly Alignment? _alignment;
13+
14+
public SpanIdTokenRenderer(ConsoleTheme theme, PropertyToken spanIdToken)
15+
{
16+
_theme = theme;
17+
_alignment = spanIdToken.Alignment;
18+
}
19+
20+
public override void Render(LogEvent logEvent, TextWriter output)
21+
{
22+
if (logEvent.SpanId is not { } spanId)
23+
return;
24+
25+
var _ = 0;
26+
using (_theme.Apply(output, ConsoleThemeStyle.Text, ref _))
27+
{
28+
if (_alignment is {} alignment)
29+
Padding.Apply(output, spanId.ToString(), alignment);
30+
else
31+
output.Write(spanId);
32+
}
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.IO;
2+
using Serilog.Events;
3+
using Serilog.Parsing;
4+
using Serilog.Sinks.SystemConsole.Rendering;
5+
using Serilog.Sinks.SystemConsole.Themes;
6+
7+
namespace Serilog.Sinks.SystemConsole.Output;
8+
9+
class TraceIdTokenRenderer : OutputTemplateTokenRenderer
10+
{
11+
readonly ConsoleTheme _theme;
12+
readonly Alignment? _alignment;
13+
14+
public TraceIdTokenRenderer(ConsoleTheme theme, PropertyToken traceIdToken)
15+
{
16+
_theme = theme;
17+
_alignment = traceIdToken.Alignment;
18+
}
19+
20+
public override void Render(LogEvent logEvent, TextWriter output)
21+
{
22+
if (logEvent.TraceId is not { } traceId)
23+
return;
24+
25+
var _ = 0;
26+
using (_theme.Apply(output, ConsoleThemeStyle.Text, ref _))
27+
{
28+
if (_alignment is {} alignment)
29+
Padding.Apply(output, traceId.ToString(), alignment);
30+
else
31+
output.Write(traceId);
32+
}
33+
}
34+
}

test/Serilog.Sinks.Console.Tests/Output/OutputTemplateRendererTests.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Globalization;
34
using System.IO;
45
using System.Linq;
56
using Serilog.Events;
7+
using Serilog.Parsing;
68
using Serilog.Sinks.Console.Tests.Support;
79
using Serilog.Sinks.SystemConsole.Output;
810
using Serilog.Sinks.SystemConsole.Themes;
@@ -188,7 +190,7 @@ public SizeFormatter(IFormatProvider innerFormatProvider)
188190
_innerFormatProvider = innerFormatProvider;
189191
}
190192

191-
public object? GetFormat(Type? formatType)
193+
public object GetFormat(Type? formatType)
192194
{
193195
return formatType == typeof(ICustomFormatter) ? this : _innerFormatProvider.GetFormat(formatType) ?? this;
194196
}
@@ -374,5 +376,29 @@ public void FormatProviderWithDestructuredProperties(string format, bool shouldU
374376
Assert.Contains(expectedFormattedDate, sw.ToString());
375377
Assert.Contains(expectedFormattedNumber, sw.ToString());
376378
}
379+
380+
[Fact]
381+
public void TraceAndSpanAreEmptyWhenAbsent()
382+
{
383+
var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{TraceId}/{SpanId}", CultureInfo.InvariantCulture);
384+
var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello, world"));
385+
var sw = new StringWriter();
386+
formatter.Format(evt, sw);
387+
Assert.Equal("/", sw.ToString());
388+
}
389+
390+
[Fact]
391+
public void TraceAndSpanAreIncludedWhenPresent()
392+
{
393+
var traceId = ActivityTraceId.CreateRandom();
394+
var spanId = ActivitySpanId.CreateRandom();
395+
var formatter = new OutputTemplateRenderer(ConsoleTheme.None, "{TraceId}/{SpanId}", CultureInfo.InvariantCulture);
396+
var evt = new LogEvent(DateTimeOffset.Now, LogEventLevel.Debug, null,
397+
new MessageTemplate(Enumerable.Empty<MessageTemplateToken>()), Enumerable.Empty<LogEventProperty>(),
398+
traceId, spanId);
399+
var sw = new StringWriter();
400+
formatter.Format(evt, sw);
401+
Assert.Equal($"{traceId}/{spanId}", sw.ToString());
402+
}
377403
}
378404
}

test/Serilog.Sinks.Console.Tests/Serilog.Sinks.Console.Tests.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net452;net462;net472;net48;net5.0</TargetFrameworks>
4+
<TargetFramework>net7.0</TargetFramework>
55
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
66
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
77
<SignAssembly>true</SignAssembly>
88
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
9-
<LangVersion>8.0</LangVersion>
109
<Nullable>enable</Nullable>
1110
</PropertyGroup>
1211

0 commit comments

Comments
 (0)