diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/jaegertracing/opentelemetry-cpp/examples/metrics_simple | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/examples/metrics_simple')
5 files changed, 364 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD new file mode 100644 index 000000000..95d6490ba --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD @@ -0,0 +1,28 @@ +cc_binary( + name = "metrics_simple_example", + srcs = [ + "main.cc", + ], + linkopts = ["-pthread"], + tags = ["ostream"], + deps = [ + "//api", + "//exporters/ostream:ostream_metrics_exporter_deprecated", + "//sdk/src/_metrics:metrics_deprecated", + ], +) + +cc_binary( + name = "metrics_ostream_example", + srcs = [ + "metrics_ostream.cc", + ], + linkopts = ["-pthread"], + tags = ["ostream"], + deps = [ + "//api", + "//examples/common/metrics_foo_library:common_metrics_foo_library", + "//exporters/ostream:ostream_metric_exporter", + "//sdk/src/metrics", + ], +) diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt new file mode 100644 index 000000000..a2088fd51 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include) +if(WITH_METRICS_PREVIEW) + add_executable(simple_metrics main.cc) + target_link_libraries( + simple_metrics ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics_deprecated + opentelemetry_exporter_ostream_metrics_deprecated) +else() + add_executable(metrics_ostream_example metrics_ostream.cc) + target_link_libraries( + metrics_ostream_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics + opentelemetry_exporter_ostream_metrics opentelemetry_resources + common_metrics_foo_library) +endif() diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md new file mode 100644 index 000000000..b2c5dc0a7 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md @@ -0,0 +1,86 @@ +# Simple Metrics Example + +This example initializes the metrics pipeline with 2 different instrument types. +Here are more detailed explanations of each part. + +1: Initialize an exporter and a reader. In this case, we initialize an OStream +Exporter which will print to stdout by default. +The reader periodically collects metrics from the collector and exports them. + +```cpp +std::unique_ptr<metric_sdk::MetricExporter> exporter{new exportermetrics::OStreamMetricExporter}; +std::unique_ptr<metric_sdk::MetricReader> reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; +``` + +2: Initialize a MeterProvider and add the reader. +We will use this to obtain Meter objects in the future. + +```cpp +auto provider = std::shared_ptr<metrics_api::MeterProvider>(new opentelemetry::metrics::MeterProvider()); +auto p = std::static_pointer_cast<metric_sdk::MeterProvider>(provider); +p->AddMetricReader(std::move(reader)); +``` + +3: Create and add a view to the provider. + +```cpp +std::unique_ptr<metric_sdk::InstrumentSelector> instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, "name_counter")}; +std::unique_ptr<metric_sdk::MeterSelector> meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; +std::unique_ptr<metric_sdk::View> sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; +p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); +``` + +4: Then create a +[Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter) +instrument from it. Every Meter pointer returned by the +MeterProvider points to the same Meter. This means that the Meter will be able +to combine metrics captured from different functions without having to +constantly pass the Meter around the library. + +```cpp +nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter(name, "1.2.0"); +auto double_counter = meter->CreateDoubleCounter(counter_name); +// Create a label set which annotates metric values +std::map<std::string, std::string> labels = {{"key", "value"}}; +auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels}; +double_counter->Add(val, labelkv); +``` + +5: To use histogram instrument, a view with proper `InstrumentType` and `AggregationType` +has to be added to the provider. + +```cpp +std::unique_ptr<metric_sdk::InstrumentSelector> histogram_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, "histogram_name")}; +std::unique_ptr<metric_sdk::MeterSelector> histogram_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; +std::unique_ptr<metric_sdk::View> histogram_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}}; +p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); + +auto histogram_counter = meter->CreateDoubleHistogram("histogram_name"); +auto context = opentelemetry::context::Context{}; +histogram_counter->Record(val, labelkv, context); +``` + +See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and +running the example. + +## Additional Documentation + +[API +Design](https://github.com/open-o11y/docs/blob/master/cpp-metrics/api-design.md) + +[SDK +Design](https://github.com/open-o11y/docs/blob/master/cpp-metrics/sdk-design.md) + +[OStreamExporters +Design](https://github.com/open-o11y/docs/blob/master/cpp-ostream/ostream-exporter-design.md) + +[OpenTelemetry C++ Metrics +Overview](https://github.com/open-o11y/docs/blob/master/cpp-metrics/README.md) diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc new file mode 100644 index 000000000..3a18a52f3 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc @@ -0,0 +1,118 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifdef ENABLE_METRICS_PREVIEW +# include "opentelemetry/_metrics/provider.h" +# include "opentelemetry/exporters/ostream/metrics_exporter.h" +# include "opentelemetry/sdk/_metrics/controller.h" +# include "opentelemetry/sdk/_metrics/meter.h" +# include "opentelemetry/sdk/_metrics/meter_provider.h" +# include "opentelemetry/sdk/_metrics/ungrouped_processor.h" + +namespace metric_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace exportermetrics = opentelemetry::exporter::metrics; +namespace metrics_api = opentelemetry::metrics; + +int main() +{ + // Initialize and set the global MeterProvider + auto provider = nostd::shared_ptr<metrics_api::MeterProvider>(new metric_sdk::MeterProvider); + metrics_api::Provider::SetMeterProvider(provider); + + // Get the Meter from the MeterProvider + nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter("Test", "0.1.0"); + + // Create the controller with Stateless Metrics Processor + metric_sdk::PushController ControllerStateless( + meter, + std::unique_ptr<metric_sdk::MetricsExporter>(new exportermetrics::OStreamMetricsExporter), + std::shared_ptr<metric_sdk::MetricsProcessor>( + new metric_sdk::UngroupedMetricsProcessor(false)), + .05); + + // Create and instrument + auto intupdowncounter = meter->NewIntUpDownCounter("UpDownCounter", "None", "none", true); + auto intcounter = meter->NewIntCounter("Counter", "none", "none", true); + + // Create a labelset + std::map<std::string, std::string> labels = {{"key", "value"}}; + auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels}; + + // Create arrays of instrument and values to add to them + metrics_api::SynchronousInstrument<int> *iinstr_arr[] = {intupdowncounter.get(), + intcounter.get()}; + int ivalues_arr[] = {10, 5}; + + // Change the arrays to be nostd::spans + nostd::span<metrics_api::SynchronousInstrument<int> *> instrument_span{iinstr_arr}; + nostd::span<const int, 2> instrument_values{ivalues_arr}; + + /** + * First way of updating an instrument, RecordBatch. We can update multiple instruments at once by + * using a span of instruments and a span of values. This RecordBatch will update the ith + * instrument with the ith value. + **/ + std::cout << "Example 1" << std::endl; + ControllerStateless.start(); + + // Updating multiple instruments with the same labelset + meter->RecordIntBatch(labelkv, instrument_span, instrument_values); + + ControllerStateless.stop(); + /** + * Second way of updating an instrument, bind then add. In this method the user binds an + *instrument to a labelset Then add to the bounded instrument, then unbind. + **/ + std::cout << "Example 2" << std::endl; + ControllerStateless.start(); + + auto boundintupdowncounter = intupdowncounter->bindUpDownCounter(labelkv); + boundintupdowncounter->add(50); + boundintupdowncounter->unbind(); + + ControllerStateless.stop(); + /** + * The Third and final way is to add a value with a labelset at the same time. This also shows + * The difference between using a Stateless and Stateful Processor + */ + + // Start exporting from the Controller with Stateless Processor + std::cout << "-----" + << " Stateless Processor " + << "-----" << std::endl; + ControllerStateless.start(); + for (int i = 0; i < 20; i++) + { + intupdowncounter->add(i, labelkv); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + ControllerStateless.stop(); + + // Do the same thing for stateful to see the difference + metric_sdk::PushController ControllerStateful( + meter, + std::unique_ptr<metric_sdk::MetricsExporter>(new exportermetrics::OStreamMetricsExporter), + std::shared_ptr<metric_sdk::MetricsProcessor>( + new metric_sdk::UngroupedMetricsProcessor(true)), + .05); + + // Start exporting from the Controller with Stateful Processor + std::cout << "-----" + << " Stateful Processor " + << "-----" << std::endl; + ControllerStateful.start(); + for (int i = 0; i < 20; i++) + { + intupdowncounter->add(i, labelkv); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + ControllerStateful.stop(); +} +#else +int main() +{ + // empty +} +#endif diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc new file mode 100644 index 000000000..585856f91 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc @@ -0,0 +1,119 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include <memory> +# include <thread> +# include "opentelemetry/exporters/ostream/metric_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 metric_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace exportermetrics = opentelemetry::exporter::metrics; +namespace metrics_api = opentelemetry::metrics; + +namespace +{ + +void initMetrics(const std::string &name) +{ + std::unique_ptr<metric_sdk::MetricExporter> exporter{new exportermetrics::OStreamMetricExporter}; + + 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<metric_sdk::MetricReader> reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + auto provider = std::shared_ptr<metrics_api::MeterProvider>(new metric_sdk::MeterProvider()); + auto p = std::static_pointer_cast<metric_sdk::MeterProvider>(provider); + p->AddMetricReader(std::move(reader)); + + // counter view + std::string counter_name = name + "_counter"; + std::unique_ptr<metric_sdk::InstrumentSelector> instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, counter_name)}; + std::unique_ptr<metric_sdk::MeterSelector> meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr<metric_sdk::View> sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + + // observable counter view + std::string observable_counter_name = name + "_observable_counter"; + std::unique_ptr<metric_sdk::InstrumentSelector> observable_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kObservableCounter, + observable_counter_name)}; + std::unique_ptr<metric_sdk::MeterSelector> observable_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr<metric_sdk::View> observable_sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + p->AddView(std::move(observable_instrument_selector), std::move(observable_meter_selector), + std::move(observable_sum_view)); + + // histogram view + std::string histogram_name = name + "_histogram"; + std::unique_ptr<metric_sdk::InstrumentSelector> histogram_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, histogram_name)}; + std::unique_ptr<metric_sdk::MeterSelector> histogram_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr<metric_sdk::View> histogram_view{ + new metric_sdk::View{name, "description", metric_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; + if (argc >= 2) + { + example_type = argv[1]; + } + + std::string name{"ostream_metric_example"}; + initMetrics(name); + + 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(); + } +} +#else +int main() {} +#endif |