Skip to content

Commit b678843

Browse files
authored
Merge pull request #36 from nblumhardt/sp-tr
Support Serilog 3.1 trace `@tr` and span `@sp` ids
2 parents ba2e998 + c788b7a commit b678843

File tree

7 files changed

+50
-33
lines changed

7 files changed

+50
-33
lines changed

example/RoundTrip/RoundTrip.csproj

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<TargetFramework>net7.0</TargetFramework>
55
<AssemblyName>RoundTrip</AssemblyName>
66
<OutputType>Exe</OutputType>
77
<PackageId>RoundTrip</PackageId>
@@ -15,7 +15,6 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Serilog" Version="2.5.0" />
1918
<PackageReference Include="Serilog.Sinks.File" Version="3.1.0" />
2019
<PackageReference Include="Serilog.Sinks.Console" Version="3.0.1" />
2120
<PackageReference Include="Serilog.Formatting.Compact" Version="1.0.0" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:Boolean x:Key="/Default/UserDictionary/Words/=nblumhardt/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

src/Serilog.Formatting.Compact.Reader/ClefFields.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ static class ClefFields
2828
public const string Renderings = "@r";
2929
public const string EventId = "@i";
3030
public const string Message = "@m";
31+
public const string TraceId = "@tr";
32+
public const string SpanId = "@sp";
3133

32-
public static readonly string[] All = { Timestamp, MessageTemplate, Level, Exception, Renderings, EventId, Message };
34+
public static readonly string[] All = { Timestamp, MessageTemplate, Level, Exception, Renderings, EventId, Message, TraceId, SpanId };
3335

3436
const string Prefix = "@";
3537
const string EscapedInitialAt = "@@";

src/Serilog.Formatting.Compact.Reader/LogEventReader.cs

+26-19
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
// limitations under the License.
1414

1515
using System;
16+
using System.Diagnostics;
1617
using System.Globalization;
1718
using System.IO;
1819
using Newtonsoft.Json;
1920
using Newtonsoft.Json.Linq;
2021
using Serilog.Events;
2122
using Serilog.Parsing;
2223
using System.Linq;
24+
// ReSharper disable MemberCanBePrivate.Global
25+
// ReSharper disable UnusedMember.Global
2326

2427
namespace Serilog.Formatting.Compact.Reader
2528
{
@@ -30,7 +33,7 @@ namespace Serilog.Formatting.Compact.Reader
3033
public class LogEventReader : IDisposable
3134
{
3235
static readonly MessageTemplateParser Parser = new MessageTemplateParser();
33-
static readonly Rendering[] NoRenderings = new Rendering[0];
36+
static readonly Rendering[] NoRenderings = Array.Empty<Rendering>();
3437
readonly TextReader _text;
3538
readonly JsonSerializer _serializer;
3639

@@ -75,8 +78,7 @@ public bool TryRead(out LogEvent evt)
7578
}
7679

7780
var data = _serializer.Deserialize(new JsonTextReader(new StringReader(line)));
78-
var fields = data as JObject;
79-
if (fields == null)
81+
if (!(data is JObject fields))
8082
throw new InvalidDataException($"The data on line {_lineNumber} is not a complete JSON object.");
8183

8284
evt = ReadFromJObject(_lineNumber, fields);
@@ -93,7 +95,7 @@ public static LogEvent ReadFromString(string document, JsonSerializer serializer
9395
{
9496
if (document == null) throw new ArgumentNullException(nameof(document));
9597

96-
serializer = serializer ?? CreateSerializer();
98+
serializer ??= CreateSerializer();
9799
var jObject = serializer.Deserialize<JObject>(new JsonTextReader(new StringReader(document)));
98100
return ReadFromJObject(jObject);
99101

@@ -123,22 +125,30 @@ static LogEvent ReadFromJObject(int lineNumber, JObject jObject)
123125
messageTemplate = null;
124126

125127
var level = LogEventLevel.Information;
126-
if (TryGetOptionalField(lineNumber, jObject, ClefFields.Level, out string l))
128+
if (TryGetOptionalField(lineNumber, jObject, ClefFields.Level, out var l))
127129
level = (LogEventLevel)Enum.Parse(typeof(LogEventLevel), l, true);
130+
128131
Exception exception = null;
129-
if (TryGetOptionalField(lineNumber, jObject, ClefFields.Exception, out string ex))
132+
if (TryGetOptionalField(lineNumber, jObject, ClefFields.Exception, out var ex))
130133
exception = new TextException(ex);
131134

135+
ActivityTraceId traceId = default;
136+
if (TryGetOptionalField(lineNumber, jObject, ClefFields.TraceId, out var tr))
137+
traceId = ActivityTraceId.CreateFromString(tr.AsSpan());
138+
139+
ActivitySpanId spanId = default;
140+
if (TryGetOptionalField(lineNumber, jObject, ClefFields.SpanId, out var sp))
141+
spanId = ActivitySpanId.CreateFromString(sp.AsSpan());
142+
132143
var parsedTemplate = messageTemplate == null ?
133144
new MessageTemplate(Enumerable.Empty<MessageTemplateToken>()) :
134145
Parser.Parse(messageTemplate);
135146

136147
var renderings = NoRenderings;
137148

138-
if (jObject.TryGetValue(ClefFields.Renderings, out JToken r))
149+
if (jObject.TryGetValue(ClefFields.Renderings, out var r))
139150
{
140-
var renderedByIndex = r as JArray;
141-
if (renderedByIndex == null)
151+
if (!(r is JArray renderedByIndex))
142152
throw new InvalidDataException($"The `{ClefFields.Renderings}` value on line {lineNumber} is not an array as expected.");
143153

144154
renderings = parsedTemplate.Tokens
@@ -164,13 +174,12 @@ static LogEvent ReadFromJObject(int lineNumber, JObject jObject)
164174
properties.Add(new LogEventProperty("@i", new ScalarValue(eventId)));
165175
}
166176

167-
return new LogEvent(timestamp, level, exception, parsedTemplate, properties);
177+
return new LogEvent(timestamp, level, exception, parsedTemplate, properties, traceId, spanId);
168178
}
169179

170180
static bool TryGetOptionalField(int lineNumber, JObject data, string field, out string value)
171181
{
172-
JToken token;
173-
if (!data.TryGetValue(field, out token) || token.Type == JTokenType.Null)
182+
if (!data.TryGetValue(field, out var token) || token.Type == JTokenType.Null)
174183
{
175184
value = null;
176185
return false;
@@ -185,8 +194,7 @@ static bool TryGetOptionalField(int lineNumber, JObject data, string field, out
185194

186195
static bool TryGetOptionalEventId(int lineNumber, JObject data, string field, out object eventId)
187196
{
188-
JToken token;
189-
if (!data.TryGetValue(field, out token) || token.Type == JTokenType.Null)
197+
if (!data.TryGetValue(field, out var token) || token.Type == JTokenType.Null)
190198
{
191199
eventId = null;
192200
return false;
@@ -208,17 +216,16 @@ static bool TryGetOptionalEventId(int lineNumber, JObject data, string field, ou
208216

209217
static DateTimeOffset GetRequiredTimestampField(int lineNumber, JObject data, string field)
210218
{
211-
JToken token;
212-
if (!data.TryGetValue(field, out token) || token.Type == JTokenType.Null)
219+
if (!data.TryGetValue(field, out var token) || token.Type == JTokenType.Null)
213220
throw new InvalidDataException($"The data on line {lineNumber} does not include the required `{field}` field.");
214221

215222
if (token.Type == JTokenType.Date)
216223
{
217224
var dt = token.Value<JValue>().Value;
218-
if (dt is DateTimeOffset)
219-
return (DateTimeOffset)dt;
225+
if (dt is DateTimeOffset offset)
226+
return offset;
220227

221-
return (DateTime)dt;
228+
return (DateTime)dt!;
222229
}
223230

224231
if (token.Type != JTokenType.String)
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<VersionPrefix>2.0.1</VersionPrefix>
5-
<TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.0;net45</TargetFrameworks>
4+
<VersionPrefix>3.0.0</VersionPrefix>
5+
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net471</TargetFrameworks>
6+
<TargetFrameworks>$(TargetFrameworks);netstandard2.1;netstandard2.0;net5.0;net6.0;net7.0</TargetFrameworks>
67
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
78
<GenerateDocumentationFile>true</GenerateDocumentationFile>
89
<AssemblyName>Serilog.Formatting.Compact.Reader</AssemblyName>
@@ -16,20 +17,18 @@
1617
<PackageProjectUrl>https://github.com/serilog/serilog-formatting-compact-reader</PackageProjectUrl>
1718
<RepositoryUrl>https://github.com/serilog/serilog-formatting-compact-reader</RepositoryUrl>
1819
<RepositoryType>git</RepositoryType>
20+
<PackageReadmeFile>README.md</PackageReadmeFile>
21+
<LangVersion>8</LangVersion>
1922
</PropertyGroup>
2023

2124
<ItemGroup>
22-
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
23-
<PackageReference Include="Serilog" Version="2.3.0" />
24-
</ItemGroup>
25-
26-
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
27-
<Reference Include="System" />
28-
<Reference Include="Microsoft.CSharp" />
25+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
26+
<PackageReference Include="Serilog" Version="3.1.0-*" />
2927
</ItemGroup>
3028

3129
<ItemGroup>
3230
<None Include="..\..\asset\icon.png" Pack="true" Visible="false" PackagePath="" />
31+
<None Include="..\..\README.md" Pack="true" Visible="false" PackagePath="" />
3332
</ItemGroup>
3433

3534
</Project>

test/Serilog.Formatting.Compact.Reader.Tests/LogEventReaderTests.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Collections.Generic;
66
using System.IO;
7-
using System.Linq;
87
using Xunit;
98

109
namespace Serilog.Formatting.Compact.Reader.Tests
@@ -102,5 +101,15 @@ public void EventIdIntegersAreAccepted()
102101

103102
Assert.Equal((uint)42, ((ScalarValue)evt.Properties["@i"]).Value);
104103
}
104+
105+
[Fact]
106+
public void ReadsTraceAndSpanIds()
107+
{
108+
const string document = "{\"@t\":\"2016-10-12T04:20:58.0554314Z\",\"@tr\":\"1befc31e94b01d1a473f63a7905f6c9b\",\"@sp\":\"bb1111820570b80e\"}";
109+
var evt = LogEventReader.ReadFromString(document);
110+
111+
Assert.Equal("1befc31e94b01d1a473f63a7905f6c9b", evt.TraceId.ToString());
112+
Assert.Equal("bb1111820570b80e", evt.SpanId.ToString());
113+
}
105114
}
106115
}

test/Serilog.Formatting.Compact.Reader.Tests/Serilog.Formatting.Compact.Reader.Tests.csproj

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" />
2424
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
2525
<PackageReference Include="xunit" Version="2.3.0" />
26-
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
2726
</ItemGroup>
2827

2928
<ItemGroup>

0 commit comments

Comments
 (0)