Skip to content

Commit 8301b4e

Browse files
committed
Cache low-numbered numeric event ids to reduce allocations
1 parent e1a4780 commit 8301b4e

File tree

3 files changed

+77
-107
lines changed

3 files changed

+77
-107
lines changed
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<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">
22
<s:Boolean x:Key="/Default/UserDictionary/Words/=destructure/@EntryIndexedValue">True</s:Boolean>
3+
<s:Boolean x:Key="/Default/UserDictionary/Words/=destructured/@EntryIndexedValue">True</s:Boolean>
34
<s:Boolean x:Key="/Default/UserDictionary/Words/=Destructurer/@EntryIndexedValue">True</s:Boolean>
5+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Destructures/@EntryIndexedValue">True</s:Boolean>
46
<s:Boolean x:Key="/Default/UserDictionary/Words/=enricher/@EntryIndexedValue">True</s:Boolean>
57
<s:Boolean x:Key="/Default/UserDictionary/Words/=enrichers/@EntryIndexedValue">True</s:Boolean>
8+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Loggable/@EntryIndexedValue">True</s:Boolean>
69
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nonscalar/@EntryIndexedValue">True</s:Boolean>
7-
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
10+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean>
11+
<s:Boolean x:Key="/Default/UserDictionary/Words/=sobj/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

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

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.Extensions.Logging;
55
using System;
66
using System.Collections.Generic;
7+
using System.Linq;
78
using Serilog.Core;
89
using Serilog.Events;
910
using FrameworkLogger = Microsoft.Extensions.Logging.ILogger;
@@ -17,15 +18,19 @@ class SerilogLogger : FrameworkLogger
1718
readonly SerilogLoggerProvider _provider;
1819
readonly ILogger _logger;
1920

20-
static readonly MessageTemplateParser _messageTemplateParser = new MessageTemplateParser();
21+
static readonly MessageTemplateParser MessageTemplateParser = new MessageTemplateParser();
22+
23+
// It's rare to see large event ids, as they are category-specific
24+
static readonly LogEventProperty[] LowEventIdValues = Enumerable.Range(0, 48)
25+
.Select(n => new LogEventProperty("Id", new ScalarValue(n)))
26+
.ToArray();
2127

2228
public SerilogLogger(
2329
SerilogLoggerProvider provider,
2430
ILogger logger = null,
2531
string name = null)
2632
{
27-
if (provider == null) throw new ArgumentNullException(nameof(provider));
28-
_provider = provider;
33+
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
2934
_logger = logger;
3035

3136
// If a logger was passed, the provider has already added itself as an enricher
@@ -60,25 +65,22 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
6065

6166
var properties = new List<LogEventProperty>();
6267

63-
var structure = state as IEnumerable<KeyValuePair<string, object>>;
64-
if (structure != null)
68+
if (state is IEnumerable<KeyValuePair<string, object>> structure)
6569
{
6670
foreach (var property in structure)
6771
{
68-
if (property.Key == SerilogLoggerProvider.OriginalFormatPropertyName && property.Value is string)
72+
if (property.Key == SerilogLoggerProvider.OriginalFormatPropertyName && property.Value is string value)
6973
{
70-
messageTemplate = (string)property.Value;
74+
messageTemplate = value;
7175
}
7276
else if (property.Key.StartsWith("@"))
7377
{
74-
LogEventProperty destructured;
75-
if (logger.BindProperty(property.Key.Substring(1), property.Value, true, out destructured))
78+
if (logger.BindProperty(property.Key.Substring(1), property.Value, true, out var destructured))
7679
properties.Add(destructured);
7780
}
7881
else
7982
{
80-
LogEventProperty bound;
81-
if (logger.BindProperty(property.Key, property.Value, false, out bound))
83+
if (logger.BindProperty(property.Key, property.Value, false, out var bound))
8284
properties.Add(bound);
8385
}
8486
}
@@ -89,8 +91,7 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
8991
if (messageTemplate == null && !stateTypeInfo.IsGenericType)
9092
{
9193
messageTemplate = "{" + stateType.Name + ":l}";
92-
LogEventProperty stateTypeProperty;
93-
if (logger.BindProperty(stateType.Name, AsLoggableValue(state, formatter), false, out stateTypeProperty))
94+
if (logger.BindProperty(stateType.Name, AsLoggableValue(state, formatter), false, out var stateTypeProperty))
9495
properties.Add(stateTypeProperty);
9596
}
9697
}
@@ -111,16 +112,15 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
111112

112113
if (propertyName != null)
113114
{
114-
LogEventProperty property;
115-
if (logger.BindProperty(propertyName, AsLoggableValue(state, formatter), false, out property))
115+
if (logger.BindProperty(propertyName, AsLoggableValue(state, formatter), false, out var property))
116116
properties.Add(property);
117117
}
118118
}
119119

120120
if (eventId.Id != 0 || eventId.Name != null)
121121
properties.Add(CreateEventIdProperty(eventId));
122122

123-
var parsedTemplate = _messageTemplateParser.Parse(messageTemplate ?? "");
123+
var parsedTemplate = MessageTemplateParser.Parse(messageTemplate ?? "");
124124
var evt = new LogEvent(DateTimeOffset.Now, level, exception, parsedTemplate, properties);
125125
logger.Write(evt);
126126
}
@@ -133,13 +133,17 @@ static object AsLoggableValue<TState>(TState state, Func<TState, Exception, stri
133133
return sobj;
134134
}
135135

136-
static LogEventProperty CreateEventIdProperty(EventId eventId)
136+
internal static LogEventProperty CreateEventIdProperty(EventId eventId)
137137
{
138138
var properties = new List<LogEventProperty>(2);
139139

140140
if (eventId.Id != 0)
141141
{
142-
properties.Add(new LogEventProperty("Id", new ScalarValue(eventId.Id)));
142+
if (eventId.Id < LowEventIdValues.Length)
143+
// Avoid some allocations
144+
properties.Add(LowEventIdValues[eventId.Id]);
145+
else
146+
properties.Add(new LogEventProperty("Id", new ScalarValue(eventId.Id)));
143147
}
144148

145149
if (eventId.Name != null)

0 commit comments

Comments
 (0)