Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d8c75ec

Browse files
Merge pull request #277 from AndreReise/avoid-closure-allocation
Remove closure allocation in SerilogLoggerProvider.
2 parents 924776e + 46dfbf4 commit d8c75ec

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

‎src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerProvider.cs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public sealed class SerilogLoggerProvider : ILoggerProvider, ILogEventEnricher,
2424
// May be null; if it is, Log.Logger will be lazily used
2525
readonly ILogger? _logger;
2626
readonly Action? _dispose;
27+
readonly ThreadLocal<ScopeCollector> _scopeCollector = new(() => new ScopeCollector());
2728
#if FEATURE_ASYNCDISPOSABLE
2829
readonly Func<ValueTask>? _disposeAsync;
2930
#endif
@@ -90,35 +91,38 @@ public IDisposable BeginScope<T>(T state)
9091
/// <inheritdoc />
9192
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
9293
{
93-
List<LogEventPropertyValue>? scopeItems = null;
94+
var scopeCollector = _scopeCollector.Value!;
95+
9496
for (var scope = CurrentScope; scope != null; scope = scope.Parent)
9597
{
9698
scope.EnrichAndCreateScopeItem(logEvent, propertyFactory, out var scopeItem);
9799

98100
if (scopeItem != null)
99101
{
100-
scopeItems ??= [];
101-
scopeItems.Add(scopeItem);
102+
scopeCollector.AddItem(scopeItem);
102103
}
103104
}
104105

105-
scopeItems?.Reverse();
106+
scopeCollector.ReverseItems();
106107

107-
_externalScopeProvider?.ForEachScope((state, accumulatingLogEvent) =>
108+
_externalScopeProvider?.ForEachScope(static(state, parameters) =>
108109
{
109110
SerilogLoggerScope.EnrichWithStateAndCreateScopeItem(
110-
accumulatingLogEvent, propertyFactory, state, update: true, out var scopeItem);
111+
parameters.LogEvent,
112+
parameters.PropertyFactory,
113+
state,
114+
update: true,
115+
out var scopeItem);
111116

112117
if (scopeItem != null)
113118
{
114-
scopeItems ??= new List<LogEventPropertyValue>();
115-
scopeItems.Add(scopeItem);
119+
parameters.ScopeCollector.AddItem(scopeItem);
116120
}
117-
}, logEvent);
121+
}, (ScopeCollector:scopeCollector,PropertyFactory:propertyFactory,LogEvent:logEvent));
118122

119-
if (scopeItems!=null)
123+
if (scopeCollector.Complete()is{}items)
120124
{
121-
logEvent.AddPropertyIfAbsent(new LogEventProperty(ScopePropertyName, new SequenceValue(scopeItems)));
125+
logEvent.AddPropertyIfAbsent(new LogEventProperty(ScopePropertyName, new SequenceValue(items)));
122126
}
123127
}
124128

@@ -149,4 +153,27 @@ public ValueTask DisposeAsync()
149153
return _disposeAsync?.Invoke() ?? default;
150154
}
151155
#endif
156+
157+
/// <summary>
158+
/// A wrapper around a list to allow lazy initialization when iterating through scopes.
159+
/// </summary>
160+
sealed class ScopeCollector
161+
{
162+
List<LogEventPropertyValue>? _scopeItems;
163+
164+
public void AddItem(LogEventPropertyValue scopeItem)
165+
{
166+
_scopeItems ??= [];
167+
_scopeItems.Add(scopeItem);
168+
}
169+
170+
public void ReverseItems() => _scopeItems?.Reverse();
171+
172+
public List<LogEventPropertyValue>? Complete()
173+
{
174+
var scopeItems = _scopeItems;
175+
_scopeItems = null;
176+
return scopeItems;
177+
}
178+
}
152179
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /