Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Buffering;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Telemetry.Bench;

[MemoryDiagnoser]
[InvocationCount(1)]
public class BufferingImpactBench
{
private ServiceProvider _baselineServices = null!;
private ServiceProvider _bufferedServices = null!;
private ILogger[] _baselineLoggers = null!;
private ILogger[] _bufferedLoggers = null!;
private GlobalLogBuffer _buffer = null!;

[Params(10_000, 20_000)]
public int RecordsPerMinute { get; set; }

[GlobalSetup]
public void GlobalSetup()
{
_baselineServices = CreateServices(bufferingEnabled: false);
_bufferedServices = CreateServices(bufferingEnabled: true);
_baselineLoggers = LoggingBenchmarkWorkload.CreateLoggers(_baselineServices.GetRequiredService<ILoggerFactory>());
_bufferedLoggers = LoggingBenchmarkWorkload.CreateLoggers(_bufferedServices.GetRequiredService<ILoggerFactory>());
_buffer = _bufferedServices.GetRequiredService<GlobalLogBuffer>();
}

[GlobalCleanup]
public void GlobalCleanup()
{
_bufferedServices.Dispose();
_baselineServices.Dispose();
}

[IterationCleanup]
public void FlushBuffer()
{
_buffer.Flush();
}

[Benchmark(Baseline = true)]
public void NoBuffering()
{
LoggingBenchmarkWorkload.LogBatch(_baselineLoggers, RecordsPerMinute);
}

[Benchmark]
public void BufferOnly()
{
LoggingBenchmarkWorkload.LogBatch(_bufferedLoggers, RecordsPerMinute);
}

[Benchmark]
public void BufferAndFlush()
{
LoggingBenchmarkWorkload.LogBatch(_bufferedLoggers, RecordsPerMinute);
_buffer.Flush();
}

private static ServiceProvider CreateServices(bool bufferingEnabled)
{
var services = new ServiceCollection();

services.AddLogging(builder =>
{
builder.AddProvider(new BenchLoggerProvider());

if (bufferingEnabled)
{
builder.AddGlobalBuffer(options =>
{
options.AutoFlushDuration = TimeSpan.Zero;
options.MaxBufferSizeInBytes = 512 * 1024 * 1024;
options.Rules.Add(new LogBufferingFilterRule(logLevel: LogLevel.Information));
});
}
});

return services.BuildServiceProvider();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Buffering;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Telemetry.Bench;

[MemoryDiagnoser]
[InvocationCount(1)]
public class CategoryCardinalityImpactBench
{
private const int RecordsPerMinute = 20_000;

private ServiceProvider _baselineServices = null!;
private ServiceProvider _strategyServices = null!;
private ILogger[] _baselineLoggers = null!;
private ILogger[] _strategyLoggers = null!;
private LogBuffer? _strategyBuffer;

public enum SamplingStrategy
{
RandomOnePercent,
CckrOnePercent
}

[Params(50, 100, 200)]
public int CategoryCount { get; set; }

[Params(SamplingStrategy.RandomOnePercent, SamplingStrategy.CckrOnePercent)]
public SamplingStrategy Strategy { get; set; }

[GlobalSetup]
public void GlobalSetup()
{
_baselineServices = CreateServices();
_strategyServices = CreateServices(Strategy, CategoryCount);
_baselineLoggers = CreateLoggers(_baselineServices);
_strategyLoggers = CreateLoggers(_strategyServices);
_strategyBuffer = _strategyServices.GetService<LogBuffer>();
}

[GlobalCleanup]
public void GlobalCleanup()
{
_strategyServices.Dispose();
_baselineServices.Dispose();
}

[IterationCleanup]
public void FlushBuffer()
{
_strategyBuffer?.Flush();
}

[Benchmark(Baseline = true)]
public void NoSampling()
{
LoggingBenchmarkWorkload.LogBatch(_baselineLoggers, RecordsPerMinute);
}

[Benchmark]
public void WithStrategy()
{
LoggingBenchmarkWorkload.LogBatch(_strategyLoggers, RecordsPerMinute);
_strategyBuffer?.Flush();
}

private static ServiceProvider CreateServices(
SamplingStrategy? strategy = null,
int categoryCount = 1)
{
var services = new ServiceCollection();

services.AddLogging(builder =>
{
builder.AddProvider(new SerializedExporterLoggerProvider());

switch (strategy)
{
case SamplingStrategy.RandomOnePercent:
builder.AddRandomProbabilisticSampler(0.01);
break;

case SamplingStrategy.CckrOnePercent:
builder.AddCckrLogSampling(options =>
{
options.Capacity = RecordsPerMinute / 100 / categoryCount;
options.PreserveCapacity = 0;
options.FlushInterval = TimeSpan.FromDays(1);
});
break;
}
});

return services.BuildServiceProvider();
}

private ILogger[] CreateLoggers(ServiceProvider services)
=> LoggingBenchmarkWorkload.CreateLoggers(
services.GetRequiredService<ILoggerFactory>(),
CategoryCount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Buffering;
using Microsoft.Extensions.Diagnostics.Sampling;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Telemetry.Bench;

[MemoryDiagnoser]
[InvocationCount(1)]
public class CckrImpactBench
{
private const int AdaptiveCapacity = 128;

private ServiceProvider _baselineServices = null!;
private ServiceProvider _disabledServices = null!;
private ServiceProvider _retainAllPolicyServices = null!;
private ServiceProvider _retainAllServices = null!;
private ServiceProvider _adaptiveServices = null!;
private ILogger[] _baselineLoggers = null!;
private ILogger[] _disabledLoggers = null!;
private ILogger[] _retainAllPolicyLoggers = null!;
private ILogger[] _retainAllLoggers = null!;
private ILogger[] _adaptiveLoggers = null!;
private LogBuffer _retainAllBuffer = null!;
private LogBuffer _adaptiveBuffer = null!;

[Params(10_000, 20_000)]
public int RecordsPerMinute { get; set; }

[GlobalSetup]
public void GlobalSetup()
{
_baselineServices = CreateServices();
_disabledServices = CreateServices(options => options.Enabled = false);
_retainAllPolicyServices = CreateServices(options => options.RetainAllCategories.Add("Benchmark.*"));
_retainAllServices = CreateServices(RecordsPerMinute / LoggingBenchmarkWorkload.CategoryCount);
_adaptiveServices = CreateServices(AdaptiveCapacity);

_baselineLoggers = CreateLoggers(_baselineServices);
_disabledLoggers = CreateLoggers(_disabledServices);
_retainAllPolicyLoggers = CreateLoggers(_retainAllPolicyServices);
_retainAllLoggers = CreateLoggers(_retainAllServices);
_adaptiveLoggers = CreateLoggers(_adaptiveServices);
_retainAllBuffer = _retainAllServices.GetRequiredService<LogBuffer>();
_adaptiveBuffer = _adaptiveServices.GetRequiredService<LogBuffer>();
}

[GlobalCleanup]
public void GlobalCleanup()
{
_adaptiveServices.Dispose();
_retainAllServices.Dispose();
_retainAllPolicyServices.Dispose();
_disabledServices.Dispose();
_baselineServices.Dispose();
}

[IterationCleanup]
public void FlushBuffers()
{
_retainAllBuffer.Flush();
_adaptiveBuffer.Flush();
}

[Benchmark(Baseline = true)]
public void NoSampling()
{
LoggingBenchmarkWorkload.LogBatch(_baselineLoggers, RecordsPerMinute);
}

[Benchmark]
public void CckrDisabled()
{
LoggingBenchmarkWorkload.LogBatch(_disabledLoggers, RecordsPerMinute);
}

[Benchmark]
public void CckrRetainAllPolicy()
{
LoggingBenchmarkWorkload.LogBatch(_retainAllPolicyLoggers, RecordsPerMinute);
}

[Benchmark]
public void CckrRetainAll()
{
LoggingBenchmarkWorkload.LogBatch(_retainAllLoggers, RecordsPerMinute);
}

[Benchmark]
public void CckrRetainAllAndFlush()
{
LoggingBenchmarkWorkload.LogBatch(_retainAllLoggers, RecordsPerMinute);
_retainAllBuffer.Flush();
}

[Benchmark]
public void CckrAdaptive()
{
LoggingBenchmarkWorkload.LogBatch(_adaptiveLoggers, RecordsPerMinute);
}

[Benchmark]
public void CckrAdaptiveAndFlush()
{
LoggingBenchmarkWorkload.LogBatch(_adaptiveLoggers, RecordsPerMinute);
_adaptiveBuffer.Flush();
}

private static ServiceProvider CreateServices(int? capacity = null)
{
if (!capacity.HasValue)
{
return CreateServices((Action<ReservoirSamplingConfig>?)null);
}

return CreateServices(options =>
{
options.Capacity = capacity.Value;
options.PreserveCapacity = 0;
options.FlushInterval = TimeSpan.FromDays(1);
});
}

private static ServiceProvider CreateServices(Action<ReservoirSamplingConfig>? configure)
{
var services = new ServiceCollection();

services.AddLogging(builder =>
{
builder.AddProvider(new BenchLoggerProvider());

if (configure is not null)
{
builder.AddCckrLogSampling(configure);
}
});

return services.BuildServiceProvider();
}

private static ILogger[] CreateLoggers(ServiceProvider services)
=> LoggingBenchmarkWorkload.CreateLoggers(services.GetRequiredService<ILoggerFactory>());
}
Loading
Loading