This commit is contained in:
Pavel Krymets 2018-10-29 11:41:41 -07:00 коммит произвёл GitHub
Родитель 03970f7104
Коммит cc90113f45
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 418 добавлений и 211 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -29,3 +29,4 @@ project.lock.json
.build/
.testPublish/
global.json
BenchmarkDotNet.Artifacts/

Просмотреть файл

@ -60,6 +60,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Loggin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.Analyzer.Test", "test\Microsoft.Extensions.Logging.Analyzer.Test\Microsoft.Extensions.Logging.Analyzer.Test.csproj", "{C0391E46-FD04-4D52-BE40-1F21CE83E037}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{0BE8FABE-0FE7-4DF1-ABDE-27BB0D86F881}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logging.Performance", "benchmarks\Logging.Performance\Logging.Performance.csproj", "{67B77ED1-8827-4088-8724-4A0AF4351FB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -134,6 +138,10 @@ Global
{C0391E46-FD04-4D52-BE40-1F21CE83E037}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0391E46-FD04-4D52-BE40-1F21CE83E037}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0391E46-FD04-4D52-BE40-1F21CE83E037}.Release|Any CPU.Build.0 = Release|Any CPU
{67B77ED1-8827-4088-8724-4A0AF4351FB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67B77ED1-8827-4088-8724-4A0AF4351FB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67B77ED1-8827-4088-8724-4A0AF4351FB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67B77ED1-8827-4088-8724-4A0AF4351FB7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -156,6 +164,7 @@ Global
{6D921637-507E-4CDC-8C5F-C3D6B62D118C} = {699DB330-0095-4266-B7B0-3EAB3710CA49}
{99DF369F-40A4-4088-8308-1C361B59DF4E} = {699DB330-0095-4266-B7B0-3EAB3710CA49}
{C0391E46-FD04-4D52-BE40-1F21CE83E037} = {09920C51-6220-4D8D-94DC-E70C13446187}
{67B77ED1-8827-4088-8724-4A0AF4351FB7} = {0BE8FABE-0FE7-4DF1-ABDE-27BB0D86F881}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BA58E3CA-3A01-46A7-B57F-FD7A188EDC79}

Просмотреть файл

@ -0,0 +1,55 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Extensions.Logging.Performance
{
[AspNetCoreBenchmark]
public class FormattingBenchmarks : LoggingBenchmarkBase
{
private ILogger _logger;
[Benchmark]
public void TwoArguments()
{
TwoArgumentErrorMessage(_logger, 1, "string", Exception);
}
[Benchmark(Baseline = true)]
public void NoArguments()
{
NoArgumentErrorMessage(_logger, Exception);
}
[GlobalSetup]
public void Setup()
{
var services = new ServiceCollection();
services.AddLogging();
services.AddSingleton<ILoggerProvider, LoggerProvider<MessageFormattingLogger>>();
_logger = services.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger("Logger");
}
public class MessageFormattingLogger: ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
formatter(state, exception);
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<RootNamespace>Microsoft.Extensions.Logging.Performance</RootNamespace>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Extensions.Logging\Microsoft.Extensions.Logging.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="$(BenchmarkDotNetPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="$(MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,40 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.Extensions.Logging.Performance
{
public class LoggingBenchmarkBase
{
protected static readonly Action<ILogger, Exception> NoArgumentTraceMessage = LoggerMessage.Define(LogLevel.Trace, 0, "Message");
protected static readonly Action<ILogger, Exception> NoArgumentErrorMessage = LoggerMessage.Define(LogLevel.Error, 0, "Message");
protected static readonly Action<ILogger, int, string, Exception> TwoArgumentTraceMessage = LoggerMessage.Define<int, string>(LogLevel.Trace, 0, "Message {Argument1} {Argument2}");
protected static readonly Action<ILogger, int, string, Exception> TwoArgumentErrorMessage = LoggerMessage.Define<int, string>(LogLevel.Error, 0, "Message {Argument1} {Argument2}");
protected static Exception Exception = ((Func<Exception>)(() => {
try
{
throw new Exception();
}
catch (Exception ex)
{
return ex;
}
}))();
public class LoggerProvider<T>: ILoggerProvider
where T: ILogger, new()
{
public void Dispose()
{
}
public ILogger CreateLogger(string categoryName)
{
return new T();
}
}
}
}

Просмотреть файл

@ -0,0 +1,90 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Extensions.Logging.Performance
{
[AspNetCoreBenchmark]
public class LoggingOverheadBenchmark: LoggingBenchmarkBase
{
private ILogger _logger;
[Benchmark]
public void NoArguments_FilteredByLevel()
{
_logger.LogTrace(Exception, "Message");
}
// Baseline as this is the fastest way to do nothing
[Benchmark(Baseline = true)]
public void NoArguments_DefineMessage_FilteredByLevel()
{
NoArgumentTraceMessage(_logger, Exception);
}
[Benchmark]
public void NoArguments()
{
_logger.LogError(Exception, "Message");
}
[Benchmark]
public void NoArguments_DefineMessage()
{
NoArgumentErrorMessage(_logger, Exception);
}
[Benchmark]
public void TwoArguments()
{
_logger.LogError(Exception, "Message {Argument1} {Argument2}", 1, "string");
}
[Benchmark]
public void TwoArguments_FilteredByLevel()
{
_logger.LogTrace(Exception, "Message {Argument1} {Argument2}", 1, "string");
}
[Benchmark]
public void TwoArguments_DefineMessage()
{
TwoArgumentErrorMessage(_logger, 1, "string", Exception);
}
[Benchmark]
public void TwoArguments_DefineMessage_FilteredByLevel()
{
TwoArgumentTraceMessage(_logger, 1, "string", Exception);
}
[GlobalSetup]
public void Setup()
{
var services = new ServiceCollection();
services.AddLogging();
services.AddSingleton<ILoggerProvider, LoggerProvider<NoopLogger>>();
_logger = services.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger("Logger");
}
}
public class NoopLogger : ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
}
}

Просмотреть файл

@ -0,0 +1,72 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.Extensions.Logging.Performance
{
[AspNetCoreBenchmark]
public class ScopesOverheadBenchmark: LoggingBenchmarkBase
{
private ILogger _logger;
[Params(true, false)]
public bool HasISupportLoggingScopeLogger { get; set; } = false;
// Baseline as this is the fastest way to do nothing
[Benchmark(Baseline = true)]
public void FilteredByLevel()
{
TwoArgumentTraceMessage(_logger, 1, "string", Exception);
}
[Benchmark]
public void FilteredByLevel_InsideScope()
{
using (_logger.BeginScope("string"))
{
TwoArgumentTraceMessage(_logger, 1, "string", Exception);
}
}
[Benchmark]
public void NotFiltered()
{
TwoArgumentErrorMessage(_logger, 1, "string", Exception);
}
[Benchmark]
public void NotFiltered_InsideScope()
{
using (_logger.BeginScope("string"))
{
TwoArgumentErrorMessage(_logger, 1, "string", Exception);
}
}
[GlobalSetup]
public void Setup()
{
var services = new ServiceCollection();
services.AddLogging();
if (HasISupportLoggingScopeLogger)
{
services.AddSingleton<ILoggerProvider, LoggerProviderWithISupportExternalScope>();
}
else
{
services.AddSingleton<ILoggerProvider, LoggerProvider<NoopLogger>>();
}
_logger = services.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger("Logger");
}
class LoggerProviderWithISupportExternalScope: LoggerProvider<NoopLogger>, ISupportExternalScope
{
public void SetScopeProvider(IExternalScopeProvider scopeProvider)
{
}
}
}
}

Просмотреть файл

@ -3,8 +3,10 @@
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
<InternalAspNetCoreSdkPackageVersion>3.0.0-alpha1-20181004.7</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-alpha1-10584</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-alpha1-10584</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Extensions.Logging.Internal
/// LogValues to enable formatting options supported by <see cref="M:string.Format"/>.
/// This also enables using {NamedformatItem} in the format string.
/// </summary>
public class FormattedLogValues : IReadOnlyList<KeyValuePair<string, object>>
public readonly struct FormattedLogValues : IReadOnlyList<KeyValuePair<string, object>>
{
internal const int MaxCachedFormatters = 1024;
private const string NullFormat = "[null]";
@ -46,6 +46,10 @@ namespace Microsoft.Extensions.Logging.Internal
});
}
}
else
{
_formatter = null;
}
_originalMessage = format ?? NullFormat;
_values = values;

Просмотреть файл

@ -119,32 +119,33 @@ namespace Microsoft.Extensions.Logging.Internal
{
for (int i = 0; i < values.Length; i++)
{
var value = values[i];
if (value == null)
{
values[i] = NullValue;
continue;
}
// since 'string' implements IEnumerable, special case it
if (value is string)
{
continue;
}
// if the value implements IEnumerable, build a comma separated string.
var enumerable = value as IEnumerable;
if (enumerable != null)
{
values[i] = string.Join(", ", enumerable.Cast<object>().Select(o => o ?? NullValue));
}
values[i] = FormatArgument(values[i]);
}
}
return string.Format(CultureInfo.InvariantCulture, _format, values ?? EmptyArray);
}
internal string Format()
{
return _format;
}
internal string Format(object arg0)
{
return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0));
}
internal string Format(object arg0, object arg1)
{
return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1));
}
internal string Format(object arg0, object arg1, object arg2)
{
return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1), FormatArgument(arg2));
}
public KeyValuePair<string, object> GetValue(object[] values, int index)
{
if (index < 0 || index > _valueNames.Count)
@ -171,5 +172,29 @@ namespace Microsoft.Extensions.Logging.Internal
valueArray[valueArray.Length - 1] = new KeyValuePair<string, object>("{OriginalFormat}", OriginalFormat);
return valueArray;
}
private object FormatArgument(object value)
{
if (value == null)
{
return NullValue;
}
// since 'string' implements IEnumerable, special case it
if (value is string)
{
return value;
}
// if the value implements IEnumerable, build a comma separated string.
var enumerable = value as IEnumerable;
if (enumerable != null)
{
return string.Join(", ", enumerable.Cast<object>().Select(o => o ?? NullValue));
}
return value;
}
}
}

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Extensions.Logging
/// </summary>
public static class LoggerExtensions
{
private static readonly Func<object, Exception, string> _messageFormatter = MessageFormatter;
private static readonly Func<FormattedLogValues, Exception, string> _messageFormatter = MessageFormatter;
//------------------------------------------DEBUG------------------------------------------//
@ -425,7 +425,7 @@ namespace Microsoft.Extensions.Logging
//------------------------------------------HELPERS------------------------------------------//
private static string MessageFormatter(object state, Exception error)
private static string MessageFormatter(FormattedLogValues state, Exception error)
{
return state.ToString();
}

Просмотреть файл

@ -102,11 +102,16 @@ namespace Microsoft.Extensions.Logging
{
var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 1);
void Log(ILogger logger, T1 arg1, Exception exception)
{
logger.Log(logLevel, eventId, new LogValues<T1>(formatter, arg1), exception, LogValues<T1>.Callback);
}
return (logger, arg1, exception) =>
{
if (logger.IsEnabled(logLevel))
{
logger.Log(logLevel, eventId, new LogValues<T1>(formatter, arg1), exception, LogValues<T1>.Callback);
Log(logger, arg1, exception);
}
};
}
@ -124,11 +129,16 @@ namespace Microsoft.Extensions.Logging
{
var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 2);
void Log(ILogger logger, T1 arg1, T2 arg2, Exception exception)
{
logger.Log(logLevel, eventId, new LogValues<T1, T2>(formatter, arg1, arg2), exception, LogValues<T1, T2>.Callback);
}
return (logger, arg1, arg2, exception) =>
{
if (logger.IsEnabled(logLevel))
{
logger.Log(logLevel, eventId, new LogValues<T1, T2>(formatter, arg1, arg2), exception, LogValues<T1, T2>.Callback);
Log(logger, arg1, arg2, exception);
}
};
}
@ -147,11 +157,16 @@ namespace Microsoft.Extensions.Logging
{
var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 3);
void Log(ILogger logger, T1 arg1, T2 arg2, T3 arg3, Exception exception)
{
logger.Log(logLevel, eventId, new LogValues<T1, T2, T3>(formatter, arg1, arg2, arg3), exception, LogValues<T1, T2, T3>.Callback);
}
return (logger, arg1, arg2, arg3, exception) =>
{
if (logger.IsEnabled(logLevel))
{
logger.Log(logLevel, eventId, new LogValues<T1, T2, T3>(formatter, arg1, arg2, arg3), exception, LogValues<T1, T2, T3>.Callback);
Log(logger, arg1, arg2, arg3, exception);
}
};
}
@ -171,11 +186,16 @@ namespace Microsoft.Extensions.Logging
{
var formatter = CreateLogValuesFormatter(formatString, expectedNamedParameterCount: 4);
void Log(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, Exception exception)
{
logger.Log(logLevel, eventId, new LogValues<T1, T2, T3, T4>(formatter, arg1, arg2, arg3, arg4), exception, LogValues<T1, T2, T3, T4>.Callback);
}
return (logger, arg1, arg2, arg3, arg4, exception) =>
{
if (logger.IsEnabled(logLevel))
{
logger.Log(logLevel, eventId, new LogValues<T1, T2, T3, T4>(formatter, arg1, arg2, arg3, arg4), exception, LogValues<T1, T2, T3, T4>.Callback);
Log(logger, arg1, arg2, arg3, arg4, exception);
}
};
}
@ -245,11 +265,9 @@ namespace Microsoft.Extensions.Logging
return logValuesFormatter;
}
private class LogValues : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues)state)._formatter.Format(((LogValues)state).ToArray());
private static object[] _valueArray = new object[0];
public static readonly Func<LogValues, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
@ -270,22 +288,14 @@ namespace Microsoft.Extensions.Logging
}
}
public int Count
{
get
{
return 1;
}
}
public int Count => 1;
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
yield return this[0];
}
public object[] ToArray() => _valueArray;
public override string ToString() => _formatter.Format(ToArray());
public override string ToString() => _formatter.Format();
IEnumerator IEnumerable.GetEnumerator()
{
@ -293,9 +303,9 @@ namespace Microsoft.Extensions.Logging
}
}
private class LogValues<T0> : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues<T0> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0>)state)._formatter.Format(((LogValues<T0>)state).ToArray());
public static readonly Func<LogValues<T0>, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
private readonly T0 _value0;
@ -310,25 +320,19 @@ namespace Microsoft.Extensions.Logging
{
get
{
if (index == 0)
switch (index)
{
return new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0);
case 0:
return new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0);
case 1:
return new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat);
default:
throw new IndexOutOfRangeException(nameof(index));
}
else if (index == 1)
{
return new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat);
}
throw new IndexOutOfRangeException(nameof(index));
}
}
public int Count
{
get
{
return 2;
}
}
public int Count => 2;
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
@ -338,9 +342,8 @@ namespace Microsoft.Extensions.Logging
}
}
public object[] ToArray() => new object[] { _value0 };
public override string ToString() => _formatter.Format(ToArray());
public override string ToString() => _formatter.Format(_value0);
IEnumerator IEnumerable.GetEnumerator()
{
@ -348,9 +351,9 @@ namespace Microsoft.Extensions.Logging
}
}
private class LogValues<T0, T1> : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues<T0, T1> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0, T1>)state)._formatter.Format(((LogValues<T0, T1>)state).ToArray());
public static readonly Func<LogValues<T0, T1>, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
private readonly T0 _value0;
@ -381,13 +384,7 @@ namespace Microsoft.Extensions.Logging
}
}
public int Count
{
get
{
return 3;
}
}
public int Count => 3;
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
@ -397,9 +394,7 @@ namespace Microsoft.Extensions.Logging
}
}
public object[] ToArray() => new object[] { _value0, _value1 };
public override string ToString() => _formatter.Format(ToArray());
public override string ToString() => _formatter.Format(_value0, _value1);
IEnumerator IEnumerable.GetEnumerator()
{
@ -407,22 +402,16 @@ namespace Microsoft.Extensions.Logging
}
}
private class LogValues<T0, T1, T2> : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues<T0, T1, T2> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0, T1, T2>)state)._formatter.Format(((LogValues<T0, T1, T2>)state).ToArray());
public static readonly Func<LogValues<T0, T1, T2>, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
public T0 _value0;
public T1 _value1;
public T2 _value2;
private readonly T0 _value0;
private readonly T1 _value1;
private readonly T2 _value2;
public int Count
{
get
{
return 4;
}
}
public int Count => 4;
public KeyValuePair<string, object> this[int index]
{
@ -452,9 +441,7 @@ namespace Microsoft.Extensions.Logging
_value2 = value2;
}
public object[] ToArray() => new object[] { _value0, _value1, _value2 };
public override string ToString() => _formatter.Format(ToArray());
public override string ToString() => _formatter.Format(_value0, _value1, _value2);
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
@ -470,23 +457,17 @@ namespace Microsoft.Extensions.Logging
}
}
private class LogValues<T0, T1, T2, T3> : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues<T0, T1, T2, T3> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0, T1, T2, T3>)state)._formatter.Format(((LogValues<T0, T1, T2, T3>)state).ToArray());
public static readonly Func<LogValues<T0, T1, T2, T3>, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
public T0 _value0;
public T1 _value1;
public T2 _value2;
public T3 _value3;
private readonly T0 _value0;
private readonly T1 _value1;
private readonly T2 _value2;
private readonly T3 _value3;
public int Count
{
get
{
return 5;
}
}
public int Count => 5;
public KeyValuePair<string, object> this[int index]
{
@ -519,7 +500,7 @@ namespace Microsoft.Extensions.Logging
_value3 = value3;
}
public object[] ToArray() => new object[] { _value0, _value1, _value2, _value3 };
private object[] ToArray() => new object[] { _value0, _value1, _value2, _value3 };
public override string ToString() => _formatter.Format(ToArray());
@ -537,24 +518,18 @@ namespace Microsoft.Extensions.Logging
}
}
private class LogValues<T0, T1, T2, T3, T4> : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues<T0, T1, T2, T3, T4> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0, T1, T2, T3, T4>)state)._formatter.Format(((LogValues<T0, T1, T2, T3, T4>)state).ToArray());
public static readonly Func<LogValues<T0, T1, T2, T3, T4>, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
public T0 _value0;
public T1 _value1;
public T2 _value2;
public T3 _value3;
public T4 _value4;
private readonly T0 _value0;
private readonly T1 _value1;
private readonly T2 _value2;
private readonly T3 _value3;
private readonly T4 _value4;
public int Count
{
get
{
return 6;
}
}
public int Count => 6;
public KeyValuePair<string, object> this[int index]
{
@ -590,7 +565,7 @@ namespace Microsoft.Extensions.Logging
_value4 = value4;
}
public object[] ToArray() => new object[] { _value0, _value1, _value2, _value3, _value4 };
private object[] ToArray() => new object[] { _value0, _value1, _value2, _value3, _value4 };
public override string ToString() => _formatter.Format(ToArray());
@ -608,25 +583,19 @@ namespace Microsoft.Extensions.Logging
}
}
private class LogValues<T0, T1, T2, T3, T4, T5> : IReadOnlyList<KeyValuePair<string, object>>
private readonly struct LogValues<T0, T1, T2, T3, T4, T5> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0, T1, T2, T3, T4, T5>)state)._formatter.Format(((LogValues<T0, T1, T2, T3, T4, T5>)state).ToArray());
public static readonly Func<LogValues<T0, T1, T2, T3, T4, T5>, Exception, string> Callback = (state, exception) => state.ToString();
private readonly LogValuesFormatter _formatter;
public T0 _value0;
public T1 _value1;
public T2 _value2;
public T3 _value3;
public T4 _value4;
public T5 _value5;
private readonly T0 _value0;
private readonly T1 _value1;
private readonly T2 _value2;
private readonly T3 _value3;
private readonly T4 _value4;
private readonly T5 _value5;
public int Count
{
get
{
return 7;
}
}
public int Count => 7;
public KeyValuePair<string, object> this[int index]
{
@ -665,86 +634,7 @@ namespace Microsoft.Extensions.Logging
_value5 = value5;
}
public object[] ToArray() => new object[] { _value0, _value1, _value2, _value3, _value4, _value5 };
public override string ToString() => _formatter.Format(ToArray());
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
for (int i = 0; i < Count; ++i)
{
yield return this[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
private class LogValues<T0, T1, T2, T3, T4, T5, T6> : IReadOnlyList<KeyValuePair<string, object>>
{
public static Func<object, Exception, string> Callback = (state, exception) => ((LogValues<T0, T1, T2, T3, T4, T5, T6>)state)._formatter.Format(((LogValues<T0, T1, T2, T3, T4, T5, T6>)state).ToArray());
private readonly LogValuesFormatter _formatter;
public T0 _value0;
public T1 _value1;
public T2 _value2;
public T3 _value3;
public T4 _value4;
public T5 _value5;
public T6 _value6;
public int Count
{
get
{
return 8;
}
}
public KeyValuePair<string, object> this[int index]
{
get
{
switch (index)
{
case 0:
return new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0);
case 1:
return new KeyValuePair<string, object>(_formatter.ValueNames[1], _value1);
case 2:
return new KeyValuePair<string, object>(_formatter.ValueNames[2], _value2);
case 3:
return new KeyValuePair<string, object>(_formatter.ValueNames[3], _value3);
case 4:
return new KeyValuePair<string, object>(_formatter.ValueNames[4], _value4);
case 5:
return new KeyValuePair<string, object>(_formatter.ValueNames[5], _value5);
case 6:
return new KeyValuePair<string, object>(_formatter.ValueNames[6], _value6);
case 7:
return new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat);
default:
throw new IndexOutOfRangeException(nameof(index));
}
}
}
public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6)
{
_formatter = formatter;
_value0 = value0;
_value1 = value1;
_value2 = value2;
_value3 = value3;
_value4 = value4;
_value5 = value5;
_value6 = value6;
}
public object[] ToArray() => new object[] { _value0, _value1, _value2, _value3, _value4, _value5, _value6 };
private object[] ToArray() => new object[] { _value0, _value1, _value2, _value3, _value4, _value5 };
public override string ToString() => _formatter.Format(ToArray());
@ -763,4 +653,3 @@ namespace Microsoft.Extensions.Logging
}
}
}