Skip to content

Commit 71d0e50

Browse files
authored
[EXPORTER] Prometheus: Add unit to names, convert to word (#2213)
1 parent 9b89843 commit 71d0e50

File tree

3 files changed

+454
-75
lines changed

3 files changed

+454
-75
lines changed

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

+92-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <string>
88
#include <vector>
99
#include "opentelemetry/metrics/provider.h"
10+
#include "opentelemetry/nostd/string_view.h"
1011
#include "opentelemetry/sdk/metrics/meter.h"
1112
#include "opentelemetry/version.h"
1213

@@ -35,7 +36,17 @@ class PrometheusExporterUtils
3536

3637
private:
3738
/**
38-
* Append key-value pair to prometheus labels.
39+
* Sanitize the given metric name or label according to Prometheus rule.
40+
*
41+
* This function is needed because names in OpenTelemetry can contain
42+
* alphanumeric characters, '_', '.', and '-', whereas in Prometheus the
43+
* name should only contain alphanumeric characters and '_'.
44+
* @param name name
45+
*/
46+
static std::string SanitizeNames(std::string name);
47+
48+
/**
49+
* Sanitize the given metric name or label according to Prometheus rule.
3950
*
4051
* @param name label name
4152
* @param value label value
@@ -45,6 +56,79 @@ class PrometheusExporterUtils
4556
std::string value,
4657
std::vector<::prometheus::ClientMetric::Label> *labels);
4758

59+
static std::string MapToPrometheusName(const std::string &name,
60+
const std::string &unit,
61+
::prometheus::MetricType prometheus_type);
62+
63+
/**
64+
* A utility function that returns the equivalent Prometheus name for the provided OTLP metric
65+
* unit.
66+
*
67+
* @param raw_metric_unitName The raw metric unit for which Prometheus metric unit needs to be
68+
* computed.
69+
* @return the computed Prometheus metric unit equivalent of the OTLP metric unit
70+
*/
71+
static std::string GetEquivalentPrometheusUnit(const std::string &raw_metric_unitName);
72+
73+
/**
74+
* This method retrieves the expanded Prometheus unit name for known abbreviations. OTLP metrics
75+
* use the c/s notation as specified at <a href="https://ucum.org/ucum.html">UCUM</a>. The list of
76+
* mappings is adopted from <a
77+
* href="https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/9a9d4778bbbf242dba233db28e2fbcfda3416959/pkg/translator/prometheus/normalize_name.go#L30">OpenTelemetry
78+
* Collector Contrib</a>.
79+
*
80+
* @param unit_abbreviation The unit that name that needs to be expanded/converted to Prometheus
81+
* units.
82+
* @return The expanded/converted unit name if known, otherwise returns the input unit name as-is.
83+
*/
84+
static std::string GetPrometheusUnit(const std::string &unit_abbreviation);
85+
86+
/**
87+
* This method retrieves the expanded Prometheus unit name to be used with "per" units for known
88+
* units. For example: s => per second (singular)
89+
*
90+
* @param per_unit_abbreviation The unit abbreviation used in a 'per' unit.
91+
* @return The expanded unit equivalent to be used in 'per' unit if the input is a known unit,
92+
* otherwise returns the input as-is.
93+
*/
94+
static std::string GetPrometheusPerUnit(const std::string &per_unit_abbreviation);
95+
96+
/**
97+
* Replaces all characters that are not a letter or a digit with '_' to make the resulting string
98+
* Prometheus compliant. This method also removes leading and trailing underscores - this is done
99+
* to keep the resulting unit similar to what is produced from the collector's implementation.
100+
*
101+
* @param str The string input that needs to be made Prometheus compliant.
102+
* @return the cleaned-up Prometheus compliant string.
103+
*/
104+
static std::string CleanUpString(const std::string &str);
105+
106+
/**
107+
* This method is used to convert the units expressed as a rate via '/' symbol in their name to
108+
* their expanded text equivalent. For instance, km/h => km_per_hour. The method operates on the
109+
* input by splitting it in 2 parts - before and after '/' symbol and will attempt to expand any
110+
* known unit abbreviation in both parts. Unknown abbreviations & unsupported characters will
111+
* remain unchanged in the final output of this function.
112+
*
113+
* @param rate_expressed_unit The rate unit input that needs to be converted to its text
114+
* equivalent.
115+
* @return The text equivalent of unit expressed as rate. If the input does not contain '/', the
116+
* function returns it as-is.
117+
*/
118+
static std::string ConvertRateExpressedToPrometheusUnit(const std::string &rate_expressed_unit);
119+
120+
/**
121+
* This method drops all characters enclosed within '{}' (including the curly braces) by replacing
122+
* them with an empty string. Note that this method will not produce the intended effect if there
123+
* are nested curly braces within the outer enclosure of '{}'.
124+
*
125+
* <p>For instance, {packet{s}s} => s}.
126+
*
127+
* @param unit The input unit from which text within curly braces needs to be removed.
128+
* @return The resulting unit after removing the text within '{}'.
129+
*/
130+
static std::string RemoveUnitPortionInBraces(const std::string &unit);
131+
48132
static opentelemetry::sdk::metrics::AggregationType getAggregationType(
49133
const opentelemetry::sdk::metrics::PointType &point_type);
50134

@@ -58,6 +142,7 @@ class PrometheusExporterUtils
58142
* Add a target_info metric to collect resource attributes
59143
*/
60144
static void SetTarget(const sdk::metrics::ResourceMetrics &data,
145+
std::chrono::nanoseconds time,
61146
const opentelemetry::sdk::instrumentationscope::InstrumentationScope *scope,
62147
std::vector<::prometheus::MetricFamily> *output);
63148

@@ -70,6 +155,7 @@ class PrometheusExporterUtils
70155
const opentelemetry::sdk::metrics::PointAttributes &labels,
71156
const opentelemetry::sdk::instrumentationscope::InstrumentationScope *scope,
72157
::prometheus::MetricType type,
158+
std::chrono::nanoseconds time,
73159
::prometheus::MetricFamily *metric_family,
74160
const opentelemetry::sdk::resource::Resource *resource);
75161

@@ -83,6 +169,7 @@ class PrometheusExporterUtils
83169
const std::vector<uint64_t> &counts,
84170
const opentelemetry::sdk::metrics::PointAttributes &labels,
85171
const opentelemetry::sdk::instrumentationscope::InstrumentationScope *scope,
172+
std::chrono::nanoseconds time,
86173
::prometheus::MetricFamily *metric_family,
87174
const opentelemetry::sdk::resource::Resource *resource);
88175

@@ -92,6 +179,7 @@ class PrometheusExporterUtils
92179
static void SetMetricBasic(
93180
::prometheus::ClientMetric &metric,
94181
const opentelemetry::sdk::metrics::PointAttributes &labels,
182+
std::chrono::nanoseconds time,
95183
const opentelemetry::sdk::instrumentationscope::InstrumentationScope *scope,
96184
const opentelemetry::sdk::resource::Resource *resource);
97185

@@ -122,6 +210,9 @@ class PrometheusExporterUtils
122210
const std::vector<double> &boundaries,
123211
const std::vector<uint64_t> &counts,
124212
::prometheus::ClientMetric *metric);
213+
214+
// For testing
215+
friend class SanitizeNameTester;
125216
};
126217
} // namespace metrics
127218
} // namespace exporter

0 commit comments

Comments
 (0)