From cfaf8a1f6ca33ecdef514cca649168ee9155af68 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 12 Sep 2022 23:44:35 -0700 Subject: [PATCH] Example for OTLP gRPC exporter for Metrics. (#1598) --- examples/otlp/CMakeLists.txt | 8 ++ examples/otlp/README.md | 24 ++++- examples/otlp/grpc_metric_main.cc | 97 +++++++++++++++++++ .../config.dev.yaml | 7 +- 4 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 examples/otlp/grpc_metric_main.cc diff --git a/examples/otlp/CMakeLists.txt b/examples/otlp/CMakeLists.txt index 3bd02737b1..f6bf25f932 100644 --- a/examples/otlp/CMakeLists.txt +++ b/examples/otlp/CMakeLists.txt @@ -37,3 +37,11 @@ if(WITH_OTLP_HTTP) opentelemetry_exporter_otlp_http_log) endif() endif() + +if(WITH_OTLP_GRPC AND NOT WITH_METRICS_PREVIEW) + add_executable(example_otlp_metric_grpc grpc_metric_main.cc) + target_link_libraries( + example_otlp_metric_grpc ${CMAKE_THREAD_LIBS_INIT} + common_metrics_foo_library opentelemetry_metrics + opentelemetry_exporter_otlp_grpc_metrics) +endif() diff --git a/examples/otlp/README.md b/examples/otlp/README.md index 91f86f8f50..f97af279da 100644 --- a/examples/otlp/README.md +++ b/examples/otlp/README.md @@ -4,21 +4,37 @@ This is an example of how to use the [OpenTelemetry Protocol](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/README.md) (OTLP) exporter. +### Traces The application in `grpc_main.cc` initializes an `OtlpGrpcExporter` instance, the application in `http_main.cc` initializes an `OtlpHttpExporter` instance. -The application in `http_log_main.cc` initializes an `OtlpHttpLogExporter` instance, -the application in `grpc_log_main.cc` initializes an `OtlpGrpcLogExporter` instance. And they register a tracer provider from the [OpenTelemetry SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then calls a `foo_library` which has been instrumented using the [OpenTelemetry API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api). +### Logs +The application in `http_log_main.cc` initializes an `OtlpHttpLogExporter` instance, +the application in `grpc_log_main.cc` initializes an `OtlpGrpcLogExporter` instance. +And they register a logger provider from the [OpenTelemetry +SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then +calls a `logs_foo_library` which has been instrumented using the [OpenTelemetry +API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api). + +### Metrics +The application in `grpc_metrics_main.cc` initializes an `OtlpGrpcMetricExporter` instance. +And it registers a meter provider from the [OpenTelemetry +SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then +calls a `metrics_foo_library` which has been instrumented using the [OpenTelemetry +API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api). + +### Enable SSL/TLS To enable TLS authentication for OTLP grpc exporter, SslCredentials can be used by specifying the path to client certificate pem file, or the string containing this certificate via OtlpGrpcExporterOptions. The path to such a .pem file can be provided as a command-line argument alongwith the collector endpoint to the main binary invocation above. +### Running OpenTelemetry Collector as docker container Resulting spans are exported to the **OpenTelemetry Collector** using the OTLP exporter. The OpenTelemetry Collector can be configured to export to other backends (see list of [supported @@ -34,13 +50,13 @@ OpenTelemetry Collector with an OTLP receiver by running: - On Unix based systems use: ```console -docker run --rm -it -p 4317:4317 -p 4318:4318 -v $(pwd)/examples/otlp:/cfg otel/opentelemetry-collector:0.38.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml +docker run --rm -it -p 4317:4317 -p 4318:4318 -v $(pwd)/examples/otlp:/cfg otel/opentelemetry-collector:0.59.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml ``` - On Windows use: ```console -docker run --rm -it -p 4317:4317 -p 4318:4318 -v "%cd%/examples/otlp":/cfg otel/opentelemetry-collector:0.38.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml +docker run --rm -it -p 4317:4317 -p 4318:4318 -v "%cd%/examples/otlp":/cfg otel/opentelemetry-collector:0.59.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml ``` Note that the OTLP gRPC and HTTP exporters connects to the Collector at `localhost:4317` and `localhost:4318/v1/traces` respectively. This can be changed with first argument from command-line, for example: diff --git a/examples/otlp/grpc_metric_main.cc b/examples/otlp/grpc_metric_main.cc new file mode 100644 index 0000000000..c316ed4d1b --- /dev/null +++ b/examples/otlp/grpc_metric_main.cc @@ -0,0 +1,97 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_factory.h" +# include "opentelemetry/metrics/provider.h" +# include "opentelemetry/sdk/metrics/aggregation/default_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" + +# include +# include + +# ifdef BAZEL_BUILD +# include "examples/common/metrics_foo_library/foo_library.h" +# else +# include "metrics_foo_library/foo_library.h" +# endif + +namespace metric_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace metrics_api = opentelemetry::metrics; +namespace otlp_exporter = opentelemetry::exporter::otlp; + +namespace +{ + +otlp_exporter::OtlpGrpcMetricExporterOptions options; + +void initMetrics() +{ + auto exporter = otlp_exporter::OtlpGrpcMetricExporterFactory::Create(options); + + std::string version{"1.2.0"}; + std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; + + // Initialize and set the global MeterProvider + metric_sdk::PeriodicExportingMetricReaderOptions options; + options.export_interval_millis = std::chrono::milliseconds(1000); + options.export_timeout_millis = std::chrono::milliseconds(500); + std::unique_ptr reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + auto provider = std::shared_ptr(new metric_sdk::MeterProvider()); + auto p = std::static_pointer_cast(provider); + p->AddMetricReader(std::move(reader)); + + metrics_api::Provider::SetMeterProvider(provider); +} +} // namespace + +int main(int argc, char *argv[]) +{ + std::string example_type; + if (argc > 1) + { + options.endpoint = argv[1]; + if (argc > 2) + { + example_type = argv[2]; + if (argc > 3) + { + options.use_ssl_credentials = true; + options.ssl_credentials_cacert_path = argv[3]; + } + } + } + // Removing this line will leave the default noop MetricProvider in place. + initMetrics(); + std::string name{"otlp_grpc_metric_example"}; + + if (example_type == "counter") + { + foo_library::counter_example(name); + } + else if (example_type == "observable_counter") + { + foo_library::observable_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 observable_counter_example{&foo_library::observable_counter_example, name}; + std::thread histogram_example{&foo_library::histogram_example, name}; + + counter_example.join(); + observable_counter_example.join(); + histogram_example.join(); + } +} +#endif diff --git a/examples/otlp/opentelemetry-collector-config/config.dev.yaml b/examples/otlp/opentelemetry-collector-config/config.dev.yaml index f10252b953..895d70ece1 100644 --- a/examples/otlp/opentelemetry-collector-config/config.dev.yaml +++ b/examples/otlp/opentelemetry-collector-config/config.dev.yaml @@ -8,8 +8,6 @@ receivers: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 - cors_allowed_origins: - - '*' service: pipelines: traces: @@ -22,3 +20,8 @@ service: - otlp exporters: - logging + metrics: + receivers: + - otlp + exporters: + - logging