Skip to content

Commit 4b58006

Browse files
committed
protobuf: move from openmetrics to protobuf
1 parent d4d816a commit 4b58006

7 files changed

Lines changed: 508 additions & 719 deletions

File tree

build.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn main() -> Result<(), Box<dyn Error>> {
99

1010
#[cfg(feature = "protobuf")]
1111
fn compile_protos() -> Result<(), Box<dyn Error>> {
12-
let protos = ["src/encoding/proto/openmetrics_data_model.proto"];
12+
let protos = ["src/encoding/proto/metrics.proto"];
1313
let includes = ["src/encoding/proto/"];
1414

1515
#[cfg(feature = "protobuf-protox")]
@@ -18,5 +18,12 @@ fn compile_protos() -> Result<(), Box<dyn Error>> {
1818
#[cfg(not(feature = "protobuf-protox"))]
1919
prost_build::compile_protos(&protos, &includes)?;
2020

21+
for path in &protos {
22+
println!("cargo:rerun-if-changed={}", path);
23+
}
24+
for path in &includes {
25+
println!("cargo:rerun-if-changed={}", path);
26+
}
27+
2128
Ok(())
2229
}

derive-encode/tests/lib.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn basic_flow() {
4848
mod protobuf {
4949
use crate::{Labels, Method};
5050
use prometheus_client::encoding::protobuf::encode;
51-
use prometheus_client::encoding::protobuf::openmetrics_data_model;
51+
use prometheus_client::encoding::protobuf::prometheus_data_model;
5252
use prometheus_client::metrics::counter::Counter;
5353
use prometheus_client::metrics::family::Family;
5454
use prometheus_client::registry::Registry;
@@ -67,17 +67,15 @@ mod protobuf {
6767
})
6868
.inc();
6969

70-
// Encode all metrics in the registry in the OpenMetrics protobuf format.
71-
let mut metric_set = encode(&registry).unwrap();
72-
let mut family: openmetrics_data_model::MetricFamily =
73-
metric_set.metric_families.pop().unwrap();
74-
let metric: openmetrics_data_model::Metric = family.metrics.pop().unwrap();
70+
let mut metric_families = encode(&registry).unwrap();
71+
let mut family: prometheus_data_model::MetricFamily = metric_families.pop().unwrap();
72+
let metric: prometheus_data_model::Metric = family.metric.pop().unwrap();
7573

76-
let method = &metric.labels[0];
74+
let method = &metric.label[0];
7775
assert_eq!("method", method.name);
7876
assert_eq!("Get", method.value);
7977

80-
let path = &metric.labels[1];
78+
let path = &metric.label[1];
8179
assert_eq!("path", path.name);
8280
assert_eq!("/metrics", path.value);
8381
}
@@ -96,13 +94,11 @@ mod protobuf {
9694
})
9795
.inc();
9896

99-
// Encode all metrics in the registry in the OpenMetrics protobuf format.
100-
let mut metric_set = encode(&registry).unwrap();
101-
let mut family: openmetrics_data_model::MetricFamily =
102-
metric_set.metric_families.pop().unwrap();
103-
let metric: openmetrics_data_model::Metric = family.metrics.pop().unwrap();
97+
let mut metric_families = encode(&registry).unwrap();
98+
let mut family: prometheus_data_model::MetricFamily = metric_families.pop().unwrap();
99+
let metric: prometheus_data_model::Metric = family.metric.pop().unwrap();
104100

105-
let label = &metric.labels[0];
101+
let label = &metric.label[0];
106102
assert_eq!("method", label.name);
107103
assert_eq!("Get", label.value);
108104
}

src/encoding.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,7 @@ impl EncodeGaugeValue for i64 {
611611

612612
impl EncodeGaugeValue for u64 {
613613
fn encode(&self, encoder: &mut GaugeValueEncoder) -> Result<(), std::fmt::Error> {
614-
// Between forcing end users to do endless as i64 for things that are
615-
// clearly valid i64 and having one error case for rarely used protobuf when
616-
// a gauge is set to >i64::MAX, the latter seems like the right choice.
617-
encoder.encode_i64(i64::try_from(*self).map_err(|_err| std::fmt::Error)?)
614+
encoder.encode_u64(*self)
618615
}
619616
}
620617

@@ -652,6 +649,10 @@ impl GaugeValueEncoder<'_> {
652649
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_u32(v))
653650
}
654651

652+
fn encode_u64(&mut self, v: u64) -> Result<(), std::fmt::Error> {
653+
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_u64(v))
654+
}
655+
655656
fn encode_i64(&mut self, v: i64) -> Result<(), std::fmt::Error> {
656657
for_both_mut!(self, GaugeValueEncoderInner, e, e.encode_i64(v))
657658
}

src/encoding/proto/metrics.proto

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright 2013 Prometheus Team
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
syntax = "proto3";
15+
16+
package io.prometheus.client;
17+
option go_package = "io_prometheus_client";
18+
19+
import "google/protobuf/timestamp.proto";
20+
21+
message LabelPair {
22+
string name = 1;
23+
string value = 2;
24+
}
25+
26+
enum MetricType {
27+
// COUNTER must use the Metric field "counter".
28+
COUNTER = 0;
29+
// GAUGE must use the Metric field "gauge".
30+
GAUGE = 1;
31+
// SUMMARY must use the Metric field "summary".
32+
SUMMARY = 2;
33+
// UNTYPED must use the Metric field "untyped".
34+
UNTYPED = 3;
35+
// HISTOGRAM must use the Metric field "histogram".
36+
HISTOGRAM = 4;
37+
// GAUGE_HISTOGRAM must use the Metric field "histogram".
38+
GAUGE_HISTOGRAM = 5;
39+
}
40+
41+
message Gauge {
42+
double value = 1;
43+
}
44+
45+
message Counter {
46+
double value = 1;
47+
Exemplar exemplar = 2;
48+
49+
google.protobuf.Timestamp start_timestamp = 3;
50+
}
51+
52+
message Quantile {
53+
double quantile = 1;
54+
double value = 2;
55+
}
56+
57+
message Summary {
58+
uint64 sample_count = 1;
59+
double sample_sum = 2;
60+
repeated Quantile quantile = 3;
61+
62+
google.protobuf.Timestamp start_timestamp = 4;
63+
}
64+
65+
message Untyped {
66+
double value = 1;
67+
}
68+
69+
message Histogram {
70+
uint64 sample_count = 1;
71+
double sample_count_float = 4; // Overrides sample_count if > 0.
72+
double sample_sum = 2;
73+
// Buckets for the classic histogram.
74+
repeated Bucket bucket = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
75+
76+
google.protobuf.Timestamp start_timestamp = 15;
77+
78+
// Everything below here is for native histograms (formerly known as sparse histograms).
79+
80+
// schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
81+
// They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
82+
// then each power of two is divided into 2^n logarithmic buckets.
83+
// Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
84+
// In the future, more bucket schemas may be added using numbers < -4 or > 8.
85+
sint32 schema = 5;
86+
double zero_threshold = 6; // Breadth of the zero bucket.
87+
uint64 zero_count = 7; // Count in zero bucket.
88+
double zero_count_float = 8; // Overrides sb_zero_count if > 0.
89+
90+
// Negative buckets for the native histogram.
91+
repeated BucketSpan negative_span = 9;
92+
// Use either "negative_delta" or "negative_count", the former for
93+
// regular histograms with integer counts, the latter for float
94+
// histograms.
95+
repeated sint64 negative_delta = 10; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
96+
repeated double negative_count = 11; // Absolute count of each bucket.
97+
98+
// Positive buckets for the native histogram.
99+
// Use a no-op span (offset 0, length 0) for a native histogram without any
100+
// observations yet and with a zero_threshold of 0. Otherwise, it would be
101+
// indistinguishable from a classic histogram.
102+
repeated BucketSpan positive_span = 12;
103+
// Use either "positive_delta" or "positive_count", the former for
104+
// regular histograms with integer counts, the latter for float
105+
// histograms.
106+
repeated sint64 positive_delta = 13; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
107+
repeated double positive_count = 14; // Absolute count of each bucket.
108+
109+
// Only used for native histograms. These exemplars MUST have a timestamp.
110+
repeated Exemplar exemplars = 16;
111+
}
112+
113+
message Bucket {
114+
uint64 cumulative_count = 1; // Cumulative in increasing order.
115+
double cumulative_count_float = 4; // Overrides cumulative_count if > 0.
116+
double upper_bound = 2; // Inclusive.
117+
Exemplar exemplar = 3;
118+
}
119+
120+
// A BucketSpan defines a number of consecutive buckets in a native
121+
// histogram with their offset. Logically, it would be more
122+
// straightforward to include the bucket counts in the Span. However,
123+
// the protobuf representation is more compact in the way the data is
124+
// structured here (with all the buckets in a single array separate
125+
// from the Spans).
126+
message BucketSpan {
127+
sint32 offset = 1; // Gap to previous span, or starting point for 1st span (which can be negative).
128+
uint32 length = 2; // Length of consecutive buckets.
129+
}
130+
131+
message Exemplar {
132+
repeated LabelPair label = 1;
133+
double value = 2;
134+
google.protobuf.Timestamp timestamp = 3; // OpenMetrics-style.
135+
}
136+
137+
message Metric {
138+
repeated LabelPair label = 1;
139+
Gauge gauge = 2;
140+
Counter counter = 3;
141+
Summary summary = 4;
142+
Untyped untyped = 5;
143+
Histogram histogram = 7;
144+
int64 timestamp_ms = 6;
145+
}
146+
147+
message MetricFamily {
148+
string name = 1;
149+
string help = 2;
150+
MetricType type = 3;
151+
repeated Metric metric = 4;
152+
string unit = 5;
153+
}

0 commit comments

Comments
 (0)