Skip to content

Commit

Permalink
Add otlp log and trace exporter benchmarks (#4807)
Browse files Browse the repository at this point in the history
  • Loading branch information
vishweshbankwar authored Aug 29, 2023
1 parent f698b5d commit bb1253e
Show file tree
Hide file tree
Showing 4 changed files with 348 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'net462'">
<PackageReference Include="Grpc.AspNetCore.Server" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.AspNetCore\OpenTelemetry.Instrumentation.AspNetCore.csproj" />
</ItemGroup>
Expand Down
154 changes: 154 additions & 0 deletions test/Benchmarks/Exporter/OtlpLogExporterBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// <copyright file="OtlpLogExporterBenchmarks.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

#if !NETFRAMEWORK
extern alias OpenTelemetryProtocol;

using BenchmarkDotNet.Attributes;
using Benchmarks.Helper;
using Grpc.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry;
using OpenTelemetry.Internal;
using OpenTelemetry.Logs;
using OpenTelemetry.Tests;
using OpenTelemetryProtocol::OpenTelemetry.Exporter;
using OtlpCollector = OpenTelemetryProtocol::OpenTelemetry.Proto.Collector.Logs.V1;

/*
BenchmarkDotNet v0.13.6, Windows 11 (10.0.22621.2134/22H2/2022Update/SunValley2) (Hyper-V)
AMD EPYC 7763, 1 CPU, 16 logical and 8 physical cores
.NET SDK 7.0.400
[Host] : .NET 7.0.10 (7.0.1023.36312), X64 RyuJIT AVX2
DefaultJob : .NET 7.0.10 (7.0.1023.36312), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|--------------------- |---------:|--------:|--------:|-------:|-------:|----------:|
| OtlpLogExporter_Http | 138.7 us | 2.08 us | 1.95 us | 0.4883 | 0.2441 | 9.85 KB |
| OtlpLogExporter_Grpc | 268.3 us | 2.57 us | 2.28 us | 0.4883 | - | 9.54 KB |
*/

namespace Benchmarks.Exporter;

public class OtlpLogExporterBenchmarks
{
private OtlpLogExporter exporter;
private LogRecord logRecord;
private CircularBuffer<LogRecord> logRecordBatch;

private IHost host;
private IDisposable server;
private string serverHost;
private int serverPort;

[GlobalSetup(Target = nameof(OtlpLogExporter_Grpc))]
public void GlobalSetupGrpc()
{
this.host = new HostBuilder()
.ConfigureWebHostDefaults(webBuilder => webBuilder
.ConfigureKestrel(options =>
{
options.ListenLocalhost(4317, listenOptions => listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2);
})
.ConfigureServices(services =>
{
services.AddGrpc();
})
.Configure(app =>
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<MockLogService>();
});
}))
.Start();

var options = new OtlpExporterOptions();
this.exporter = new OtlpLogExporter(options);

this.logRecord = LogRecordHelper.CreateTestLogRecord();
this.logRecordBatch = new CircularBuffer<LogRecord>(1);
this.logRecordBatch.Add(this.logRecord);
}

[GlobalSetup(Target = nameof(OtlpLogExporter_Http))]
public void GlobalSetupHttp()
{
this.server = TestHttpServer.RunServer(
(ctx) =>
{
ctx.Response.StatusCode = 200;
ctx.Response.OutputStream.Close();
},
out this.serverHost,
out this.serverPort);

var options = new OtlpExporterOptions
{
Endpoint = new Uri($"http://{this.serverHost}:{this.serverPort}"),
Protocol = OtlpExportProtocol.HttpProtobuf,
};
this.exporter = new OtlpLogExporter(options);

this.logRecord = LogRecordHelper.CreateTestLogRecord();
this.logRecordBatch = new CircularBuffer<LogRecord>(1);
this.logRecordBatch.Add(this.logRecord);
}

[GlobalCleanup(Target = nameof(OtlpLogExporter_Grpc))]
public void GlobalCleanupGrpc()
{
this.exporter.Shutdown();
this.exporter.Dispose();
this.host.Dispose();
}

[GlobalCleanup(Target = nameof(OtlpLogExporter_Http))]
public void GlobalCleanupHttp()
{
this.exporter.Shutdown();
this.exporter.Dispose();
this.server.Dispose();
}

[Benchmark]
public void OtlpLogExporter_Http()
{
this.exporter.Export(new Batch<LogRecord>(this.logRecordBatch, 1));
}

[Benchmark]
public void OtlpLogExporter_Grpc()
{
this.exporter.Export(new Batch<LogRecord>(this.logRecordBatch, 1));
}

private sealed class MockLogService : OtlpCollector.LogsService.LogsServiceBase
{
private static OtlpCollector.ExportLogsServiceResponse response = new OtlpCollector.ExportLogsServiceResponse();

public override Task<OtlpCollector.ExportLogsServiceResponse> Export(OtlpCollector.ExportLogsServiceRequest request, ServerCallContext context)
{
return Task.FromResult(response);
}
}
}
#endif
156 changes: 156 additions & 0 deletions test/Benchmarks/Exporter/OtlpTraceExporterBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// <copyright file="OtlpTraceExporterBenchmarks.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

#if !NETFRAMEWORK
extern alias OpenTelemetryProtocol;

using System.Diagnostics;
using BenchmarkDotNet.Attributes;
using Benchmarks.Helper;
using Grpc.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry;
using OpenTelemetry.Internal;
using OpenTelemetry.Tests;
using OpenTelemetryProtocol::OpenTelemetry.Exporter;
using OtlpCollector = OpenTelemetryProtocol::OpenTelemetry.Proto.Collector.Trace.V1;

/*
BenchmarkDotNet v0.13.6, Windows 11 (10.0.22621.2134/22H2/2022Update/SunValley2) (Hyper-V)
AMD EPYC 7763, 1 CPU, 16 logical and 8 physical cores
.NET SDK 7.0.400
[Host] : .NET 7.0.10 (7.0.1023.36312), X64 RyuJIT AVX2
DefaultJob : .NET 7.0.10 (7.0.1023.36312), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
|----------------------- |---------:|--------:|--------:|-------:|-------:|----------:|
| OtlpTraceExporter_Http | 139.4 us | 1.41 us | 1.32 us | 0.4883 | 0.2441 | 9.8 KB |
| OtlpTraceExporter_Grpc | 263.0 us | 3.47 us | 3.24 us | 0.4883 | - | 9.34 KB |
*/

namespace Benchmarks.Exporter;

public class OtlpTraceExporterBenchmarks
{
private OtlpTraceExporter exporter;
private Activity activity;
private CircularBuffer<Activity> activityBatch;

private IHost host;
private IDisposable server;
private string serverHost;
private int serverPort;

[GlobalSetup(Target = nameof(OtlpTraceExporter_Grpc))]
public void GlobalSetupGrpc()
{
this.host = new HostBuilder()
.ConfigureWebHostDefaults(webBuilder => webBuilder
.ConfigureKestrel(options =>
{
options.ListenLocalhost(4317, listenOptions => listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2);
})
.ConfigureServices(services =>
{
services.AddGrpc();
})
.Configure(app =>
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<MockTraceService>();
});
}))
.Start();

var options = new OtlpExporterOptions();
this.exporter = new OtlpTraceExporter(options);

this.activity = ActivityHelper.CreateTestActivity();
this.activityBatch = new CircularBuffer<Activity>(1);
this.activityBatch.Add(this.activity);
}

[GlobalSetup(Target = nameof(OtlpTraceExporter_Http))]
public void GlobalSetupHttp()
{
this.server = TestHttpServer.RunServer(
(ctx) =>
{
ctx.Response.StatusCode = 200;
ctx.Response.OutputStream.Close();
},
out this.serverHost,
out this.serverPort);

var options = new OtlpExporterOptions
{
Endpoint = new Uri($"http://{this.serverHost}:{this.serverPort}"),
Protocol = OtlpExportProtocol.HttpProtobuf,
};
this.exporter = new OtlpTraceExporter(options);

this.activity = ActivityHelper.CreateTestActivity();
this.activityBatch = new CircularBuffer<Activity>(1);
this.activityBatch.Add(this.activity);
}

[GlobalCleanup(Target = nameof(OtlpTraceExporter_Grpc))]
public void GlobalCleanupGrpc()
{
this.exporter.Shutdown();
this.exporter.Dispose();
this.activity.Dispose();
this.host.Dispose();
}

[GlobalCleanup(Target = nameof(OtlpTraceExporter_Http))]
public void GlobalCleanupHttp()
{
this.exporter.Shutdown();
this.exporter.Dispose();
this.server.Dispose();
this.activity.Dispose();
}

[Benchmark]
public void OtlpTraceExporter_Http()
{
this.exporter.Export(new Batch<Activity>(this.activityBatch, 1));
}

[Benchmark]
public void OtlpTraceExporter_Grpc()
{
this.exporter.Export(new Batch<Activity>(this.activityBatch, 1));
}

private sealed class MockTraceService : OtlpCollector.TraceService.TraceServiceBase
{
private static OtlpCollector.ExportTraceServiceResponse response = new OtlpCollector.ExportTraceServiceResponse();

public override Task<OtlpCollector.ExportTraceServiceResponse> Export(OtlpCollector.ExportTraceServiceRequest request, ServerCallContext context)
{
return Task.FromResult(response);
}
}
}
#endif
37 changes: 37 additions & 0 deletions test/Benchmarks/Helper/LogRecordHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// <copyright file="LogRecordHelper.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;

namespace Benchmarks.Helper;

internal class LogRecordHelper
{
internal static LogRecord CreateTestLogRecord()
{
var items = new List<LogRecord>(1);
using var factory = LoggerFactory.Create(builder => builder
.AddOpenTelemetry(loggerOptions =>
{
loggerOptions.AddInMemoryExporter(items);
}));

var logger = factory.CreateLogger("TestLogger");
logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99);
return items[0];
}
}

0 comments on commit bb1253e

Please sign in to comment.