Skip to content

Commit

Permalink
Reduce enumerator-allocation when only using CaptureMessageProperties…
Browse files Browse the repository at this point in the history
… (Without CaptureMessageTemplates)
  • Loading branch information
snakefoot committed Jul 25, 2018
1 parent 28ac193 commit 38f4407
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
45 changes: 36 additions & 9 deletions src/NLog.Extensions.Logging/Logging/NLogLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,39 @@ public NLogLogger(Logger logger, NLogProviderOptions options, NLogBeginScopePars
public void Log<TState>(Microsoft.Extensions.Logging.LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var nLogLogLevel = ConvertLogLevel(logLevel);
if (!IsEnabled(nLogLogLevel))
if (!_logger.IsEnabled(nLogLogLevel))
{
return;
}

if (formatter == null)
{
throw new ArgumentNullException(nameof(formatter));
}

var messageParameters = NLogMessageParameterList.TryParse(_options.CaptureMessageTemplates ? state as IReadOnlyList<KeyValuePair<string, object>> : null);
var messageParameters = _options.CaptureMessageTemplates
? NLogMessageParameterList.TryParse(state as IReadOnlyList<KeyValuePair<string, object>>)
: null;

LogEventInfo eventInfo =
TryParseLogEventInfo(nLogLogLevel, messageParameters) ??
TryParseMessageTemplate(nLogLogLevel, messageParameters) ??
CreateLogEventInfo(nLogLogLevel, formatter(state, exception), messageParameters);

if (exception != null)
{
eventInfo.Exception = exception;
}

CaptureEventId(eventInfo, eventId);

if (messageParameters == null)
if (messageParameters == null && _options.CaptureMessageProperties)
{
CaptureMessageProperties(eventInfo, state);
if (_options.CaptureMessageTemplates || !CaptureMessagePropertiesList(eventInfo, state))
{
CaptureMessageProperties(eventInfo, state);
}
}

CaptureEventId(eventInfo, eventId);

_logger.Log(typeof(Microsoft.Extensions.Logging.ILogger), eventInfo);
}

Expand Down Expand Up @@ -99,7 +105,7 @@ private LogEventInfo CreateLogEventInfo(LogLevel nLogLogLevel, string message, N
/// <remarks>
/// Using the NLog MesageTemplate Parser will hurt performance: 1 x Microsoft Parser - 2 x NLog Parser - 1 x NLog Formatter
/// </remarks>
private LogEventInfo TryParseLogEventInfo(LogLevel nLogLogLevel, NLogMessageParameterList messageParameters)
private LogEventInfo TryParseMessageTemplate(LogLevel nLogLogLevel, NLogMessageParameterList messageParameters)
{
if (messageParameters?.OriginalMessage != null && (messageParameters.HasComplexParameters || (_options.ParseMessageTemplates && messageParameters.Count > 0)))
{
Expand Down Expand Up @@ -304,7 +310,7 @@ private static Tuple<string, string, string> CreateEventIdPropertyNames(string e

private void CaptureMessageProperties<TState>(LogEventInfo eventInfo, TState state)
{
if (_options.CaptureMessageProperties && state is IEnumerable<KeyValuePair<string, object>> messageProperties)
if (state is IEnumerable<KeyValuePair<string, object>> messageProperties)
{
foreach (var property in messageProperties)
{
Expand All @@ -316,6 +322,27 @@ private void CaptureMessageProperties<TState>(LogEventInfo eventInfo, TState sta
}
}

private bool CaptureMessagePropertiesList<TState>(LogEventInfo eventInfo, TState state)
{
if (state is IReadOnlyList<KeyValuePair<string, object>> messageProperties)
{
for (int i = 0; i < messageProperties.Count; ++i)
{
var property = messageProperties[i];
if (String.IsNullOrEmpty(property.Key))
continue;

if (i == messageProperties.Count - 1 && property.Key == OriginalFormatPropertyName)
continue;

eventInfo.Properties[property.Key] = property.Value;
}
return true;
}

return false;
}

/// <summary>
/// Is logging enabled for this logger at this <paramref name="logLevel"/>?
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/NLog.Extensions.Logging/Logging/NLogLoggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ public NLogLoggerProvider(NLogProviderOptions options)
/// <returns>New Logger</returns>
public Microsoft.Extensions.Logging.ILogger CreateLogger(string name)
{
var beginScopeExtractor = ((Options?.CaptureMessageProperties ?? true) && (Options?.IncludeScopes ?? true))
var beginScopeParser = ((Options?.CaptureMessageProperties ?? true) && (Options?.IncludeScopes ?? true))
? (_beginScopeParser ?? System.Threading.Interlocked.CompareExchange(ref _beginScopeParser, new NLogBeginScopeParser(Options), null))
: null;
return new NLogLogger(LogManager.GetLogger(name), Options, beginScopeExtractor);
return new NLogLogger(LogManager.GetLogger(name), Options, beginScopeParser);
}

/// <summary>
Expand Down

0 comments on commit 38f4407

Please sign in to comment.