From 769f87d802303153aed658885bf0bd5500bbc62e Mon Sep 17 00:00:00 2001 From: ishan0803 Date: Wed, 7 Jan 2026 19:52:47 +0530 Subject: [PATCH] exporters/otlp: add HTTP metric exporter benchmark MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a Google Benchmark-based performance benchmark for the OTLP HTTP metric exporter, covering both binary (protobuf) and JSON encodings. Key changes: - Add `otlp_http_metric_exporter_benchmark` target under `WITH_BENCHMARK && WITH_OTLP_HTTP`. - Benchmark `OtlpHttpMetricExporter::Export()` across increasing numbers of metric data points (1 → 10,000). - Measure export cost for both binary and JSON content types. - Disable retries and logging to reduce noise and isolate exporter overhead. This benchmark provides a baseline for evaluating export performance and future optimizations in the OTLP HTTP metric exporter. Fix resource lifetime in OTLP HTTP metric exporter benchmark fix CI build errors in HTTP metric exporter benchmark --- exporters/otlp/CMakeLists.txt | 11 ++ .../otlp_http_metric_exporter_benchmark.cc | 128 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 exporters/otlp/benchmark/otlp_http_metric_exporter_benchmark.cc diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 23a5cd6b6c..3cff324ec9 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -999,3 +999,14 @@ if(BUILD_TESTING) TEST_LIST otlp_file_metric_exporter_factory_test) endif() endif() # BUILD_TESTING + +if(WITH_BENCHMARK AND WITH_OTLP_HTTP) + add_executable(otlp_http_metric_exporter_benchmark + benchmark/otlp_http_metric_exporter_benchmark.cc) + + target_link_libraries( + otlp_http_metric_exporter_benchmark + PRIVATE opentelemetry_exporter_otlp_http_metric opentelemetry_metrics + opentelemetry_resources benchmark::benchmark + ${CMAKE_THREAD_LIBS_INIT}) +endif() diff --git a/exporters/otlp/benchmark/otlp_http_metric_exporter_benchmark.cc b/exporters/otlp/benchmark/otlp_http_metric_exporter_benchmark.cc new file mode 100644 index 0000000000..b18496c532 --- /dev/null +++ b/exporters/otlp/benchmark/otlp_http_metric_exporter_benchmark.cc @@ -0,0 +1,128 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include + +#include +#include +#include +#include +#include + +#include "opentelemetry/exporters/otlp/otlp_http.h" +#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter.h" +#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h" + +#include "opentelemetry/nostd/string_view.h" + +#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/common/global_log_handler.h" + +#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" + +#include "opentelemetry/sdk/metrics/data/metric_data.h" +#include "opentelemetry/sdk/metrics/data/point_data.h" +#include "opentelemetry/sdk/metrics/export/metric_producer.h" +#include "opentelemetry/sdk/metrics/instruments.h" +#include "opentelemetry/sdk/resource/resource.h" + +using InstrumentationScope = opentelemetry::sdk::instrumentationscope::InstrumentationScope; +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::exporter::otlp; + +// Create ResourceMetrics with a single metric containing 'n' data points +static ResourceMetrics MakeMetrics(std::size_t n_points) +{ + ResourceMetrics rm; + static const opentelemetry::sdk::resource::Resource resource = + opentelemetry::sdk::resource::Resource::Create({{"service.name", "metric-benchmark"}}); + rm.resource_ = &resource; + + static auto scope = InstrumentationScope::Create("benchmark", "1.0.0"); + ScopeMetrics scope_metrics; + scope_metrics.scope_ = scope.get(); + + MetricData metric; + metric.instrument_descriptor.name_ = "cpu.utilization"; + metric.instrument_descriptor.unit_ = "1"; + metric.instrument_descriptor.type_ = InstrumentType::kCounter; + metric.aggregation_temporality = AggregationTemporality::kCumulative; + + for (std::size_t i = 0; i < n_points; ++i) + { + SumPointData sum; + sum.value_ = static_cast(i); + sum.is_monotonic_ = true; + + PointDataAttributes p; + p.attributes = {{"core", static_cast(i)}}; + p.point_data = sum; + + metric.point_data_attr_.push_back(p); + } + + scope_metrics.metric_data_.push_back(metric); + rm.scope_metric_data_.push_back(scope_metrics); + return rm; +} + +// Benchmark Export() using Binary encoding +static void BM_OtlpHttpMetricExporter_Export_Binary(benchmark::State &state) +{ + OtlpHttpMetricExporterOptions opts; + opts.url = "http://localhost:4318/v1/metrics"; + opts.content_type = HttpRequestContentType::kBinary; + opts.timeout = std::chrono::milliseconds(1); + opts.retry_policy_max_attempts = 0; + + OtlpHttpMetricExporter exporter(opts); + auto metrics = MakeMetrics(state.range(0)); + + for (auto _ : state) + { + benchmark::DoNotOptimize(exporter.Export(metrics)); + } + + state.SetItemsProcessed(state.iterations() * state.range(0)); +} + +// Benchmark Export() using JSON encoding +static void BM_OtlpHttpMetricExporter_Export_Json(benchmark::State &state) +{ + OtlpHttpMetricExporterOptions opts; + opts.url = "http://localhost:4318/v1/metrics"; + opts.content_type = HttpRequestContentType::kJson; + opts.timeout = std::chrono::milliseconds(1); + opts.retry_policy_max_attempts = 0; + + OtlpHttpMetricExporter exporter(opts); + auto metrics = MakeMetrics(state.range(0)); + + for (auto _ : state) + { + benchmark::DoNotOptimize(exporter.Export(metrics)); + } + + state.SetItemsProcessed(state.iterations() * state.range(0)); +} + +BENCHMARK(BM_OtlpHttpMetricExporter_Export_Binary) + ->RangeMultiplier(10) + ->Range(1, 10000) + ->Unit(benchmark::kMicrosecond); + +BENCHMARK(BM_OtlpHttpMetricExporter_Export_Json) + ->RangeMultiplier(10) + ->Range(1, 10000) + ->Unit(benchmark::kMicrosecond); + +int main(int argc, char **argv) +{ + opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogLevel( + opentelemetry::sdk::common::internal_log::LogLevel::None); + + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); + benchmark::Shutdown(); + return 0; +}