Skip to content

Commit

Permalink
ostream metrics example (open-telemetry#1312)
Browse files Browse the repository at this point in the history
  • Loading branch information
esigo committed Apr 12, 2022
1 parent e200c1f commit 755f109
Show file tree
Hide file tree
Showing 11 changed files with 382 additions and 187 deletions.
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"

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

0 comments on commit 755f109

Please sign in to comment.