From 3fd5ca38a0371b0ce64a6b90f54a6af00cc0d96b Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 16 May 2022 16:53:40 +0200 Subject: [PATCH] Getting started document using ostream exporter (#1394) Co-authored-by: Reiley Yang --- examples/metrics_simple/README.md | 111 ++++++++---------- exporters/ostream/src/metric_exporter.cc | 1 + exporters/ostream/test/ostream_metric_test.cc | 4 + 3 files changed, 55 insertions(+), 61 deletions(-) diff --git a/examples/metrics_simple/README.md b/examples/metrics_simple/README.md index 41d683c782..b2c5dc0a74 100644 --- a/examples/metrics_simple/README.md +++ b/examples/metrics_simple/README.md @@ -1,83 +1,72 @@ # Simple Metrics Example -In this example, the application in `main.cc` initializes the metrics pipeline -and shows 3 different ways of updating instrument values. Here are more detailed -explanations of each part. +This example initializes the metrics pipeline with 2 different instrument types. +Here are more detailed explanations of each part. -1: Initialize a MeterProvider. We will use this to obtain Meter objects in the -future. - -`auto provider = shared_ptr(new MeterProvider);` - -2: Set the MeterProvider as the default instance for the library. This ensures -that we will have access to the same MeterProvider across our application. - -`Provider::SetMeterProvider(provider);` - -3: Obtain a meter from this meter provider. 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. - -`shared_ptr meter = provider→GetMeter("Test");` - -4: Initialize an exporter and processor. In this case, we initialize an OStream -Exporter which will print to stdout by default. The Processor is an -UngroupedProcessor which doesn’t filter or group captured metrics in any way. -The false parameter indicates that this processor will send metric deltas rather -than metric cumulatives. +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 -unique_ptr exporter = unique_ptr(new OStreamMetricsExporter); -shared_ptr processor = shared_ptr(new UngroupedMetricsProcessor(false)); +std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; +std::unique_ptr reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; ``` -5: Pass the meter, exporter, and processor into the controller. Since this is a -push controller, a collection interval parameter (in seconds) is also taken. At -each collection interval, the controller will request data from all of the -instruments in the code and export them. Start the controller to begin the -metrics pipeline. +2: Initialize a MeterProvider and add the reader. +We will use this to obtain Meter objects in the future. -`metrics_sdk::PushController controller(meter, std::move(exporter), processor, -5);` `controller.start();` +```cpp +auto provider = std::shared_ptr(new opentelemetry::metrics::MeterProvider()); +auto p = std::static_pointer_cast(provider); +p->AddMetricReader(std::move(reader)); +``` -6: Instrument code with synchronous and asynchronous instrument. These -instruments can be placed in areas of interest to collect metrics and are -created by the meter. Synchronous instruments are updated whenever the user -desires with a value and label set. Calling add on a counter instrument for -example will increase its value. Asynchronous instruments can be updated the -same way, but are intended to receive updates from a callback function. The -callback below observes a value of 1. The user never has to call this function -as it is automatically called by the controller. +3: Create and add a view to the provider. ```cpp -// Observer callback function -void SumObserverCallback(metrics_api::ObserverResult result){ - std::map labels = {{"key", "value"}}; - auto labelkv = common::KeyValueIterableView{labels}; - result.observe(1,labelkv); -} +std::unique_ptr instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, "name_counter")}; +std::unique_ptr meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; +std::unique_ptr 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)); +``` -// Create new instruments -auto ctr= meter->NewIntCounter("Counter","none", "none", true); -auto obs= meter->NewIntSumObserver("Counter","none", "none", true, &SumObserverCallback); +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 meter = provider->GetMeter(name, "1.2.0"); +auto double_counter = meter->CreateDoubleCounter(counter_name); // Create a label set which annotates metric values std::map labels = {{"key", "value"}}; auto labelkv = common::KeyValueIterableView{labels}; - -// Capture data from instruments. Note that the asynchronous instrument is updates -// automatically though its callback at the collection interval. Additional measurments -// can be made through calls to its observe function. -ctr->add(5, labelkv); - +double_counter->Add(val, labelkv); ``` -7: Stop the controller once the program finished. This ensures that any metrics -inside the pipeline are properly exported. Otherwise, some metrics may be -destroyed in cleanup. +5: To use histogram instrument, a view with proper `InstrumentType` and `AggregationType` +has to be added to the provider. -`controller.stop();` +```cpp +std::unique_ptr histogram_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, "histogram_name")}; +std::unique_ptr histogram_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; +std::unique_ptr 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. diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index bf97db04c2..18e73a310c 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -96,6 +96,7 @@ void OStreamMetricExporter::printInstrumentationInfoMetricData( { sout_ << "\n start time\t: " << timeToString(record.start_ts) << "\n end time\t: " << timeToString(record.end_ts) + << "\n name\t\t: " << record.instrument_descriptor.name_ << "\n description\t: " << record.instrument_descriptor.description_ << "\n unit\t\t: " << record.instrument_descriptor.unit_; diff --git a/exporters/ostream/test/ostream_metric_test.cc b/exporters/ostream/test/ostream_metric_test.cc index 3618d93e7a..82c1be2bc7 100644 --- a/exporters/ostream/test/ostream_metric_test.cc +++ b/exporters/ostream/test/ostream_metric_test.cc @@ -70,6 +70,7 @@ TEST(OStreamMetricsExporter, ExportSumPointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n type\t\t: SumPointData" @@ -128,6 +129,7 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n type : HistogramPointData" @@ -190,6 +192,7 @@ TEST(OStreamMetricsExporter, ExportLastValuePointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n type : LastValuePointData" @@ -244,6 +247,7 @@ TEST(OStreamMetricsExporter, ExportDropPointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n}\n";