Skip to content

Commit

Permalink
add _total suffix to prometheus counters
Browse files Browse the repository at this point in the history
  • Loading branch information
dashpole committed Sep 1, 2023
1 parent f52ec6c commit ed46cdd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Increment the:

## [Unreleased]

* [EXPORTER] Add _total suffixes to Prometheus counters
[#2288](https://github.com/open-telemetry/opentelemetry-cpp/pull/2288)

## [1.11.0] 2023-08-21

* [BUILD] Fix more cases for symbol name for 32-bit win32 DLL build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class PrometheusExporterUtils
static opentelemetry::sdk::metrics::AggregationType getAggregationType(
const opentelemetry::sdk::metrics::PointType &point_type);

static inline bool endsWith(std::string const &value, std::string const &ending);

/**
* Translate the OTel metric type to Prometheus metric type
*/
Expand Down
44 changes: 32 additions & 12 deletions exporters/prometheus/src/exporter_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,37 @@ std::vector<prometheus_client::MetricFamily> PrometheusExporterUtils::TranslateT
{
for (const auto &metric_data : instrumentation_info.metric_data_)
{
auto origin_name = metric_data.instrument_descriptor.name_;
auto unit = metric_data.instrument_descriptor.unit_;
auto sanitized = SanitizeNames(origin_name);
if (metric_data.point_data_attr_.empty())
{
continue;
}
prometheus_client::MetricFamily metric_family;
auto front = metric_data.point_data_attr_.front();
auto kind = getAggregationType(front.point_data);
bool is_monotonic = true;
if (kind == sdk::metrics::AggregationType::kSum)
{
is_monotonic = nostd::get<sdk::metrics::SumPointData>(front.point_data).is_monotonic_;
}
auto type = TranslateType(kind, is_monotonic);
metric_family.type = type;
auto origin_name = metric_data.instrument_descriptor.name_;
auto unit = metric_data.instrument_descriptor.unit_;
auto sanitized = SanitizeNames(origin_name);
if (type == prometheus_client::MetricType::Counter && endsWith(sanitized, "_total"))
{
// trim _total from counters, since it will be appended after the unit.
sanitized = sanitized.substr(0, sanitized.length() - sizeof("_total"));
}
metric_family.name = sanitized + "_" + unit;
if (type == prometheus_client::MetricType::Counter)
{
metric_family.name += "_total";
}
metric_family.help = metric_data.instrument_descriptor.description_;
auto time = metric_data.end_ts.time_since_epoch();
for (const auto &point_data_attr : metric_data.point_data_attr_)
{
auto kind = getAggregationType(point_data_attr.point_data);
bool is_monotonic = true;
if (kind == sdk::metrics::AggregationType::kSum)
{
is_monotonic =
nostd::get<sdk::metrics::SumPointData>(point_data_attr.point_data).is_monotonic_;
}
const prometheus_client::MetricType type = TranslateType(kind, is_monotonic);
metric_family.type = type;
if (type == prometheus_client::MetricType::Histogram) // Histogram
{
auto histogram_point_data =
Expand Down Expand Up @@ -121,6 +134,13 @@ std::vector<prometheus_client::MetricFamily> PrometheusExporterUtils::TranslateT
return output;
}

inline bool PrometheusExporterUtils::endsWith(std::string const &value, std::string const &ending)
{
if (ending.size() > value.size())
return false;
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}

/**
* Sanitize the given metric name or label according to Prometheus rule.
*
Expand Down
16 changes: 8 additions & 8 deletions exporters/prometheus/test/exporter_utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ void assert_basic(prometheus_client::MetricFamily &metric,
int label_num,
std::vector<T> vals)
{
ASSERT_EQ(metric.name, sanitized_name + "_unit"); // name sanitized
ASSERT_EQ(metric.help, description); // description not changed
ASSERT_EQ(metric.type, type); // type translated
ASSERT_EQ(metric.name, sanitized_name); // name sanitized
ASSERT_EQ(metric.help, description); // description not changed
ASSERT_EQ(metric.type, type); // type translated

auto metric_data = metric.metric[0];
ASSERT_EQ(metric_data.label.size(), label_num);
Expand Down Expand Up @@ -114,8 +114,8 @@ TEST(PrometheusExporterUtils, TranslateToPrometheusIntegerCounter)

auto metric1 = translated[0];
std::vector<int> vals = {10};
assert_basic(metric1, "library_name", "description", prometheus_client::MetricType::Counter, 1,
vals);
assert_basic(metric1, "library_name_unit_total", "description",
prometheus_client::MetricType::Counter, 1, vals);
}

TEST(PrometheusExporterUtils, TranslateToPrometheusIntegerLastValue)
Expand All @@ -127,7 +127,7 @@ TEST(PrometheusExporterUtils, TranslateToPrometheusIntegerLastValue)

auto metric1 = translated[0];
std::vector<int> vals = {10};
assert_basic(metric1, "library_name", "description", prometheus_client::MetricType::Gauge, 1,
assert_basic(metric1, "library_name_unit", "description", prometheus_client::MetricType::Gauge, 1,
vals);
}

Expand All @@ -140,8 +140,8 @@ TEST(PrometheusExporterUtils, TranslateToPrometheusHistogramNormal)

auto metric = translated[0];
std::vector<double> vals = {3, 900.5, 4};
assert_basic(metric, "library_name", "description", prometheus_client::MetricType::Histogram, 1,
vals);
assert_basic(metric, "library_name_unit", "description", prometheus_client::MetricType::Histogram,
1, vals);
assert_histogram(metric, std::list<double>{10.1, 20.2, 30.2}, {200, 300, 400, 500});
}

Expand Down

0 comments on commit ed46cdd

Please sign in to comment.