From 908e3a6be14c415c25f23301fb7375ae1c6fbc4e Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Thu, 2 Oct 2025 11:25:30 -0400 Subject: [PATCH 1/4] feat(om1.1): Add UTF-8 metric names and labels Part of https://github.com/prometheus/prometheus/issues/16093 Signed-off-by: Owen Williams --- docs/specs/om/open_metrics_spec_1_1.md | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/docs/specs/om/open_metrics_spec_1_1.md b/docs/specs/om/open_metrics_spec_1_1.md index 0d9ed4026..332c0694a 100644 --- a/docs/specs/om/open_metrics_spec_1_1.md +++ b/docs/specs/om/open_metrics_spec_1_1.md @@ -23,6 +23,10 @@ author: name: Rob Skillington organization: Chronosphere email: rob.skillington@gmail.com +- ins: O. Williams + name: Owen Williams + organization: Grafana Labs + email: owen.williams@grafana.com --- - Version: 1.1 @@ -312,22 +316,24 @@ metricset = *metricfamily metricfamily = *metric-descriptor *metric -metric-descriptor = HASH SP type SP metricname SP metric-type LF -metric-descriptor =/ HASH SP help SP metricname SP escaped-string LF -metric-descriptor =/ HASH SP unit SP metricname SP *metricname-char LF +metric-descriptor = HASH SP type SP (metricname / metricname-utf8) SP metric-type LF +metric-descriptor =/ HASH SP help SP (metricname / metricname-utf8) SP escaped-string LF +metric-descriptor =/ HASH SP unit SP (metricname / metricname-utf8) SP *metricname-char LF metric = *sample metric-type = counter / gauge / histogram / gaugehistogram / stateset metric-type =/ info / summary / unknown -sample = metricname [labels] SP number [SP timestamp] [exemplar] LF +sample = metricname-and-labels SP number [SP timestamp] [exemplar] LF -exemplar = SP HASH SP labels SP number [SP timestamp] +metricname-and-labels = metricname [labels-in-braces] / name-in-braces +labels-in-braces = "{" [label *(COMMA label)] "}" +name-in-braces = "{" metricname-utf8 *(COMMA label) "}" -labels = "{" [label *(COMMA label)] "}" +label = label-key EQ DQUOTE escaped-string DQUOTE -label = label-name EQ DQUOTE escaped-string DQUOTE +exemplar = SP HASH SP labels-in-braces SP number [SP timestamp] number = realnumber ; Case insensitive @@ -366,16 +372,16 @@ HASH = "#" SIGN = "-" / "+" metricname = metricname-initial-char 0*metricname-char - metricname-char = metricname-initial-char / DIGIT metricname-initial-char = ALPHA / "_" / ":" +metricname-utf8 = DQUOTE escaped-string DQUOTE +label-key = label-name / DQUOTE escaped-string DQUOTE label-name = label-name-initial-char *label-name-char - label-name-char = label-name-initial-char / DIGIT label-name-initial-char = ALPHA / "_" -escaped-string = *escaped-char +escaped-string = 1*escaped-char escaped-char = normal-char escaped-char =/ BS ("n" / DQUOTE / BS) @@ -430,6 +436,8 @@ A double backslash SHOULD be used to represent a backslash character. A single backslash SHOULD NOT be used for undefined escape sequences. As an example, `\\\\a` is equivalent and preferable to `\\a`. +Escaping MUST also be applied to quoted UTF-8 strings. + ##### Numbers Integer numbers MUST NOT have a decimal point. Examples are `23`, `0042`, and `1341298465647914`. From 0206e9b7a2f498e6e4f477c3ff0925889976e823 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Thu, 2 Oct 2025 11:41:27 -0400 Subject: [PATCH 2/4] tweak name sections Signed-off-by: Owen Williams --- docs/specs/om/open_metrics_spec_1_1.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/specs/om/open_metrics_spec_1_1.md b/docs/specs/om/open_metrics_spec_1_1.md index 332c0694a..a290726cb 100644 --- a/docs/specs/om/open_metrics_spec_1_1.md +++ b/docs/specs/om/open_metrics_spec_1_1.md @@ -60,7 +60,7 @@ Common examples of metric time series would be network interface counters, devic ## Data Model -This section MUST be read together with the ABNF section. In case of disagreements between the two, the ABNF's restrictions MUST take precedence. This reduces repetition as the text wire format MUST be supported. +This section MUST be read together with the ABNF section. In case of disagreements between the two, the ABNF's restrictions MUST take precedence. This reduces repetition as the text wire format MUST be supported. ### Data Types @@ -84,7 +84,7 @@ Strings MUST only consist of valid UTF-8 characters and MAY be zero length. NULL Labels are key-value pairs consisting of strings. -Label names beginning with underscores are RESERVED and MUST NOT be used unless specified by this standard. Label names MUST follow the restrictions in the ABNF section. +Label names beginning with two underscores are RESERVED and MUST NOT be used unless specified by this standard. Label names SHOULD follow the restrictions in the ABNF section under the `label-name` section. Label names MAY be any quoted escaped UTF-8 string as described in the ABNF section. Be aware that exposing UTF-8 metrics is still experimental and may reduce usability. Empty label values SHOULD be treated as if the label was not present. @@ -120,7 +120,7 @@ A MetricFamily MAY have zero or more Metrics. A MetricFamily MUST have a name, H ##### Name -MetricFamily names are a string and MUST be unique within a MetricSet. Names SHOULD be in snake_case. Metric names MUST follow the restrictions in the ABNF section. +MetricFamily names are a string and MUST be unique within a MetricSet. Names SHOULD be in snake_case. Names SHOULD follow the restrictions in the ABNF section under `metricname`. Metric names MAY be any quoted and escaped UTF-8 string as described in the ABNF section. Be aware that exposing UTF-8 metrics is still experimental and may reduce usability, especially when suffixes are not included. Colons in MetricFamily names are RESERVED to signal that the MetricFamily is the result of a calculation or aggregation of a general purpose monitoring system. From 0b25d061d18c2edd3a2e41ee831c013d971e300c Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Fri, 3 Oct 2025 11:08:44 -0400 Subject: [PATCH 3/4] note Signed-off-by: Owen Williams --- docs/specs/om/open_metrics_spec_1_1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/specs/om/open_metrics_spec_1_1.md b/docs/specs/om/open_metrics_spec_1_1.md index a290726cb..a31ba8d7a 100644 --- a/docs/specs/om/open_metrics_spec_1_1.md +++ b/docs/specs/om/open_metrics_spec_1_1.md @@ -327,9 +327,9 @@ metric-type =/ info / summary / unknown sample = metricname-and-labels SP number [SP timestamp] [exemplar] LF -metricname-and-labels = metricname [labels-in-braces] / name-in-braces +metricname-and-labels = metricname [labels-in-braces] / name-and-labels-in-braces labels-in-braces = "{" [label *(COMMA label)] "}" -name-in-braces = "{" metricname-utf8 *(COMMA label) "}" +name-and-labels-in-braces = "{" metricname-utf8 *(COMMA label) "}" label = label-key EQ DQUOTE escaped-string DQUOTE From 8564f6d8dbe83ee505dc6db10cb49a108e4c5769 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Wed, 8 Oct 2025 09:34:28 -0400 Subject: [PATCH 4/4] notes Signed-off-by: Owen Williams --- docs/specs/om/open_metrics_spec_1_1.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/specs/om/open_metrics_spec_1_1.md b/docs/specs/om/open_metrics_spec_1_1.md index a31ba8d7a..cbda78d65 100644 --- a/docs/specs/om/open_metrics_spec_1_1.md +++ b/docs/specs/om/open_metrics_spec_1_1.md @@ -374,14 +374,15 @@ SIGN = "-" / "+" metricname = metricname-initial-char 0*metricname-char metricname-char = metricname-initial-char / DIGIT metricname-initial-char = ALPHA / "_" / ":" -metricname-utf8 = DQUOTE escaped-string DQUOTE +metricname-utf8 = DQUOTE escaped-string-non-empty DQUOTE -label-key = label-name / DQUOTE escaped-string DQUOTE +label-key = label-name / DQUOTE escaped-string-non-empty DQUOTE label-name = label-name-initial-char *label-name-char label-name-char = label-name-initial-char / DIGIT label-name-initial-char = ALPHA / "_" -escaped-string = 1*escaped-char +escaped-string = escaped-char +escaped-string-non-empty = 1*escaped-char escaped-char = normal-char escaped-char =/ BS ("n" / DQUOTE / BS) @@ -950,7 +951,7 @@ For high availability and ad-hoc access a common approach is to have multiple in # EDITOR’S NOTE: This section might be good for a BCP paper. --> -We aim for a balance between understandability, avoiding clashes, and succinctness in the naming of metrics and label names. Names are separated through underscores, so metric names end up being in “snake_case”. +We aim for a balance between understandability, avoiding clashes, and succinctness in the naming of metrics and label names. Names are separated through underscores, so metric names end up being in “snake_case”. While we strongly recommend the practices recommended in this document, other metric systems have different philosophies regarding naming conventions. OpenMetrics allows metrics to be exposed, but without the conventions and suffixes recommended here there is an increased risk of collisions and incompatibilities along the chain of services in a metrics system. Users wishing to use alternative conventions will need to take special care and expend additional effort to ensure that the entire ecosystem is consistent. To take an example "http_request_seconds" is succinct but would clash between large numbers of applications, and it's also unclear exactly what this metric is measuring. For example, it might be before or after auth middleware in a complex system. @@ -990,7 +991,7 @@ While there is metadata about metric names such as HELP, TYPE and UNIT there is ### Metric Names versus Labels -There are situations in which both using multiple Metrics within a MetricFamily or multiple MetricFamilies seem to make sense. Summing or averaging aMetricFamily should be meaningful even if it's not always useful. For example, mixing voltage and fan speed is not meaningful. +There are situations in which both using multiple Metrics within a MetricFamily or multiple MetricFamilies seem to make sense. Summing or averaging a MetricFamily should be meaningful even if it's not always useful. For example, mixing voltage and fan speed is not meaningful. As a reminder, OpenMetrics is built with the assumption that ingestors can process and perform aggregations on data.