use std::time::Duration; use crank_metrics::{ ExemplarTraceId, HttpMethod, HttpRoute, HttpStatusClass, exemplar_snapshot, record_http_request_with_exemplar, }; use metrics_util::debugging::DebuggingRecorder; #[test] fn trace_id_is_validated_and_never_becomes_an_ordinary_label() { assert!(ExemplarTraceId::parse("0123456789abcdef0123456789abcdef").is_some()); assert!(ExemplarTraceId::parse("0123456789ABCDEF0123456789ABCDEF").is_none()); assert!(ExemplarTraceId::parse("short").is_none()); let recorder = DebuggingRecorder::new(); let snapshotter = recorder.snapshotter(); metrics::with_local_recorder(&recorder, || { record_http_request_with_exemplar( HttpRoute::from_matched_path("/health"), HttpMethod::Get, HttpStatusClass::Success, Duration::ZERO, ExemplarTraceId::parse("0123456789abcdef0123456789abcdef"), ); record_http_request_with_exemplar( HttpRoute::from_matched_path("/health"), HttpMethod::Get, HttpStatusClass::Success, Duration::from_millis(10), ExemplarTraceId::parse("0123456789abcdef0123456789abcdef"), ); record_http_request_with_exemplar( HttpRoute::from_matched_path("/health"), HttpMethod::Get, HttpStatusClass::Success, Duration::from_secs(61), ExemplarTraceId::parse("0123456789abcdef0123456789abcdef"), ); record_http_request_with_exemplar( HttpRoute::from_matched_path("/health"), HttpMethod::Get, HttpStatusClass::Success, Duration::from_millis(10), None, ); }); let aggregate = snapshotter.snapshot().into_vec(); assert!( aggregate .iter() .all(|(key, _, _, _)| { key.key().labels().all(|label| label.key() != "trace_id") }) ); let exemplars = exemplar_snapshot(); assert_eq!(exemplars.len(), 3); assert!( exemplars .iter() .all(|exemplar| exemplar.trace_id.as_str() == "0123456789abcdef0123456789abcdef") ); let bounds = exemplars .iter() .map(|exemplar| exemplar.bucket_upper_bound) .collect::>(); assert!(bounds.contains(&Some(0.005))); assert!(bounds.contains(&Some(0.01))); assert!(bounds.contains(&None)); }