Skip to content

Commit edc8d26

Browse files
committed
Allow omission of prometheus type & unit from name
1 parent 63683c1 commit edc8d26

File tree

5 files changed

+62
-11
lines changed

5 files changed

+62
-11
lines changed

exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_options.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ struct PrometheusExporterOptions
2828

2929
// Populating otel_scope_name/otel_scope_labels attributes
3030
bool without_otel_scope = false;
31+
32+
// Option to export metrics without the unit suffix
33+
bool without_units = false;
34+
35+
// Option to export metrics without the type suffix
36+
bool without_type_suffix = false;
3137
};
3238

3339
} // namespace metrics

exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ class PrometheusExporterUtils
3030
* @param populate_target_info whether to populate target_info
3131
* @param without_otel_scope whether to populate otel_scope_name and otel_scope_version
3232
* attributes
33+
* @param without_units exporter configuration controlling whether to append unit suffix in
34+
* the exported metrics.
35+
* @param without_type_suffix exporter configuration controlling whether to append type suffix in
36+
* the exported metrics.
3337
* @return a collection of translated metrics that is acceptable by Prometheus
3438
*/
3539
static std::vector<::prometheus::MetricFamily> TranslateToPrometheus(
3640
const sdk::metrics::ResourceMetrics &data,
3741
bool populate_target_info = true,
38-
bool without_otel_scope = false);
42+
bool without_otel_scope = false,
43+
bool without_units = false,
44+
bool without_type_suffix = false);
3945

4046
private:
4147
/**
@@ -61,7 +67,9 @@ class PrometheusExporterUtils
6167

6268
static std::string MapToPrometheusName(const std::string &name,
6369
const std::string &unit,
64-
::prometheus::MetricType prometheus_type);
70+
::prometheus::MetricType prometheus_type,
71+
bool without_units,
72+
bool without_type_suffix);
6573

6674
/**
6775
* A utility function that returns the equivalent Prometheus name for the provided OTLP metric

exporters/prometheus/src/exporter_options.cc

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,34 @@ inline bool GetPrometheusPopulateTargetInfo()
4848
return exists ? setting : true;
4949
}
5050

51+
inline bool GetPrometheusWithoutUnits()
52+
{
53+
constexpr char kPrometheusWithoutUnits[] =
54+
"OTEL_CPP_PROMETHEUS_EXPORTER_WITHOUT_UNITS";
55+
bool setting;
56+
const auto exists =
57+
opentelemetry::sdk::common::GetBoolEnvironmentVariable(kPrometheusWithoutUnits, setting);
58+
59+
return exists ? setting : false;
60+
}
61+
62+
inline bool GetPrometheusWithoutTypeSuffix()
63+
{
64+
constexpr char kPrometheusWithoutTypeSuffix[] =
65+
"OTEL_CPP_PROMETHEUS_EXPORTER_WITHOUT_TYPE_SUFFIX";
66+
bool setting;
67+
const auto exists =
68+
opentelemetry::sdk::common::GetBoolEnvironmentVariable(kPrometheusWithoutTypeSuffix, setting);
69+
70+
return exists ? setting : false;
71+
}
72+
5173
PrometheusExporterOptions::PrometheusExporterOptions()
5274
: url(GetPrometheusDefaultHttpEndpoint()),
5375
populate_target_info(GetPrometheusPopulateTargetInfo()),
54-
without_otel_scope(GetPrometheusWithoutOtelScope())
76+
without_otel_scope(GetPrometheusWithoutOtelScope()),
77+
without_units(GetPrometheusWithoutUnits()),
78+
without_type_suffix(GetPrometheusWithoutTypeSuffix())
5579
{}
5680

5781
} // namespace metrics

exporters/prometheus/src/exporter_utils.cc

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@ std::string SanitizeLabel(std::string label_key)
102102
* Helper function to convert OpenTelemetry metrics data collection
103103
* to Prometheus metrics data collection
104104
*
105-
* @param records a collection of metrics in OpenTelemetry
105+
* @param data a collection of metrics in OpenTelemetry
106106
* @return a collection of translated metrics that is acceptable by Prometheus
107107
*/
108108
std::vector<prometheus_client::MetricFamily> PrometheusExporterUtils::TranslateToPrometheus(
109109
const sdk::metrics::ResourceMetrics &data,
110110
bool populate_target_info,
111-
bool without_otel_scope)
111+
bool without_otel_scope,
112+
bool without_units,
113+
bool without_type_suffix)
112114
{
113115

114116
// initialize output vector
@@ -150,7 +152,9 @@ std::vector<prometheus_client::MetricFamily> PrometheusExporterUtils::TranslateT
150152
}
151153
const prometheus_client::MetricType type = TranslateType(kind, is_monotonic);
152154
metric_family.name = MapToPrometheusName(metric_data.instrument_descriptor.name_,
153-
metric_data.instrument_descriptor.unit_, type);
155+
metric_data.instrument_descriptor.unit_, type,
156+
without_units, without_type_suffix);
157+
// TODO (psx95): Add tests to check compliance
154158
metric_family.type = type;
155159
const opentelemetry::sdk::instrumentationscope::InstrumentationScope *scope =
156160
without_otel_scope ? nullptr : instrumentation_info.scope_;
@@ -492,10 +496,19 @@ std::string PrometheusExporterUtils::CleanUpString(const std::string &str)
492496
std::string PrometheusExporterUtils::MapToPrometheusName(
493497
const std::string &name,
494498
const std::string &unit,
495-
prometheus_client::MetricType prometheus_type)
499+
prometheus_client::MetricType prometheus_type,
500+
bool without_units,
501+
bool without_type_suffix)
496502
{
497503
auto sanitized_name = SanitizeNames(name);
498-
std::string prometheus_equivalent_unit = GetEquivalentPrometheusUnit(unit);
504+
std::string prometheus_equivalent_unit;
505+
if (without_units)
506+
{
507+
prometheus_equivalent_unit = "";
508+
} else
509+
{
510+
prometheus_equivalent_unit = GetEquivalentPrometheusUnit(unit);
511+
}
499512

500513
// Append prometheus unit if not null or empty.
501514
if (!prometheus_equivalent_unit.empty() &&
@@ -505,7 +518,7 @@ std::string PrometheusExporterUtils::MapToPrometheusName(
505518
}
506519

507520
// Special case - counter
508-
if (prometheus_type == prometheus_client::MetricType::Counter)
521+
if (prometheus_type == prometheus_client::MetricType::Counter && !without_type_suffix)
509522
{
510523
auto t_pos = sanitized_name.rfind("_total");
511524
bool ends_with_total = t_pos == sanitized_name.size() - 6;
@@ -517,7 +530,7 @@ std::string PrometheusExporterUtils::MapToPrometheusName(
517530

518531
// Special case - gauge
519532
if (unit == "1" && prometheus_type == prometheus_client::MetricType::Gauge &&
520-
sanitized_name.find("ratio") == std::string::npos)
533+
sanitized_name.find("ratio") == std::string::npos && !without_type_suffix)
521534
{
522535
sanitized_name += "_ratio";
523536
}

exporters/prometheus/test/exporter_utils_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class SanitizeNameTester
5656
const std::string &unit,
5757
prometheus_client::MetricType prometheus_type)
5858
{
59-
return PrometheusExporterUtils::MapToPrometheusName(name, unit, prometheus_type);
59+
return PrometheusExporterUtils::MapToPrometheusName(name, unit, prometheus_type, false, false);
6060
}
6161
};
6262
} // namespace metrics

0 commit comments

Comments
 (0)