-
Notifications
You must be signed in to change notification settings - Fork 411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ostream metrics example #1312
ostream metrics example #1312
Changes from 1 commit
8d1bf2c
8c6ea1d
04afa7f
dcb1c5d
e51b14b
55aa2d9
7aa6a14
7b89ff9
f9e42c6
35cb208
34e8b8e
454a2c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <memory> | ||
#ifndef ENABLE_METRICS_PREVIEW | ||
# include <chrono> | ||
# 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" | ||
|
||
# include <iostream> | ||
|
||
namespace metric_sdk = opentelemetry::sdk::metrics; | ||
namespace nostd = opentelemetry::nostd; | ||
namespace common = opentelemetry::common; | ||
namespace exportermetrics = opentelemetry::exporter::metrics; | ||
namespace metrics_api = opentelemetry::metrics; | ||
|
||
void sync_sum() | ||
{ | ||
std::unique_ptr<metric_sdk::MetricExporter> exporter{new exportermetrics::OStreamMetricExporter}; | ||
std::vector<std::unique_ptr<metric_sdk::MetricExporter>> exporters; | ||
|
||
std::string name{"ostream_metric_example"}; | ||
std::string version{"1.2.0"}; | ||
std::string schema{"ostream_metric_example"}; | ||
|
||
// 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(std::move(exporters))); | ||
auto p = std::static_pointer_cast<metric_sdk::MeterProvider>(provider); | ||
p->AddMetricReader(std::move(reader)); | ||
std::unique_ptr<metric_sdk::InstrumentSelector> instrument_selector{ | ||
new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, name)}; | ||
std::unique_ptr<metric_sdk::MeterSelector> meter_selector{ | ||
new metric_sdk::MeterSelector(name, version, schema)}; | ||
std::unique_ptr<metric_sdk::View> view{ | ||
new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; | ||
p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); | ||
metrics_api::Provider::SetMeterProvider(provider); | ||
|
||
// Get the Meter from the MeterProvider | ||
nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter(name, "1.2.0"); | ||
auto double_counter = meter->CreateDoubleCounter(name); | ||
double_counter->Add(28.5); | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
double_counter->Add(3.14); | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
double_counter->Add(23.5); | ||
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); | ||
p->ForceFlush(); | ||
} | ||
|
||
int main() | ||
{ | ||
sync_sum(); | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,54 +14,46 @@ namespace exporter | |
namespace metrics | ||
{ | ||
|
||
template <typename Container> | ||
inline void printVec(std::ostream &os, Container &vec) | ||
{ | ||
using T = typename std::decay<decltype(*vec.begin())>::type; | ||
os << '['; | ||
if (vec.size() > 1) | ||
{ | ||
std::copy(vec.begin(), vec.end(), std::ostream_iterator<T>(os, ", ")); | ||
} | ||
os << ']'; | ||
} | ||
|
||
OStreamMetricExporter::OStreamMetricExporter(std::ostream &sout) noexcept : sout_(sout) {} | ||
|
||
sdk::common::ExportResult OStreamMetricExporter::Export( | ||
const nostd::span<std::unique_ptr<opentelemetry::sdk::metrics::MetricData>> &records) noexcept | ||
const sdk::metrics::MetricData &data) noexcept | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may need further changes, based on the review for #1299, as it adds Resources and Instrumentation Info to Metric Data to be exported. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #1299 is merged. you can modify the PR to use ResourceMetrics instead of MetricData. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @esigo - Just want to check if you want this to be reviewed now, as I was thinking to review it once it incorporates changes for ResourceMetrics as mentioned above :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @lalitb, I'm rewriting the unit tests, should be done by tomorrow. I'll ping you when I'm done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, @esigo. Just wanted to ensure that I am not delaying the review comments in case you are expecting it to be reviewed :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lalitb this should be ready for review, thanks :) |
||
{ | ||
if (isShutdown()) | ||
{ | ||
OTEL_INTERNAL_LOG_ERROR("[OStream Metric] Exporting " | ||
<< records.size() << " records(s) failed, exporter is shutdown"); | ||
<< data.point_data_attr_.size() | ||
<< " records(s) failed, exporter is shutdown"); | ||
return sdk::common::ExportResult::kFailure; | ||
} | ||
|
||
for (auto &record : records) | ||
for (auto &record : data.point_data_attr_) | ||
{ | ||
sout_ << "{" | ||
<< "\n name : " << record->instrumentation_library_->GetName() | ||
<< "\n version : " << record->instrumentation_library_->GetVersion(); | ||
printPointData(record->point_data_); | ||
sout_ << "{"; | ||
printPointData(record.point_data); | ||
sout_ << "\n}\n"; | ||
} | ||
return sdk::common::ExportResult::kSuccess; | ||
} | ||
|
||
template <typename T> | ||
inline void printVec(std::ostream &os, std::vector<T> &vec) | ||
{ | ||
os << '['; | ||
if (vec.size() > 1) | ||
{ | ||
std::copy(vec.begin(), vec.end() - 1, std::ostream_iterator<T>(os, ", ")); | ||
} | ||
if (!vec.empty()) | ||
{ | ||
os << vec.back(); | ||
} | ||
os << ']'; | ||
} | ||
|
||
void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointType &point_data) | ||
void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::PointType &point_data) | ||
{ | ||
if (nostd::holds_alternative<sdk::metrics::SumPointData>(point_data)) | ||
{ | ||
auto sum_point_data = nostd::get<sdk::metrics::SumPointData>(point_data); | ||
sout_ << "\n type : SumPointData"; | ||
sout_ << "\n start timestamp : " | ||
<< std::to_string(sum_point_data.start_epoch_nanos_.time_since_epoch().count()); | ||
sout_ << "\n end timestamp : " | ||
<< std::to_string(sum_point_data.end_epoch_nanos_.time_since_epoch().count()); | ||
sout_ << "\n value : "; | ||
if (nostd::holds_alternative<double>(sum_point_data.value_)) | ||
{ | ||
|
@@ -76,8 +68,6 @@ void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointTyp | |
{ | ||
auto histogram_point_data = nostd::get<sdk::metrics::HistogramPointData>(point_data); | ||
sout_ << "\n type : HistogramPointData"; | ||
sout_ << "\n timestamp : " | ||
<< std::to_string(histogram_point_data.epoch_nanos_.time_since_epoch().count()); | ||
sout_ << "\n count : " << histogram_point_data.count_; | ||
sout_ << "\n sum : "; | ||
if (nostd::holds_alternative<double>(histogram_point_data.sum_)) | ||
|
@@ -90,14 +80,14 @@ void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointTyp | |
} | ||
|
||
sout_ << "\n buckets : "; | ||
if (nostd::holds_alternative<std::vector<double>>(histogram_point_data.boundaries_)) | ||
if (nostd::holds_alternative<std::list<double>>(histogram_point_data.boundaries_)) | ||
{ | ||
auto &double_boundaries = nostd::get<std::vector<double>>(histogram_point_data.boundaries_); | ||
auto &double_boundaries = nostd::get<std::list<double>>(histogram_point_data.boundaries_); | ||
printVec(sout_, double_boundaries); | ||
} | ||
else if (nostd::holds_alternative<std::vector<long>>(histogram_point_data.boundaries_)) | ||
else if (nostd::holds_alternative<std::list<long>>(histogram_point_data.boundaries_)) | ||
{ | ||
auto &long_boundaries = nostd::get<std::vector<long>>(histogram_point_data.boundaries_); | ||
auto &long_boundaries = nostd::get<std::list<long>>(histogram_point_data.boundaries_); | ||
printVec(sout_, long_boundaries); | ||
} | ||
|
||
|
@@ -109,8 +99,8 @@ void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointTyp | |
auto last_point_data = nostd::get<sdk::metrics::LastValuePointData>(point_data); | ||
sout_ << "\n type : LastValuePointData"; | ||
sout_ << "\n timestamp : " | ||
<< std::to_string(last_point_data.epoch_nanos_.time_since_epoch().count()) | ||
<< std::boolalpha << "\n valid : " << last_point_data.is_lastvalue_valid_; | ||
<< std::to_string(last_point_data.sample_ts_.time_since_epoch().count()) << std::boolalpha | ||
<< "\n valid : " << last_point_data.is_lastvalue_valid_; | ||
sout_ << "\n value : "; | ||
if (nostd::holds_alternative<double>(last_point_data.value_)) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit - should we add small metrics instrumentation under (example/common) similar to how we do for traces and logs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, added.