Skip to content

Commit

Permalink
Getting started document using ostream exporter (#1394)
Browse files Browse the repository at this point in the history
Co-authored-by: Reiley Yang <reyang@microsoft.com>
  • Loading branch information
esigo and reyang committed May 16, 2022
1 parent 4b69a10 commit 3fd5ca3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 61 deletions.
111 changes: 50 additions & 61 deletions examples/metrics_simple/README.md
Original file line number Diff line number Diff line change
@@ -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<MeterProvider>(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> 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<MetricsExporter> exporter = unique_ptr<MetricsExporter>(new OStreamMetricsExporter);
shared_ptr<MetricsProcessor> processor = shared_ptr<MetricsProcessor>(new UngroupedMetricsProcessor(false));
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)};
```
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<metrics_api::MeterProvider>(new opentelemetry::metrics::MeterProvider());
auto p = std::static_pointer_cast<metric_sdk::MeterProvider>(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<int> result){
std::map<std::string, std::string> labels = {{"key", "value"}};
auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
result.observe(1,labelkv);
}
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));
```
// 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<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};

// 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<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.
Expand Down
1 change: 1 addition & 0 deletions exporters/ostream/src/metric_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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_;

Expand Down
4 changes: 4 additions & 0 deletions exporters/ostream/test/ostream_metric_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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";
Expand Down

0 comments on commit 3fd5ca3

Please sign in to comment.