-
Notifications
You must be signed in to change notification settings - Fork 385
/
integration_test.rs
161 lines (131 loc) · 5.69 KB
/
integration_test.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use opentelemetry::sdk::Resource;
use opentelemetry::{
metrics::{BatchObserverResult, MeterProvider, ObserverResult},
KeyValue,
};
use opentelemetry_prometheus::PrometheusExporter;
use prometheus::{Encoder, TextEncoder};
#[test]
fn free_unused_instruments() {
let exporter = opentelemetry_prometheus::exporter()
.with_default_histogram_boundaries(vec![-0.5, 1.0])
.with_resource(Resource::new(vec![KeyValue::new("R", "V")]))
.init();
let mut expected = Vec::new();
{
let meter = exporter.provider().unwrap().meter("test", None, None);
let counter = meter.f64_counter("counter").init();
let attributes = vec![KeyValue::new("A", "B"), KeyValue::new("C", "D")];
counter.add(10.0, &attributes);
counter.add(5.3, &attributes);
expected.push(r#"counter{A="B",C="D",R="V"} 15.3"#);
}
// Standard export
compare_export(&exporter, expected.clone());
// Final export before instrument dropped
compare_export(&exporter, expected.clone());
// Instrument dropped, but last value kept by prom exporter
compare_export(&exporter, expected);
}
#[test]
fn batch() {
let exporter = opentelemetry_prometheus::exporter()
.with_resource(Resource::new(vec![KeyValue::new("R", "V")]))
.init();
let meter = exporter.provider().unwrap().meter("test", None, None);
let mut expected = Vec::new();
meter.batch_observer(|batch| {
let uint_observer = batch.u64_value_observer("uint_observer").init();
let float_observer = batch.f64_value_observer("float_observer").init();
move |result: BatchObserverResult| {
result.observe(
&[KeyValue::new("A", "B")],
&[
uint_observer.observation(2),
float_observer.observation(3.1),
],
);
}
});
expected.push(r#"uint_observer{A="B",R="V"} 2"#);
expected.push(r#"float_observer{A="B",R="V"} 3.1"#);
compare_export(&exporter, expected);
}
#[test]
fn test_add() {
let exporter = opentelemetry_prometheus::exporter()
.with_default_histogram_boundaries(vec![-0.5, 1.0])
.with_resource(Resource::new(vec![KeyValue::new("R", "V")]))
.init();
let meter = exporter.provider().unwrap().meter("test", None, None);
let up_down_counter = meter.f64_up_down_counter("updowncounter").init();
let counter = meter.f64_counter("counter").init();
let histogram = meter.f64_histogram("my.histogram").init();
let attributes = vec![KeyValue::new("A", "B"), KeyValue::new("C", "D")];
let mut expected = Vec::new();
counter.add(10.0, &attributes);
counter.add(5.3, &attributes);
expected.push(r#"counter{A="B",C="D",R="V"} 15.3"#);
let cb_attributes = attributes.clone();
let _observer = meter
.i64_value_observer("intobserver", move |result: ObserverResult<i64>| {
result.observe(1, cb_attributes.as_ref())
})
.init();
expected.push(r#"intobserver{A="B",C="D",R="V"} 1"#);
histogram.record(-0.6, &attributes);
histogram.record(-0.4, &attributes);
histogram.record(0.6, &attributes);
histogram.record(20.0, &attributes);
expected.push(r#"my_histogram_bucket{A="B",C="D",R="V",le="+Inf"} 4"#);
expected.push(r#"my_histogram_bucket{A="B",C="D",R="V",le="-0.5"} 1"#);
expected.push(r#"my_histogram_bucket{A="B",C="D",R="V",le="1"} 3"#);
expected.push(r#"my_histogram_count{A="B",C="D",R="V"} 4"#);
expected.push(r#"my_histogram_sum{A="B",C="D",R="V"} 19.6"#);
up_down_counter.add(10.0, &attributes);
up_down_counter.add(-3.2, &attributes);
expected.push(r#"updowncounter{A="B",C="D",R="V"} 6.8"#);
compare_export(&exporter, expected)
}
#[test]
fn test_sanitization() {
let exporter = opentelemetry_prometheus::exporter()
.with_default_histogram_boundaries(vec![-0.5, 1.0])
.with_resource(Resource::new(vec![KeyValue::new(
"service.name",
"Test Service",
)]))
.init();
let meter = exporter.provider().unwrap().meter("test", None, None);
let histogram = meter.f64_histogram("http.server.duration").init();
let attributes = vec![
KeyValue::new("http.method", "GET"),
KeyValue::new("http.host", "server"),
];
histogram.record(-0.6, &attributes);
histogram.record(-0.4, &attributes);
histogram.record(0.6, &attributes);
histogram.record(20.0, &attributes);
let expected = vec![
r#"http_server_duration_bucket{http_host="server",http_method="GET",service_name="Test Service",le="+Inf"} 4"#,
r#"http_server_duration_bucket{http_host="server",http_method="GET",service_name="Test Service",le="-0.5"} 1"#,
r#"http_server_duration_bucket{http_host="server",http_method="GET",service_name="Test Service",le="1"} 3"#,
r#"http_server_duration_count{http_host="server",http_method="GET",service_name="Test Service"} 4"#,
r#"http_server_duration_sum{http_host="server",http_method="GET",service_name="Test Service"} 19.6"#,
];
compare_export(&exporter, expected)
}
fn compare_export(exporter: &PrometheusExporter, mut expected: Vec<&'static str>) {
let mut output = Vec::new();
let encoder = TextEncoder::new();
let metric_families = exporter.registry().gather();
encoder.encode(&metric_families, &mut output).unwrap();
let output_string = String::from_utf8(output).unwrap();
let mut metrics_only = output_string
.split_terminator('\n')
.filter(|line| !line.starts_with('#') && !line.is_empty())
.collect::<Vec<_>>();
metrics_only.sort_unstable();
expected.sort_unstable();
assert_eq!(expected.join("\n"), metrics_only.join("\n"))
}