From 5e369a6af1e0d7fd0d03bdd5035e7fe325ae4d98 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Sun, 14 Nov 2021 17:00:04 -0800 Subject: [PATCH] update promtheus exporter benchmark (#2607) --- ...ver.cs => PrometheusExporterHttpServer.cs} | 12 ++--- .../PrometheusExporter.cs | 4 +- ...s.cs => PrometheusSerializerBenchmarks.cs} | 54 +++++++------------ ...s => PrometheusExporterHttpServerTests.cs} | 6 +-- 4 files changed, 31 insertions(+), 45 deletions(-) rename src/OpenTelemetry.Exporter.Prometheus/Implementation/{PrometheusExporterMetricsHttpServer.cs => PrometheusExporterHttpServer.cs} (95%) rename test/Benchmarks/Exporter/{PrometheusExporterMiddlewareBenchmarks.cs => PrometheusSerializerBenchmarks.cs} (53%) rename test/OpenTelemetry.Exporter.Prometheus.Tests/{PrometheusExporterMetricsHttpServerTests.cs => PrometheusExporterHttpServerTests.cs} (94%) diff --git a/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterMetricsHttpServer.cs b/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterHttpServer.cs similarity index 95% rename from src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterMetricsHttpServer.cs rename to src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterHttpServer.cs index 4680f0291..d60d8552a 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterMetricsHttpServer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterHttpServer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,9 +23,9 @@ using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Prometheus { /// - /// A HTTP listener used to expose Prometheus metrics. + /// An HTTP listener used to expose Prometheus metrics. /// - internal sealed class PrometheusExporterMetricsHttpServer : IDisposable + internal sealed class PrometheusExporterHttpServer : IDisposable { private readonly PrometheusExporter exporter; private readonly HttpListener httpListener = new HttpListener(); @@ -35,10 +35,10 @@ namespace OpenTelemetry.Exporter.Prometheus private Task workerThread; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The instance. - public PrometheusExporterMetricsHttpServer(PrometheusExporter exporter) + public PrometheusExporterHttpServer(PrometheusExporter exporter) { Guard.Null(exporter, nameof(exporter)); @@ -68,7 +68,7 @@ namespace OpenTelemetry.Exporter.Prometheus /// /// Start exporter. /// - /// An optional that can be used to stop the htto server. + /// An optional that can be used to stop the HTTP server. public void Start(CancellationToken token = default) { lock (this.syncObject) diff --git a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporter.cs b/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporter.cs index 4df7718f7..30be8f412 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporter.cs +++ b/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporter.cs @@ -32,7 +32,7 @@ namespace OpenTelemetry.Exporter internal readonly PrometheusExporterOptions Options; internal Batch Metrics; // TODO: this is no longer needed, we can remove it later private readonly SemaphoreSlim semaphore = new SemaphoreSlim(1, 1); - private readonly PrometheusExporterMetricsHttpServer metricsHttpServer; + private readonly PrometheusExporterHttpServer metricsHttpServer; private Func funcCollect; private Func, ExportResult> funcExport; private bool disposed; @@ -49,7 +49,7 @@ namespace OpenTelemetry.Exporter { try { - this.metricsHttpServer = new PrometheusExporterMetricsHttpServer(this); + this.metricsHttpServer = new PrometheusExporterHttpServer(this); this.metricsHttpServer.Start(); } catch (Exception ex) diff --git a/test/Benchmarks/Exporter/PrometheusExporterMiddlewareBenchmarks.cs b/test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs similarity index 53% rename from test/Benchmarks/Exporter/PrometheusExporterMiddlewareBenchmarks.cs rename to test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs index 5bb7be4b6..a6a125cf0 100644 --- a/test/Benchmarks/Exporter/PrometheusExporterMiddlewareBenchmarks.cs +++ b/test/Benchmarks/Exporter/PrometheusSerializerBenchmarks.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,17 +14,15 @@ // limitations under the License. // -#if NETCOREAPP3_1_OR_GREATER +extern alias InMemory; + using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.IO; -using System.Threading; -using System.Threading.Tasks; using BenchmarkDotNet.Attributes; -using Microsoft.AspNetCore.Http; +using InMemory::OpenTelemetry.Metrics; using OpenTelemetry; -using OpenTelemetry.Exporter; using OpenTelemetry.Exporter.Prometheus; using OpenTelemetry.Metrics; using OpenTelemetry.Tests; @@ -32,67 +30,55 @@ using OpenTelemetry.Tests; namespace Benchmarks.Exporter { [MemoryDiagnoser] - public class PrometheusExporterMiddlewareBenchmarks + public class PrometheusSerializerBenchmarks { private Meter meter; - private MemoryStream responseStream; private MeterProvider meterProvider; - private PrometheusExporter exporter; - private DefaultHttpContext context; + private List metrics = new List(); + private byte[] buffer = new byte[85000]; [Params(1, 1000, 10000)] - public int NumberOfExportCalls { get; set; } + public int NumberOfSerializeCalls { get; set; } [GlobalSetup] public void GlobalSetup() { this.meter = new Meter(Utils.GetCurrentMethodName()); - this.responseStream = new MemoryStream(1024 * 1024); - this.meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter(this.meter.Name) - .AddPrometheusExporter() + .AddInMemoryExporter(this.metrics) .Build(); var counter = this.meter.CreateCounter("counter_name_1", "long", "counter_name_1_description"); - counter.Add(18, new KeyValuePair("label1", "value1"), new KeyValuePair("label2", "value2")); + counter.Add(18, new("label1", "value1"), new("label2", "value2")); var gauge = this.meter.CreateObservableGauge("gauge_name_1", () => 18.0D, "long", "gauge_name_1_description"); var histogram = this.meter.CreateHistogram("histogram_name_1", "long", "histogram_name_1_description"); - histogram.Record(100, new KeyValuePair("label1", "value1"), new KeyValuePair("label2", "value2")); + histogram.Record(100, new("label1", "value1"), new("label2", "value2")); - this.context = new DefaultHttpContext(); - this.context.Response.Body = this.responseStream; - - if (!this.meterProvider.TryFindExporter(out this.exporter)) - { - throw new InvalidOperationException("PrometheusExporter could not be found on MeterProvider."); - } - - this.exporter.Collect(Timeout.Infinite); + this.meterProvider.ForceFlush(); } [GlobalCleanup] public void GlobalCleanup() { this.meter?.Dispose(); - this.responseStream?.Dispose(); this.meterProvider?.Dispose(); } - /* TODO: revisit this after PrometheusExporter race condition is solved + // TODO: this has a dependency on https://github.com/open-telemetry/opentelemetry-dotnet/issues/2361 [Benchmark] - public async Task WriteMetricsToResponse() + public void WriteMetric() { - this.responseStream.Position = 0; - - for (int i = 0; i < this.NumberOfExportCalls; i++) + for (int i = 0; i < this.NumberOfSerializeCalls; i++) { - await PrometheusExporterMiddleware.WriteMetricsToResponse(this.exporter, this.context.Response).ConfigureAwait(false); + int cursor = 0; + foreach (var metric in this.metrics) + { + cursor = PrometheusSerializer.WriteMetric(this.buffer, cursor, metric); + } } } - */ } } -#endif diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterMetricsHttpServerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterHttpServerTests.cs similarity index 94% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterMetricsHttpServerTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterHttpServerTests.cs index 3d3b739bf..8c3a35d77 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterMetricsHttpServerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterHttpServerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,10 +26,10 @@ using Xunit; namespace OpenTelemetry.Exporter.Prometheus.Tests { - public class PrometheusExporterMetricsHttpServerTests + public class PrometheusExporterHttpServerTests { [Fact] - public async Task PrometheusExporterMetricsHttpServerIntegration() + public async Task PrometheusExporterHttpServerIntegration() { Random random = new Random(); int port = 0;