Skip to content
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

Merged
merged 12 commits into from
Apr 12, 2022
17 changes: 17 additions & 0 deletions examples/common/metrics_foo_library/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package(default_visibility = ["//visibility:public"])

cc_library(
name = "common_metrics_foo_library",
srcs = [
"foo_library.cc",
],
hdrs = [
"foo_library.h",
],
defines = ["BAZEL_BUILD"],
deps = [
"//api",
"//sdk:headers",
"//sdk/src/metrics",
],
)
25 changes: 25 additions & 0 deletions examples/common/metrics_foo_library/foo_library.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#ifndef ENABLE_METRICS_PREVIEW
# include <chrono>
# include <thread>
# include "opentelemetry/metrics/provider.h"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instrumentation library shouldn't include any sdk component. Can we remove these includes ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, removed.

namespace nostd = opentelemetry::nostd;
namespace metrics_api = opentelemetry::metrics;

void foo_library(const std::string &name)
{
// Get the Meter from the MeterProvider
auto provider = metrics_api::Provider::GetMeterProvider();
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));
}
#endif
9 changes: 9 additions & 0 deletions examples/common/metrics_foo_library/foo_library.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once
#ifndef ENABLE_METRICS_PREVIEW
# include <string>

void foo_library(const std::string &name);
#endif
15 changes: 15 additions & 0 deletions examples/metrics_simple/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,18 @@ cc_binary(
"//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",
],
)
65 changes: 65 additions & 0 deletions examples/metrics_simple/metrics_ostream.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#ifndef ENABLE_METRICS_PREVIEW
# include <memory>
# 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::vector<std::unique_ptr<metric_sdk::MetricExporter>> exporters;

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(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);
}
} // namespace
int main()
{
std::string name{"ostream_metric_example"};
initMetrics(name);
foo_library(name);
}
#else
int main() {}
#endif
59 changes: 29 additions & 30 deletions exporters/ostream/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -43,37 +43,36 @@ cc_library(
],
)

# TODO - Uncomment once MetricData interface is finalised
#cc_library(
# name = "ostream_metric_exporter",
# srcs = [
# "src/metric_exporter.cc",
# ],
# hdrs = [
# "include/opentelemetry/exporters/ostream/metric_exporter.h",
# ],
# strip_include_prefix = "include",
# tags = [
# "metrics",
# "ostream",
# ],
# deps = [
# "//sdk/src/metrics",
# ],
#)
cc_library(
name = "ostream_metric_exporter",
srcs = [
"src/metric_exporter.cc",
],
hdrs = [
"include/opentelemetry/exporters/ostream/metric_exporter.h",
],
strip_include_prefix = "include",
tags = [
"metrics",
"ostream",
],
deps = [
"//sdk/src/metrics",
],
)

#cc_test(
# name = "ostream_metric_test",
# srcs = ["test/ostream_metric_test.cc"],
# tags = [
# "ostream",
# "test",
# ],
# deps = [
# ":ostream_metric_exporter",
# "@com_google_googletest//:gtest_main",
# ],
#)
cc_test(
name = "ostream_metric_test",
srcs = ["test/ostream_metric_test.cc"],
tags = [
"ostream",
"test",
],
deps = [
":ostream_metric_exporter",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "ostream_metrics_test_deprecated",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricEx

/**
* Export
* @param records a span of unique pointers to metrics data
* @param data metrics data
*/
sdk::common::ExportResult Export(
const nostd::span<std::unique_ptr<opentelemetry::sdk::metrics::MetricData>> &records) noexcept
override;
sdk::common::ExportResult Export(const sdk::metrics::ResourceMetrics &data) noexcept override;

/**
* Force flush the exporter.
Expand All @@ -60,7 +58,9 @@ class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricEx
bool is_shutdown_ = false;
mutable opentelemetry::common::SpinLockMutex lock_;
bool isShutdown() const noexcept;
void printPointData(opentelemetry::sdk::metrics::PointType &point_data);
void printInstrumentationInfoMetricData(
const sdk::metrics::InstrumentationInfoMetrics &info_metrics);
void printPointData(const opentelemetry::sdk::metrics::PointType &point_data);
};
} // namespace metrics
} // namespace exporter
Expand Down
88 changes: 54 additions & 34 deletions exporters/ostream/src/metric_exporter.cc
Original file line number Diff line number Diff line change
@@ -1,68 +1,90 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <chrono>
#ifndef ENABLE_METRICS_PREVIEW
# include "opentelemetry/exporters/ostream/metric_exporter.h"
# include <algorithm>
# include "opentelemetry/exporters/ostream/metric_exporter.h"
# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h"
# include "opentelemetry/sdk_config.h"

namespace
{
std::string timeToString(opentelemetry::common::SystemTimestamp time_stamp)
{
std::time_t epoch_time = std::chrono::system_clock::to_time_t(time_stamp);
return std::ctime(&epoch_time);
}
} // namespace

OPENTELEMETRY_BEGIN_NAMESPACE
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::ResourceMetrics &data) noexcept
{
if (isShutdown())
{
OTEL_INTERNAL_LOG_ERROR("[OStream Metric] Exporting "
<< records.size() << " records(s) failed, exporter is shutdown");
<< data.instrumentation_info_metric_data_.size()
<< " records(s) failed, exporter is shutdown");
return sdk::common::ExportResult::kFailure;
}

for (auto &record : records)
for (auto &record : data.instrumentation_info_metric_data_)
{
sout_ << "{"
<< "\n name : " << record->instrumentation_library_->GetName()
<< "\n version : " << record->instrumentation_library_->GetVersion();
printPointData(record->point_data_);
sout_ << "\n}\n";
printInstrumentationInfoMetricData(record);
}
return sdk::common::ExportResult::kSuccess;
}

template <typename T>
inline void printVec(std::ostream &os, std::vector<T> &vec)
void OStreamMetricExporter::printInstrumentationInfoMetricData(
const sdk::metrics::InstrumentationInfoMetrics &info_metric)
{
os << '[';
if (vec.size() > 1)
{
std::copy(vec.begin(), vec.end() - 1, std::ostream_iterator<T>(os, ", "));
}
if (!vec.empty())
sout_ << "{";
sout_ << "\n name\t\t: " << info_metric.instrumentation_library_->GetName()
<< "\n schema url\t: " << info_metric.instrumentation_library_->GetSchemaURL()
<< "\n version\t: " << info_metric.instrumentation_library_->GetVersion();
for (const auto &record : info_metric.metric_data_)
{
os << vec.back();
sout_ << "\n start time\t: " << timeToString(record.start_ts)
<< " end time\t: " << timeToString(record.end_ts)
<< " description\t: " << record.instrument_descriptor.description_
<< "\n unit\t\t: " << record.instrument_descriptor.unit_;

for (const auto &pd : record.point_data_attr_)
{
printPointData(pd.point_data);
}
}
os << ']';
sout_ << "\n}\n";
}

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 : ";
sout_ << "\n type\t\t: SumPointData";
sout_ << "\n value\t\t: ";
if (nostd::holds_alternative<double>(sum_point_data.value_))
{
sout_ << nostd::get<double>(sum_point_data.value_);
Expand All @@ -76,8 +98,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_))
Expand All @@ -90,14 +110,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);
}

Expand All @@ -109,8 +129,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_))
{
Expand Down
Loading