Skip to content

Commit 5864a5d

Browse files
committed
Use LogEvent.UnstableAssembleFromParts() to avoid a dictionary alloc
1 parent f845237 commit 5864a5d

File tree

4 files changed

+18
-19
lines changed

4 files changed

+18
-19
lines changed

src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLogger.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,30 +93,30 @@ LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state
9393
{
9494
string? messageTemplate = null;
9595

96-
var properties = new List<LogEventProperty>();
96+
var properties = new Dictionary<string, LogEventPropertyValue>();
9797

9898
if (state is IEnumerable<KeyValuePair<string, object>> structure)
9999
{
100100
foreach (var property in structure)
101101
{
102-
if (property.Key == SerilogLoggerProvider.OriginalFormatPropertyName && property.Value is string value)
102+
if (property is { Key: SerilogLoggerProvider.OriginalFormatPropertyName, Value: string value })
103103
{
104104
messageTemplate = value;
105105
}
106106
else if (property.Key.StartsWith("@"))
107107
{
108108
if (_logger.BindProperty(GetKeyWithoutFirstSymbol(DestructureDictionary, property.Key), property.Value, true, out var destructured))
109-
properties.Add(destructured);
109+
properties.Add(destructured.Name, destructured.Value);
110110
}
111111
else if (property.Key.StartsWith("$"))
112112
{
113113
if (_logger.BindProperty(GetKeyWithoutFirstSymbol(StringifyDictionary, property.Key), property.Value?.ToString(), true, out var stringified))
114-
properties.Add(stringified);
114+
properties.Add(stringified.Name, stringified.Value);
115115
}
116116
else
117117
{
118118
if (_logger.BindProperty(property.Key, property.Value, false, out var bound))
119-
properties.Add(bound);
119+
properties.Add(bound.Name, bound.Value);
120120
}
121121
}
122122

@@ -127,7 +127,7 @@ LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state
127127
{
128128
messageTemplate = "{" + stateType.Name + ":l}";
129129
if (_logger.BindProperty(stateType.Name, AsLoggableValue(state, formatter), false, out var stateTypeProperty))
130-
properties.Add(stateTypeProperty);
130+
properties.Add(stateTypeProperty.Name, stateTypeProperty.Value);
131131
}
132132
}
133133

@@ -150,19 +150,19 @@ LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state
150150
if (propertyName != null)
151151
{
152152
if (_logger.BindProperty(propertyName, AsLoggableValue(state, formatter!), false, out var property))
153-
properties.Add(property);
153+
properties.Add(property.Name, property.Value);
154154
}
155155
}
156156

157157
if (eventId.Id != 0 || eventId.Name != null)
158-
properties.Add(CreateEventIdProperty(eventId));
158+
properties.Add("EventId", CreateEventIdPropertyValue(eventId));
159159

160160
var (traceId, spanId) = Activity.Current is { } activity ?
161161
(activity.TraceId, activity.SpanId) :
162162
(default(ActivityTraceId), default(ActivitySpanId));
163163

164164
var parsedTemplate = MessageTemplateParser.Parse(messageTemplate ?? "");
165-
return new LogEvent(DateTimeOffset.Now, level, exception, parsedTemplate, properties, traceId, spanId);
165+
return LogEvent.UnstableAssembleFromParts(DateTimeOffset.Now, level, exception, parsedTemplate, properties, traceId, spanId);
166166
}
167167

168168
static object? AsLoggableValue<TState>(TState state, Func<TState, Exception?, string>? formatter)
@@ -173,7 +173,7 @@ LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state
173173
return stateObj ?? state;
174174
}
175175

176-
internal static LogEventProperty CreateEventIdProperty(EventId eventId)
176+
internal static StructureValue CreateEventIdPropertyValue(EventId eventId)
177177
{
178178
var properties = new List<LogEventProperty>(2);
179179

@@ -191,6 +191,6 @@ internal static LogEventProperty CreateEventIdProperty(EventId eventId)
191191
properties.Add(new LogEventProperty("Name", new ScalarValue(eventId.Name)));
192192
}
193193

194-
return new LogEventProperty("EventId", new StructureValue(properties));
194+
return new StructureValue(properties);
195195
}
196196
}

src/Serilog.Extensions.Logging/Serilog.Extensions.Logging.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<None Include="..\..\assets\serilog-extension-nuget.png" Pack="true" PackagePath="" Visible="false" />
3030
<None Include="..\..\README.md" Pack="true" PackagePath="\" Visible="false" />
3131
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
32-
<PackageReference Include="Serilog" Version="3.1.1" />
32+
<PackageReference Include="Serilog" Version="4.0.0-*" />
3333
<!-- The version of this reference must match the major and minor components of the package version prefix. -->
3434
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
3535
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="All" />

test/Serilog.Extensions.Logging.Benchmarks/LogEventBenchmark.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace Serilog.Extensions.Logging.Benchmarks
2525
[MemoryDiagnoser]
2626
public class LogEventBenchmark
2727
{
28-
private class Person
28+
class Person
2929
{
3030
public string? Name { get; set; }
3131
public int Age { get; set; }
@@ -58,8 +58,8 @@ public void LogInformation()
5858
[Benchmark]
5959
public void LogInformationScoped()
6060
{
61-
using (var scope = _melLogger.BeginScope("Hi {@User} from {$Me}", _bob, _alice))
62-
_melLogger.LogInformation("Hi");
61+
using var scope = _melLogger.BeginScope("Hi {@User} from {$Me}", _bob, _alice);
62+
_melLogger.LogInformation("Hi");
6363
}
6464
}
6565
}

test/Serilog.Extensions.Logging.Tests/SerilogLoggerTests.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,9 @@ public IDisposable Push(object? state)
500500
return scope;
501501
}
502502

503-
private class Scope : IDisposable
503+
class Scope : IDisposable
504504
{
505-
public bool IsDisposed { get; set; } = false;
505+
public bool IsDisposed { get; set; }
506506
public object? Value { get; set; }
507507

508508
public Scope(object? value)
@@ -525,8 +525,7 @@ public void Dispose()
525525
public void LowAndHighNumberedEventIdsAreMapped(int id)
526526
{
527527
var orig = new EventId(id, "test");
528-
var mapped = SerilogLogger.CreateEventIdProperty(orig);
529-
var value = Assert.IsType<StructureValue>(mapped.Value);
528+
var value = SerilogLogger.CreateEventIdPropertyValue(orig);
530529
Assert.Equal(2, value.Properties.Count);
531530
var idValue = value.Properties.Single(p => p.Name == "Id").Value;
532531
var scalar = Assert.IsType<ScalarValue>(idValue);

0 commit comments

Comments
 (0)