rs_zero/observability/
otlp.rs1use std::{collections::BTreeMap, time::Duration};
2
3use crate::observability::{ObservabilityError, ObservabilityResult};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum OtlpProtocol {
8 Grpc,
10 HttpProtobuf,
12}
13
14#[derive(Debug, Clone, PartialEq)]
16pub struct OtlpTraceConfig {
17 pub endpoint: String,
19 pub protocol: OtlpProtocol,
21 pub headers: BTreeMap<String, String>,
23 pub resource: BTreeMap<String, String>,
25 pub sampling_ratio: f64,
27 pub timeout: Duration,
29}
30
31impl Default for OtlpTraceConfig {
32 fn default() -> Self {
33 Self {
34 endpoint: "http://127.0.0.1:4317".to_string(),
35 protocol: OtlpProtocol::Grpc,
36 headers: BTreeMap::new(),
37 resource: BTreeMap::new(),
38 sampling_ratio: 1.0,
39 timeout: Duration::from_secs(5),
40 }
41 }
42}
43
44#[derive(Debug, Clone, Default)]
46pub struct TraceShutdownHandle {
47 installed: bool,
48}
49
50impl TraceShutdownHandle {
51 pub fn installed() -> Self {
53 Self { installed: true }
54 }
55
56 pub fn is_installed(&self) -> bool {
58 self.installed
59 }
60
61 pub fn flush(&self) -> ObservabilityResult<()> {
63 Ok(())
64 }
65
66 pub fn shutdown(self) -> ObservabilityResult<()> {
68 Ok(())
69 }
70}
71
72pub fn build_otlp_trace_config(config: OtlpTraceConfig) -> ObservabilityResult<OtlpTraceConfig> {
74 if config.endpoint.trim().is_empty() {
75 return Err(ObservabilityError::MissingOtlpEndpoint);
76 }
77 Ok(config)
78}
79
80#[cfg(test)]
81mod tests {
82 use super::{OtlpTraceConfig, TraceShutdownHandle, build_otlp_trace_config};
83 use crate::observability::ObservabilityError;
84
85 #[test]
86 fn otlp_config_requires_endpoint() {
87 let error = build_otlp_trace_config(OtlpTraceConfig {
88 endpoint: String::new(),
89 ..OtlpTraceConfig::default()
90 })
91 .expect_err("endpoint");
92 assert_eq!(error, ObservabilityError::MissingOtlpEndpoint);
93 }
94
95 #[test]
96 fn shutdown_handle_flushes_without_collector() {
97 let handle = TraceShutdownHandle::installed();
98 assert!(handle.is_installed());
99 handle.flush().expect("flush");
100 handle.shutdown().expect("shutdown");
101 }
102}