@temporalio/core-bridge 1.12.0 → 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +64 -119
- package/Cargo.toml +1 -1
- package/index.js +3 -2
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.cargo/config.toml +1 -2
- package/sdk-core/.github/workflows/per-pr.yml +2 -0
- package/sdk-core/AGENTS.md +7 -0
- package/sdk-core/Cargo.toml +9 -5
- package/sdk-core/README.md +6 -5
- package/sdk-core/client/Cargo.toml +3 -2
- package/sdk-core/client/src/lib.rs +17 -8
- package/sdk-core/client/src/metrics.rs +57 -23
- package/sdk-core/client/src/raw.rs +33 -15
- package/sdk-core/core/Cargo.toml +11 -9
- package/sdk-core/core/benches/workflow_replay.rs +114 -15
- package/sdk-core/core/src/core_tests/activity_tasks.rs +18 -18
- package/sdk-core/core/src/core_tests/child_workflows.rs +4 -4
- package/sdk-core/core/src/core_tests/determinism.rs +6 -6
- package/sdk-core/core/src/core_tests/local_activities.rs +20 -20
- package/sdk-core/core/src/core_tests/mod.rs +40 -5
- package/sdk-core/core/src/core_tests/queries.rs +25 -16
- package/sdk-core/core/src/core_tests/replay_flag.rs +3 -3
- package/sdk-core/core/src/core_tests/updates.rs +3 -3
- package/sdk-core/core/src/core_tests/workers.rs +9 -7
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +40 -42
- package/sdk-core/core/src/ephemeral_server/mod.rs +1 -19
- package/sdk-core/core/src/lib.rs +10 -1
- package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/telemetry/metrics.rs +306 -152
- package/sdk-core/core/src/telemetry/mod.rs +11 -4
- package/sdk-core/core/src/telemetry/otel.rs +134 -131
- package/sdk-core/core/src/telemetry/prometheus_meter.rs +885 -0
- package/sdk-core/core/src/telemetry/prometheus_server.rs +48 -28
- package/sdk-core/core/src/test_help/mod.rs +27 -12
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +7 -7
- package/sdk-core/core/src/worker/activities.rs +4 -4
- package/sdk-core/core/src/worker/client/mocks.rs +10 -3
- package/sdk-core/core/src/worker/client.rs +68 -5
- package/sdk-core/core/src/worker/heartbeat.rs +229 -0
- package/sdk-core/core/src/worker/mod.rs +35 -14
- package/sdk-core/core/src/worker/tuner/resource_based.rs +4 -4
- package/sdk-core/core/src/worker/workflow/history_update.rs +71 -19
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +31 -48
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +3 -3
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +4 -1
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +15 -15
- package/sdk-core/core-api/Cargo.toml +2 -2
- package/sdk-core/core-api/src/envconfig.rs +204 -99
- package/sdk-core/core-api/src/lib.rs +9 -0
- package/sdk-core/core-api/src/telemetry/metrics.rs +548 -100
- package/sdk-core/core-api/src/worker.rs +11 -5
- package/sdk-core/core-c-bridge/Cargo.toml +49 -0
- package/sdk-core/core-c-bridge/build.rs +26 -0
- package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +817 -0
- package/sdk-core/core-c-bridge/src/client.rs +679 -0
- package/sdk-core/core-c-bridge/src/lib.rs +245 -0
- package/sdk-core/core-c-bridge/src/metric.rs +682 -0
- package/sdk-core/core-c-bridge/src/random.rs +61 -0
- package/sdk-core/core-c-bridge/src/runtime.rs +445 -0
- package/sdk-core/core-c-bridge/src/testing.rs +282 -0
- package/sdk-core/core-c-bridge/src/tests/context.rs +644 -0
- package/sdk-core/core-c-bridge/src/tests/mod.rs +178 -0
- package/sdk-core/core-c-bridge/src/tests/utils.rs +108 -0
- package/sdk-core/core-c-bridge/src/worker.rs +1069 -0
- package/sdk-core/etc/deps.svg +64 -64
- package/sdk-core/sdk/src/activity_context.rs +6 -4
- package/sdk-core/sdk/src/lib.rs +49 -27
- package/sdk-core/sdk/src/workflow_future.rs +18 -25
- package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +4 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +0 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +630 -83
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +632 -78
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto +4 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +6 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +32 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +10 -1
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/deployment.proto +26 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/reset.proto +4 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +47 -31
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +4 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +7 -1
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/worker/v1/message.proto +134 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +14 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +148 -37
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +21 -0
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -4
- package/sdk-core/sdk-core-protos/src/history_builder.rs +9 -5
- package/sdk-core/sdk-core-protos/src/lib.rs +96 -6
- package/sdk-core/test-utils/src/lib.rs +11 -3
- package/sdk-core/tests/cloud_tests.rs +3 -3
- package/sdk-core/tests/heavy_tests.rs +11 -3
- package/sdk-core/tests/integ_tests/client_tests.rs +12 -13
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/metrics_tests.rs +188 -83
- package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +56 -40
- package/sdk-core/tests/integ_tests/update_tests.rs +2 -7
- package/sdk-core/tests/integ_tests/worker_tests.rs +3 -4
- package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +3 -7
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +3 -5
- package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +24 -17
- package/src/client.rs +6 -0
- package/src/metrics.rs +6 -6
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
use crate::dbg_panic;
|
|
1
2
|
use std::{
|
|
2
3
|
any::Any,
|
|
3
4
|
borrow::Cow,
|
|
4
|
-
|
|
5
|
+
collections::{BTreeMap, HashMap},
|
|
6
|
+
fmt::{Debug, Display},
|
|
5
7
|
ops::Deref,
|
|
6
8
|
sync::{Arc, OnceLock},
|
|
7
9
|
time::Duration,
|
|
@@ -23,16 +25,16 @@ pub trait CoreMeter: Send + Sync + Debug {
|
|
|
23
25
|
existing: MetricAttributes,
|
|
24
26
|
attribs: NewAttributes,
|
|
25
27
|
) -> MetricAttributes;
|
|
26
|
-
fn counter(&self, params: MetricParameters) ->
|
|
27
|
-
fn histogram(&self, params: MetricParameters) ->
|
|
28
|
-
fn histogram_f64(&self, params: MetricParameters) ->
|
|
28
|
+
fn counter(&self, params: MetricParameters) -> Counter;
|
|
29
|
+
fn histogram(&self, params: MetricParameters) -> Histogram;
|
|
30
|
+
fn histogram_f64(&self, params: MetricParameters) -> HistogramF64;
|
|
29
31
|
/// Create a histogram which records Durations. Implementations should choose to emit in
|
|
30
32
|
/// either milliseconds or seconds depending on how they have been configured.
|
|
31
33
|
/// [MetricParameters::unit] should be overwritten by implementations to be `ms` or `s`
|
|
32
34
|
/// accordingly.
|
|
33
|
-
fn histogram_duration(&self, params: MetricParameters) ->
|
|
34
|
-
fn gauge(&self, params: MetricParameters) ->
|
|
35
|
-
fn gauge_f64(&self, params: MetricParameters) ->
|
|
35
|
+
fn histogram_duration(&self, params: MetricParameters) -> HistogramDuration;
|
|
36
|
+
fn gauge(&self, params: MetricParameters) -> Gauge;
|
|
37
|
+
fn gauge_f64(&self, params: MetricParameters) -> GaugeF64;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
#[derive(Debug, Clone, derive_builder::Builder)]
|
|
@@ -84,26 +86,26 @@ impl CoreMeter for Arc<dyn CoreMeter> {
|
|
|
84
86
|
self.as_ref().extend_attributes(existing, attribs)
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
fn counter(&self, params: MetricParameters) ->
|
|
89
|
+
fn counter(&self, params: MetricParameters) -> Counter {
|
|
88
90
|
self.as_ref().counter(params)
|
|
89
91
|
}
|
|
90
|
-
fn histogram(&self, params: MetricParameters) ->
|
|
92
|
+
fn histogram(&self, params: MetricParameters) -> Histogram {
|
|
91
93
|
self.as_ref().histogram(params)
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
fn histogram_f64(&self, params: MetricParameters) ->
|
|
96
|
+
fn histogram_f64(&self, params: MetricParameters) -> HistogramF64 {
|
|
95
97
|
self.as_ref().histogram_f64(params)
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
fn histogram_duration(&self, params: MetricParameters) ->
|
|
100
|
+
fn histogram_duration(&self, params: MetricParameters) -> HistogramDuration {
|
|
99
101
|
self.as_ref().histogram_duration(params)
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
fn gauge(&self, params: MetricParameters) ->
|
|
104
|
+
fn gauge(&self, params: MetricParameters) -> Gauge {
|
|
103
105
|
self.as_ref().gauge(params)
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
fn gauge_f64(&self, params: MetricParameters) ->
|
|
108
|
+
fn gauge_f64(&self, params: MetricParameters) -> GaugeF64 {
|
|
107
109
|
self.as_ref().gauge_f64(params)
|
|
108
110
|
}
|
|
109
111
|
}
|
|
@@ -117,8 +119,12 @@ pub enum MetricAttributes {
|
|
|
117
119
|
OTel {
|
|
118
120
|
kvs: Arc<Vec<opentelemetry::KeyValue>>,
|
|
119
121
|
},
|
|
122
|
+
Prometheus {
|
|
123
|
+
labels: Arc<OrderedPromLabelSet>,
|
|
124
|
+
},
|
|
120
125
|
Buffer(BufferAttributes),
|
|
121
126
|
Dynamic(Arc<dyn CustomMetricAttributes>),
|
|
127
|
+
Empty,
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
/// A reference to some attributes created lang side.
|
|
@@ -150,7 +156,7 @@ where
|
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
/// A K/V pair that can be used to label a specific recording of a metric
|
|
153
|
-
#[derive(Clone, Debug)]
|
|
159
|
+
#[derive(Clone, Debug, PartialEq)]
|
|
154
160
|
pub struct MetricKeyValue {
|
|
155
161
|
pub key: String,
|
|
156
162
|
pub value: MetricValue,
|
|
@@ -165,7 +171,7 @@ impl MetricKeyValue {
|
|
|
165
171
|
}
|
|
166
172
|
|
|
167
173
|
/// Values metric labels may assume
|
|
168
|
-
#[derive(Clone, Debug, derive_more::From)]
|
|
174
|
+
#[derive(Clone, Debug, PartialEq, derive_more::From)]
|
|
169
175
|
pub enum MetricValue {
|
|
170
176
|
String(String),
|
|
171
177
|
Int(i64),
|
|
@@ -178,30 +184,368 @@ impl From<&'static str> for MetricValue {
|
|
|
178
184
|
MetricValue::String(value.to_string())
|
|
179
185
|
}
|
|
180
186
|
}
|
|
187
|
+
impl Display for MetricValue {
|
|
188
|
+
fn fmt(&self, f1: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
189
|
+
match self {
|
|
190
|
+
MetricValue::String(s) => write!(f1, "{s}"),
|
|
191
|
+
MetricValue::Int(i) => write!(f1, "{i}"),
|
|
192
|
+
MetricValue::Float(f) => write!(f1, "{f}"),
|
|
193
|
+
MetricValue::Bool(b) => write!(f1, "{b}"),
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
pub trait MetricAttributable<Base> {
|
|
199
|
+
/// Replace any existing attributes on this metric with new ones, and return a new copy
|
|
200
|
+
/// of the metric, or a base version, which can be used to record values.
|
|
201
|
+
///
|
|
202
|
+
/// Note that this operation is relatively expensive compared to simply recording a value
|
|
203
|
+
/// without any additional attributes, so users should prefer to save the metric instance
|
|
204
|
+
/// after calling this, and use the value-only methods afterward.
|
|
205
|
+
///
|
|
206
|
+
/// This operation may fail if the underlying metrics implementation disallows the registration
|
|
207
|
+
/// of a new metric, or encounters any other issue.
|
|
208
|
+
fn with_attributes(
|
|
209
|
+
&self,
|
|
210
|
+
attributes: &MetricAttributes,
|
|
211
|
+
) -> Result<Base, Box<dyn std::error::Error>>;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
#[derive(Clone)]
|
|
215
|
+
pub struct LazyBoundMetric<T, B> {
|
|
216
|
+
metric: T,
|
|
217
|
+
attributes: MetricAttributes,
|
|
218
|
+
bound_cache: OnceLock<B>,
|
|
219
|
+
}
|
|
220
|
+
impl<T, B> LazyBoundMetric<T, B> {
|
|
221
|
+
pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
|
|
222
|
+
self.attributes = new_attributes;
|
|
223
|
+
self.bound_cache = OnceLock::new();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
pub trait CounterBase: Send + Sync {
|
|
228
|
+
fn adds(&self, value: u64);
|
|
229
|
+
}
|
|
230
|
+
pub type Counter = LazyBoundMetric<
|
|
231
|
+
Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>,
|
|
232
|
+
Arc<dyn CounterBase>,
|
|
233
|
+
>;
|
|
234
|
+
impl Counter {
|
|
235
|
+
pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>) -> Self {
|
|
236
|
+
Self {
|
|
237
|
+
metric: inner,
|
|
238
|
+
attributes: MetricAttributes::Empty,
|
|
239
|
+
bound_cache: OnceLock::new(),
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
pub fn add(&self, value: u64, attributes: &MetricAttributes) {
|
|
243
|
+
match self.metric.with_attributes(attributes) {
|
|
244
|
+
Ok(base) => {
|
|
245
|
+
base.adds(value);
|
|
246
|
+
}
|
|
247
|
+
Err(e) => {
|
|
248
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}",);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
impl CounterBase for Counter {
|
|
254
|
+
fn adds(&self, value: u64) {
|
|
255
|
+
// TODO: Replace all of these with below when stable
|
|
256
|
+
// https://doc.rust-lang.org/std/sync/struct.OnceLock.html#method.get_or_try_init
|
|
257
|
+
let bound = self.bound_cache.get_or_init(|| {
|
|
258
|
+
self.metric
|
|
259
|
+
.with_attributes(&self.attributes)
|
|
260
|
+
.map(Into::into)
|
|
261
|
+
.unwrap_or_else(|e| {
|
|
262
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}");
|
|
263
|
+
Arc::new(NoOpInstrument) as Arc<dyn CounterBase>
|
|
264
|
+
})
|
|
265
|
+
});
|
|
266
|
+
bound.adds(value);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
impl MetricAttributable<Counter> for Counter {
|
|
270
|
+
fn with_attributes(
|
|
271
|
+
&self,
|
|
272
|
+
attributes: &MetricAttributes,
|
|
273
|
+
) -> Result<Counter, Box<dyn std::error::Error>> {
|
|
274
|
+
Ok(Self {
|
|
275
|
+
metric: self.metric.clone(),
|
|
276
|
+
attributes: attributes.clone(),
|
|
277
|
+
bound_cache: OnceLock::new(),
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
}
|
|
181
281
|
|
|
182
|
-
pub trait
|
|
183
|
-
fn
|
|
282
|
+
pub trait HistogramBase: Send + Sync {
|
|
283
|
+
fn records(&self, value: u64);
|
|
284
|
+
}
|
|
285
|
+
pub type Histogram = LazyBoundMetric<
|
|
286
|
+
Arc<dyn MetricAttributable<Box<dyn HistogramBase>> + Send + Sync>,
|
|
287
|
+
Arc<dyn HistogramBase>,
|
|
288
|
+
>;
|
|
289
|
+
impl Histogram {
|
|
290
|
+
pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn HistogramBase>> + Send + Sync>) -> Self {
|
|
291
|
+
Self {
|
|
292
|
+
metric: inner,
|
|
293
|
+
attributes: MetricAttributes::Empty,
|
|
294
|
+
bound_cache: OnceLock::new(),
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
pub fn record(&self, value: u64, attributes: &MetricAttributes) {
|
|
298
|
+
match self.metric.with_attributes(attributes) {
|
|
299
|
+
Ok(base) => {
|
|
300
|
+
base.records(value);
|
|
301
|
+
}
|
|
302
|
+
Err(e) => {
|
|
303
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}",);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
impl HistogramBase for Histogram {
|
|
309
|
+
fn records(&self, value: u64) {
|
|
310
|
+
let bound = self.bound_cache.get_or_init(|| {
|
|
311
|
+
self.metric
|
|
312
|
+
.with_attributes(&self.attributes)
|
|
313
|
+
.map(Into::into)
|
|
314
|
+
.unwrap_or_else(|e| {
|
|
315
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}");
|
|
316
|
+
Arc::new(NoOpInstrument) as Arc<dyn HistogramBase>
|
|
317
|
+
})
|
|
318
|
+
});
|
|
319
|
+
bound.records(value);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
impl MetricAttributable<Histogram> for Histogram {
|
|
323
|
+
fn with_attributes(
|
|
324
|
+
&self,
|
|
325
|
+
attributes: &MetricAttributes,
|
|
326
|
+
) -> Result<Histogram, Box<dyn std::error::Error>> {
|
|
327
|
+
Ok(Self {
|
|
328
|
+
metric: self.metric.clone(),
|
|
329
|
+
attributes: attributes.clone(),
|
|
330
|
+
bound_cache: OnceLock::new(),
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
pub trait HistogramF64Base: Send + Sync {
|
|
336
|
+
fn records(&self, value: f64);
|
|
337
|
+
}
|
|
338
|
+
pub type HistogramF64 = LazyBoundMetric<
|
|
339
|
+
Arc<dyn MetricAttributable<Box<dyn HistogramF64Base>> + Send + Sync>,
|
|
340
|
+
Arc<dyn HistogramF64Base>,
|
|
341
|
+
>;
|
|
342
|
+
impl HistogramF64 {
|
|
343
|
+
pub fn new(
|
|
344
|
+
inner: Arc<dyn MetricAttributable<Box<dyn HistogramF64Base>> + Send + Sync>,
|
|
345
|
+
) -> Self {
|
|
346
|
+
Self {
|
|
347
|
+
metric: inner,
|
|
348
|
+
attributes: MetricAttributes::Empty,
|
|
349
|
+
bound_cache: OnceLock::new(),
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
pub fn record(&self, value: f64, attributes: &MetricAttributes) {
|
|
353
|
+
match self.metric.with_attributes(attributes) {
|
|
354
|
+
Ok(base) => {
|
|
355
|
+
base.records(value);
|
|
356
|
+
}
|
|
357
|
+
Err(e) => {
|
|
358
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}",);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
impl HistogramF64Base for HistogramF64 {
|
|
364
|
+
fn records(&self, value: f64) {
|
|
365
|
+
let bound = self.bound_cache.get_or_init(|| {
|
|
366
|
+
self.metric
|
|
367
|
+
.with_attributes(&self.attributes)
|
|
368
|
+
.map(Into::into)
|
|
369
|
+
.unwrap_or_else(|e| {
|
|
370
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}");
|
|
371
|
+
Arc::new(NoOpInstrument) as Arc<dyn HistogramF64Base>
|
|
372
|
+
})
|
|
373
|
+
});
|
|
374
|
+
bound.records(value);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
impl MetricAttributable<HistogramF64> for HistogramF64 {
|
|
378
|
+
fn with_attributes(
|
|
379
|
+
&self,
|
|
380
|
+
attributes: &MetricAttributes,
|
|
381
|
+
) -> Result<HistogramF64, Box<dyn std::error::Error>> {
|
|
382
|
+
Ok(Self {
|
|
383
|
+
metric: self.metric.clone(),
|
|
384
|
+
attributes: attributes.clone(),
|
|
385
|
+
bound_cache: OnceLock::new(),
|
|
386
|
+
})
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
pub trait HistogramDurationBase: Send + Sync {
|
|
391
|
+
fn records(&self, value: Duration);
|
|
392
|
+
}
|
|
393
|
+
pub type HistogramDuration = LazyBoundMetric<
|
|
394
|
+
Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
|
|
395
|
+
Arc<dyn HistogramDurationBase>,
|
|
396
|
+
>;
|
|
397
|
+
impl HistogramDuration {
|
|
398
|
+
pub fn new(
|
|
399
|
+
inner: Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
|
|
400
|
+
) -> Self {
|
|
401
|
+
Self {
|
|
402
|
+
metric: inner,
|
|
403
|
+
attributes: MetricAttributes::Empty,
|
|
404
|
+
bound_cache: OnceLock::new(),
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
pub fn record(&self, value: Duration, attributes: &MetricAttributes) {
|
|
408
|
+
match self.metric.with_attributes(attributes) {
|
|
409
|
+
Ok(base) => {
|
|
410
|
+
base.records(value);
|
|
411
|
+
}
|
|
412
|
+
Err(e) => {
|
|
413
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}",);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
impl HistogramDurationBase for HistogramDuration {
|
|
419
|
+
fn records(&self, value: Duration) {
|
|
420
|
+
let bound = self.bound_cache.get_or_init(|| {
|
|
421
|
+
self.metric
|
|
422
|
+
.with_attributes(&self.attributes)
|
|
423
|
+
.map(Into::into)
|
|
424
|
+
.unwrap_or_else(|e| {
|
|
425
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}");
|
|
426
|
+
Arc::new(NoOpInstrument) as Arc<dyn HistogramDurationBase>
|
|
427
|
+
})
|
|
428
|
+
});
|
|
429
|
+
bound.records(value);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
impl MetricAttributable<HistogramDuration> for HistogramDuration {
|
|
433
|
+
fn with_attributes(
|
|
434
|
+
&self,
|
|
435
|
+
attributes: &MetricAttributes,
|
|
436
|
+
) -> Result<HistogramDuration, Box<dyn std::error::Error>> {
|
|
437
|
+
Ok(Self {
|
|
438
|
+
metric: self.metric.clone(),
|
|
439
|
+
attributes: attributes.clone(),
|
|
440
|
+
bound_cache: OnceLock::new(),
|
|
441
|
+
})
|
|
442
|
+
}
|
|
184
443
|
}
|
|
185
444
|
|
|
186
|
-
pub trait
|
|
187
|
-
|
|
188
|
-
|
|
445
|
+
pub trait GaugeBase: Send + Sync {
|
|
446
|
+
fn records(&self, value: u64);
|
|
447
|
+
}
|
|
448
|
+
pub type Gauge = LazyBoundMetric<
|
|
449
|
+
Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>,
|
|
450
|
+
Arc<dyn GaugeBase>,
|
|
451
|
+
>;
|
|
452
|
+
impl Gauge {
|
|
453
|
+
pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>) -> Self {
|
|
454
|
+
Self {
|
|
455
|
+
metric: inner,
|
|
456
|
+
attributes: MetricAttributes::Empty,
|
|
457
|
+
bound_cache: OnceLock::new(),
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
pub fn record(&self, value: u64, attributes: &MetricAttributes) {
|
|
461
|
+
match self.metric.with_attributes(attributes) {
|
|
462
|
+
Ok(base) => {
|
|
463
|
+
base.records(value);
|
|
464
|
+
}
|
|
465
|
+
Err(e) => {
|
|
466
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}",);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
189
470
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
471
|
+
impl GaugeBase for Gauge {
|
|
472
|
+
fn records(&self, value: u64) {
|
|
473
|
+
let bound = self.bound_cache.get_or_init(|| {
|
|
474
|
+
self.metric
|
|
475
|
+
.with_attributes(&self.attributes)
|
|
476
|
+
.map(Into::into)
|
|
477
|
+
.unwrap_or_else(|e| {
|
|
478
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}");
|
|
479
|
+
Arc::new(NoOpInstrument) as Arc<dyn GaugeBase>
|
|
480
|
+
})
|
|
481
|
+
});
|
|
482
|
+
bound.records(value);
|
|
483
|
+
}
|
|
193
484
|
}
|
|
194
|
-
|
|
195
|
-
fn
|
|
485
|
+
impl MetricAttributable<Gauge> for Gauge {
|
|
486
|
+
fn with_attributes(
|
|
487
|
+
&self,
|
|
488
|
+
attributes: &MetricAttributes,
|
|
489
|
+
) -> Result<Gauge, Box<dyn std::error::Error>> {
|
|
490
|
+
Ok(Self {
|
|
491
|
+
metric: self.metric.clone(),
|
|
492
|
+
attributes: attributes.clone(),
|
|
493
|
+
bound_cache: OnceLock::new(),
|
|
494
|
+
})
|
|
495
|
+
}
|
|
196
496
|
}
|
|
197
497
|
|
|
198
|
-
pub trait
|
|
199
|
-
|
|
200
|
-
|
|
498
|
+
pub trait GaugeF64Base: Send + Sync {
|
|
499
|
+
fn records(&self, value: f64);
|
|
500
|
+
}
|
|
501
|
+
pub type GaugeF64 = LazyBoundMetric<
|
|
502
|
+
Arc<dyn MetricAttributable<Box<dyn GaugeF64Base>> + Send + Sync>,
|
|
503
|
+
Arc<dyn GaugeF64Base>,
|
|
504
|
+
>;
|
|
505
|
+
impl GaugeF64 {
|
|
506
|
+
pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn GaugeF64Base>> + Send + Sync>) -> Self {
|
|
507
|
+
Self {
|
|
508
|
+
metric: inner,
|
|
509
|
+
attributes: MetricAttributes::Empty,
|
|
510
|
+
bound_cache: OnceLock::new(),
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
pub fn record(&self, value: f64, attributes: &MetricAttributes) {
|
|
514
|
+
match self.metric.with_attributes(attributes) {
|
|
515
|
+
Ok(base) => {
|
|
516
|
+
base.records(value);
|
|
517
|
+
}
|
|
518
|
+
Err(e) => {
|
|
519
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}",);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
impl GaugeF64Base for GaugeF64 {
|
|
525
|
+
fn records(&self, value: f64) {
|
|
526
|
+
let bound = self.bound_cache.get_or_init(|| {
|
|
527
|
+
self.metric
|
|
528
|
+
.with_attributes(&self.attributes)
|
|
529
|
+
.map(Into::into)
|
|
530
|
+
.unwrap_or_else(|e| {
|
|
531
|
+
dbg_panic!("Failed to initialize metric, will drop values: {e:?}");
|
|
532
|
+
Arc::new(NoOpInstrument) as Arc<dyn GaugeF64Base>
|
|
533
|
+
})
|
|
534
|
+
});
|
|
535
|
+
bound.records(value);
|
|
536
|
+
}
|
|
201
537
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
538
|
+
impl MetricAttributable<GaugeF64> for GaugeF64 {
|
|
539
|
+
fn with_attributes(
|
|
540
|
+
&self,
|
|
541
|
+
attributes: &MetricAttributes,
|
|
542
|
+
) -> Result<GaugeF64, Box<dyn std::error::Error>> {
|
|
543
|
+
Ok(Self {
|
|
544
|
+
metric: self.metric.clone(),
|
|
545
|
+
attributes: attributes.clone(),
|
|
546
|
+
bound_cache: OnceLock::new(),
|
|
547
|
+
})
|
|
548
|
+
}
|
|
205
549
|
}
|
|
206
550
|
|
|
207
551
|
#[derive(Debug, Clone)]
|
|
@@ -297,50 +641,65 @@ impl CoreMeter for NoOpCoreMeter {
|
|
|
297
641
|
existing
|
|
298
642
|
}
|
|
299
643
|
|
|
300
|
-
fn counter(&self, _: MetricParameters) ->
|
|
301
|
-
Arc::new(NoOpInstrument)
|
|
644
|
+
fn counter(&self, _: MetricParameters) -> Counter {
|
|
645
|
+
Counter::new(Arc::new(NoOpInstrument))
|
|
302
646
|
}
|
|
303
647
|
|
|
304
|
-
fn histogram(&self, _: MetricParameters) ->
|
|
305
|
-
Arc::new(NoOpInstrument)
|
|
648
|
+
fn histogram(&self, _: MetricParameters) -> Histogram {
|
|
649
|
+
Histogram::new(Arc::new(NoOpInstrument))
|
|
306
650
|
}
|
|
307
651
|
|
|
308
|
-
fn histogram_f64(&self, _: MetricParameters) ->
|
|
309
|
-
Arc::new(NoOpInstrument)
|
|
652
|
+
fn histogram_f64(&self, _: MetricParameters) -> HistogramF64 {
|
|
653
|
+
HistogramF64::new(Arc::new(NoOpInstrument))
|
|
310
654
|
}
|
|
311
655
|
|
|
312
|
-
fn histogram_duration(&self, _: MetricParameters) ->
|
|
313
|
-
Arc::new(NoOpInstrument)
|
|
656
|
+
fn histogram_duration(&self, _: MetricParameters) -> HistogramDuration {
|
|
657
|
+
HistogramDuration::new(Arc::new(NoOpInstrument))
|
|
314
658
|
}
|
|
315
659
|
|
|
316
|
-
fn gauge(&self, _: MetricParameters) ->
|
|
317
|
-
Arc::new(NoOpInstrument)
|
|
660
|
+
fn gauge(&self, _: MetricParameters) -> Gauge {
|
|
661
|
+
Gauge::new(Arc::new(NoOpInstrument))
|
|
318
662
|
}
|
|
319
663
|
|
|
320
|
-
fn gauge_f64(&self, _: MetricParameters) ->
|
|
321
|
-
Arc::new(NoOpInstrument)
|
|
664
|
+
fn gauge_f64(&self, _: MetricParameters) -> GaugeF64 {
|
|
665
|
+
GaugeF64::new(Arc::new(NoOpInstrument))
|
|
322
666
|
}
|
|
323
667
|
}
|
|
324
668
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
fn record(&self, _: Duration, _: &MetricAttributes) {}
|
|
337
|
-
}
|
|
338
|
-
impl Gauge for NoOpInstrument {
|
|
339
|
-
fn record(&self, _: u64, _: &MetricAttributes) {}
|
|
669
|
+
macro_rules! impl_metric_attributable {
|
|
670
|
+
($base_trait:ident, $rt:ty, $init:expr) => {
|
|
671
|
+
impl MetricAttributable<Box<dyn $base_trait>> for $rt {
|
|
672
|
+
fn with_attributes(
|
|
673
|
+
&self,
|
|
674
|
+
_: &MetricAttributes,
|
|
675
|
+
) -> Result<Box<dyn $base_trait>, Box<dyn std::error::Error>> {
|
|
676
|
+
Ok(Box::new($init))
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
};
|
|
340
680
|
}
|
|
341
|
-
|
|
342
|
-
|
|
681
|
+
|
|
682
|
+
pub struct NoOpInstrument;
|
|
683
|
+
macro_rules! impl_no_op {
|
|
684
|
+
($base_trait:ident, $value_type:ty) => {
|
|
685
|
+
impl_metric_attributable!($base_trait, NoOpInstrument, NoOpInstrument);
|
|
686
|
+
impl $base_trait for NoOpInstrument {
|
|
687
|
+
fn records(&self, _: $value_type) {}
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
($base_trait:ident) => {
|
|
691
|
+
impl_metric_attributable!($base_trait, NoOpInstrument, NoOpInstrument);
|
|
692
|
+
impl $base_trait for NoOpInstrument {
|
|
693
|
+
fn adds(&self, _: u64) {}
|
|
694
|
+
}
|
|
695
|
+
};
|
|
343
696
|
}
|
|
697
|
+
impl_no_op!(CounterBase);
|
|
698
|
+
impl_no_op!(HistogramBase, u64);
|
|
699
|
+
impl_no_op!(HistogramF64Base, f64);
|
|
700
|
+
impl_no_op!(HistogramDurationBase, Duration);
|
|
701
|
+
impl_no_op!(GaugeBase, u64);
|
|
702
|
+
impl_no_op!(GaugeF64Base, f64);
|
|
344
703
|
|
|
345
704
|
#[derive(Debug, Clone)]
|
|
346
705
|
pub struct NoOpAttributes;
|
|
@@ -355,6 +714,12 @@ mod otel_impls {
|
|
|
355
714
|
use super::*;
|
|
356
715
|
use opentelemetry::{KeyValue, metrics};
|
|
357
716
|
|
|
717
|
+
#[derive(Clone)]
|
|
718
|
+
struct InstrumentWithAttributes<I> {
|
|
719
|
+
inner: I,
|
|
720
|
+
attributes: MetricAttributes,
|
|
721
|
+
}
|
|
722
|
+
|
|
358
723
|
impl From<MetricKeyValue> for KeyValue {
|
|
359
724
|
fn from(kv: MetricKeyValue) -> Self {
|
|
360
725
|
KeyValue::new(kv.key, kv.value)
|
|
@@ -372,68 +737,151 @@ mod otel_impls {
|
|
|
372
737
|
}
|
|
373
738
|
}
|
|
374
739
|
|
|
375
|
-
impl
|
|
376
|
-
fn
|
|
377
|
-
|
|
378
|
-
|
|
740
|
+
impl MetricAttributable<Box<dyn CounterBase>> for metrics::Counter<u64> {
|
|
741
|
+
fn with_attributes(
|
|
742
|
+
&self,
|
|
743
|
+
attributes: &MetricAttributes,
|
|
744
|
+
) -> Result<Box<dyn CounterBase>, Box<dyn std::error::Error>> {
|
|
745
|
+
Ok(Box::new(InstrumentWithAttributes {
|
|
746
|
+
inner: self.clone(),
|
|
747
|
+
attributes: attributes.clone(),
|
|
748
|
+
}))
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
impl CounterBase for InstrumentWithAttributes<metrics::Counter<u64>> {
|
|
753
|
+
fn adds(&self, value: u64) {
|
|
754
|
+
if let MetricAttributes::OTel { kvs } = &self.attributes {
|
|
755
|
+
self.inner.add(value, kvs);
|
|
379
756
|
} else {
|
|
380
|
-
|
|
381
|
-
false,
|
|
382
|
-
"Must use OTel attributes with an OTel metric implementation"
|
|
383
|
-
);
|
|
757
|
+
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
384
758
|
}
|
|
385
759
|
}
|
|
386
760
|
}
|
|
387
761
|
|
|
388
|
-
impl
|
|
389
|
-
fn
|
|
390
|
-
|
|
391
|
-
|
|
762
|
+
impl MetricAttributable<Box<dyn GaugeBase>> for metrics::Gauge<u64> {
|
|
763
|
+
fn with_attributes(
|
|
764
|
+
&self,
|
|
765
|
+
attributes: &MetricAttributes,
|
|
766
|
+
) -> Result<Box<dyn GaugeBase>, Box<dyn std::error::Error>> {
|
|
767
|
+
Ok(Box::new(InstrumentWithAttributes {
|
|
768
|
+
inner: self.clone(),
|
|
769
|
+
attributes: attributes.clone(),
|
|
770
|
+
}))
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
impl GaugeBase for InstrumentWithAttributes<metrics::Gauge<u64>> {
|
|
775
|
+
fn records(&self, value: u64) {
|
|
776
|
+
if let MetricAttributes::OTel { kvs } = &self.attributes {
|
|
777
|
+
self.inner.record(value, kvs);
|
|
392
778
|
} else {
|
|
393
|
-
|
|
394
|
-
false,
|
|
395
|
-
"Must use OTel attributes with an OTel metric implementation"
|
|
396
|
-
);
|
|
779
|
+
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
397
780
|
}
|
|
398
781
|
}
|
|
399
782
|
}
|
|
400
783
|
|
|
401
|
-
impl
|
|
402
|
-
fn
|
|
403
|
-
|
|
404
|
-
|
|
784
|
+
impl MetricAttributable<Box<dyn GaugeF64Base>> for metrics::Gauge<f64> {
|
|
785
|
+
fn with_attributes(
|
|
786
|
+
&self,
|
|
787
|
+
attributes: &MetricAttributes,
|
|
788
|
+
) -> Result<Box<dyn GaugeF64Base>, Box<dyn std::error::Error>> {
|
|
789
|
+
Ok(Box::new(InstrumentWithAttributes {
|
|
790
|
+
inner: self.clone(),
|
|
791
|
+
attributes: attributes.clone(),
|
|
792
|
+
}))
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
impl GaugeF64Base for InstrumentWithAttributes<metrics::Gauge<f64>> {
|
|
797
|
+
fn records(&self, value: f64) {
|
|
798
|
+
if let MetricAttributes::OTel { kvs } = &self.attributes {
|
|
799
|
+
self.inner.record(value, kvs);
|
|
405
800
|
} else {
|
|
406
|
-
|
|
407
|
-
false,
|
|
408
|
-
"Must use OTel attributes with an OTel metric implementation"
|
|
409
|
-
);
|
|
801
|
+
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
410
802
|
}
|
|
411
803
|
}
|
|
412
804
|
}
|
|
413
805
|
|
|
414
|
-
impl
|
|
415
|
-
fn
|
|
416
|
-
|
|
417
|
-
|
|
806
|
+
impl MetricAttributable<Box<dyn HistogramBase>> for metrics::Histogram<u64> {
|
|
807
|
+
fn with_attributes(
|
|
808
|
+
&self,
|
|
809
|
+
attributes: &MetricAttributes,
|
|
810
|
+
) -> Result<Box<dyn HistogramBase>, Box<dyn std::error::Error>> {
|
|
811
|
+
Ok(Box::new(InstrumentWithAttributes {
|
|
812
|
+
inner: self.clone(),
|
|
813
|
+
attributes: attributes.clone(),
|
|
814
|
+
}))
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
impl HistogramBase for InstrumentWithAttributes<metrics::Histogram<u64>> {
|
|
819
|
+
fn records(&self, value: u64) {
|
|
820
|
+
if let MetricAttributes::OTel { kvs } = &self.attributes {
|
|
821
|
+
self.inner.record(value, kvs);
|
|
418
822
|
} else {
|
|
419
|
-
|
|
420
|
-
false,
|
|
421
|
-
"Must use OTel attributes with an OTel metric implementation"
|
|
422
|
-
);
|
|
823
|
+
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
423
824
|
}
|
|
424
825
|
}
|
|
425
826
|
}
|
|
426
827
|
|
|
427
|
-
impl
|
|
428
|
-
fn
|
|
429
|
-
|
|
430
|
-
|
|
828
|
+
impl MetricAttributable<Box<dyn HistogramF64Base>> for metrics::Histogram<f64> {
|
|
829
|
+
fn with_attributes(
|
|
830
|
+
&self,
|
|
831
|
+
attributes: &MetricAttributes,
|
|
832
|
+
) -> Result<Box<dyn HistogramF64Base>, Box<dyn std::error::Error>> {
|
|
833
|
+
Ok(Box::new(InstrumentWithAttributes {
|
|
834
|
+
inner: self.clone(),
|
|
835
|
+
attributes: attributes.clone(),
|
|
836
|
+
}))
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
impl HistogramF64Base for InstrumentWithAttributes<metrics::Histogram<f64>> {
|
|
841
|
+
fn records(&self, value: f64) {
|
|
842
|
+
if let MetricAttributes::OTel { kvs } = &self.attributes {
|
|
843
|
+
self.inner.record(value, kvs);
|
|
431
844
|
} else {
|
|
432
|
-
|
|
433
|
-
false,
|
|
434
|
-
"Must use OTel attributes with an OTel metric implementation"
|
|
435
|
-
);
|
|
845
|
+
dbg_panic!("Must use OTel attributes with an OTel metric implementation");
|
|
436
846
|
}
|
|
437
847
|
}
|
|
438
848
|
}
|
|
439
849
|
}
|
|
850
|
+
|
|
851
|
+
/// Maintains a mapping of metric labels->values with a defined ordering, used for Prometheus labels
|
|
852
|
+
#[derive(Debug, Clone, PartialEq, Default)]
|
|
853
|
+
pub struct OrderedPromLabelSet {
|
|
854
|
+
attributes: BTreeMap<String, MetricValue>,
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
impl OrderedPromLabelSet {
|
|
858
|
+
pub const fn new() -> Self {
|
|
859
|
+
Self {
|
|
860
|
+
attributes: BTreeMap::new(),
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
pub fn keys_ordered(&self) -> impl Iterator<Item = &str> {
|
|
864
|
+
self.attributes.keys().map(|s| s.as_str())
|
|
865
|
+
}
|
|
866
|
+
pub fn as_prom_labels(&self) -> HashMap<&str, String> {
|
|
867
|
+
let mut labels = HashMap::new();
|
|
868
|
+
for (k, v) in self.attributes.iter() {
|
|
869
|
+
labels.insert(k.as_str(), v.to_string());
|
|
870
|
+
}
|
|
871
|
+
labels
|
|
872
|
+
}
|
|
873
|
+
pub fn add_kv(&mut self, kv: MetricKeyValue) {
|
|
874
|
+
// Replace '-' with '_' per Prom naming requirements
|
|
875
|
+
self.attributes.insert(kv.key.replace('-', "_"), kv.value);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
impl From<NewAttributes> for OrderedPromLabelSet {
|
|
880
|
+
fn from(n: NewAttributes) -> Self {
|
|
881
|
+
let mut me = Self::default();
|
|
882
|
+
for kv in n.attributes {
|
|
883
|
+
me.add_kv(kv);
|
|
884
|
+
}
|
|
885
|
+
me
|
|
886
|
+
}
|
|
887
|
+
}
|