diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 008e983842..14749500ec 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -222,8 +222,8 @@ elif [[ "$1" == "bazel.legacy.test" ]]; then elif [[ "$1" == "bazel.noexcept" ]]; then # there are some exceptions and error handling code from the Prometheus and Jaeger Clients # that make this test always fail. ignore Prometheus and Jaeger exporters in the noexcept here. - bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... - bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... + bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... -//examples/prometheus/... + bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... -//examples/prometheus/... exit 0 elif [[ "$1" == "bazel.nortti" ]]; then # there are some exceptions and error handling code from the Prometheus and Jaeger Clients diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index db0fe159be..2367918c7e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -15,6 +15,9 @@ endif() if(WITH_ZIPKIN) add_subdirectory(zipkin) endif() +if(WITH_PROMETHEUS AND NOT WITH_METRICS_PREVIEW) + add_subdirectory(prometheus) +endif() add_subdirectory(plugin) add_subdirectory(simple) add_subdirectory(batch) diff --git a/examples/prometheus/BUILD b/examples/prometheus/BUILD new file mode 100644 index 0000000000..edbfde61e6 --- /dev/null +++ b/examples/prometheus/BUILD @@ -0,0 +1,14 @@ +cc_binary( + name = "prometheus_example", + srcs = [ + "main.cc", + ], + linkopts = ["-pthread"], + tags = ["ostream"], + deps = [ + "//api", + "//examples/common/metrics_foo_library:common_metrics_foo_library", + "//exporters/prometheus:prometheus_exporter", + "//sdk/src/metrics", + ], +) diff --git a/examples/prometheus/CMakeLists.txt b/examples/prometheus/CMakeLists.txt new file mode 100644 index 0000000000..b377920dee --- /dev/null +++ b/examples/prometheus/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${CMAKE_SOURCE_DIR}/exporters/prometheus/include) +add_executable(prometheus_example main.cc) +target_link_libraries( + prometheus_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics + prometheus_exporter opentelemetry_resources common_metrics_foo_library) diff --git a/examples/prometheus/main.cc b/examples/prometheus/main.cc new file mode 100644 index 0000000000..77a648f55d --- /dev/null +++ b/examples/prometheus/main.cc @@ -0,0 +1,118 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/exporters/prometheus/exporter.h" +# include "opentelemetry/metrics/provider.h" +# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/metrics/meter.h" +# include "opentelemetry/sdk/metrics/meter_provider.h" + +# ifdef BAZEL_BUILD +# include "examples/common/metrics_foo_library/foo_library.h" +# else +# include "metrics_foo_library/foo_library.h" +# endif + +namespace metrics_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace metrics_exporter = opentelemetry::exporter::metrics; +namespace metrics_api = opentelemetry::metrics; + +namespace +{ + +void initMetrics(const std::string &name, const std::string &addr) +{ + metrics_exporter::PrometheusExporterOptions opts; + if (!addr.empty()) + { + opts.url = addr; + } + std::puts("PrometheusExporter example program running ..."); + + std::unique_ptr exporter{ + new metrics_exporter::PrometheusExporter(opts)}; + + std::string version{"1.2.0"}; + std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; + + // Initialize and set the global MeterProvider + metrics_sdk::PeriodicExportingMetricReaderOptions options; + options.export_interval_millis = std::chrono::milliseconds(1000); + options.export_timeout_millis = std::chrono::milliseconds(500); + std::unique_ptr reader{ + new metrics_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + auto provider = std::shared_ptr(new metrics_sdk::MeterProvider()); + auto p = std::static_pointer_cast(provider); + p->AddMetricReader(std::move(reader)); + + // counter view + std::string counter_name = name + "_counter"; + std::unique_ptr instrument_selector{ + new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kCounter, counter_name)}; + std::unique_ptr meter_selector{ + new metrics_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr sum_view{ + new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kSum}}; + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + + // histogram view + std::string histogram_name = name + "_histogram"; + std::unique_ptr histogram_instrument_selector{ + new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kHistogram, histogram_name)}; + std::unique_ptr histogram_meter_selector{ + new metrics_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr histogram_view{ + new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kHistogram}}; + p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); + metrics_api::Provider::SetMeterProvider(provider); +} +} // namespace + +int main(int argc, char **argv) +{ + std::string example_type; + std::string addr{"localhost:8080"}; + if (argc == 1) + { + std::puts("usage: $prometheus_example "); + } + + if (argc >= 2) + { + example_type = argv[1]; + } + if (argc > 2) + { + addr = argv[2]; + } + + std::string name{"prometheus_metric_example"}; + initMetrics(name, addr); + + if (example_type == "counter") + { + foo_library::counter_example(name); + } + else if (example_type == "histogram") + { + foo_library::histogram_example(name); + } + else + { + std::thread counter_example{&foo_library::counter_example, name}; + std::thread histogram_example{&foo_library::histogram_example, name}; + counter_example.join(); + histogram_example.join(); + } +} +#else +int main() {} +#endif diff --git a/examples/prometheus/prometheus.yml b/examples/prometheus/prometheus.yml new file mode 100644 index 0000000000..3f415d39dc --- /dev/null +++ b/examples/prometheus/prometheus.yml @@ -0,0 +1,16 @@ +global: + scrape_interval: 5s + scrape_timeout: 2s + evaluation_interval: 5s +alerting: + alertmanagers: + - follow_redirects: true + scheme: http + timeout: 5s + api_version: v2 + static_configs: + - targets: [localhost:8080] +scrape_configs: + - job_name: otel + static_configs: + - targets: ['localhost:8080'] \ No newline at end of file diff --git a/examples/prometheus/run.sh b/examples/prometheus/run.sh new file mode 100644 index 0000000000..412c6ef454 --- /dev/null +++ b/examples/prometheus/run.sh @@ -0,0 +1 @@ +docker run -p 9090:9090 -v $(pwd):/etc/prometheus --network="host" prom/prometheus \ No newline at end of file diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h index 6945f09bb9..151244928f 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h @@ -31,7 +31,7 @@ namespace metrics inline const std::string GetOtlpDefaultHttpEndpoint() { constexpr char kPrometheusEndpointEnv[] = "PROMETHEUS_EXPORTER_ENDPOINT"; - constexpr char kPrometheusEndpointDefault[] = "http://localhost:8080"; + constexpr char kPrometheusEndpointDefault[] = "localhost:8080"; auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kPrometheusEndpointEnv); return endpoint.size() ? endpoint : kPrometheusEndpointDefault;