init_tracing_opentelemetry/
resource.rs1use opentelemetry::KeyValue;
2use opentelemetry_sdk::{resource::ResourceDetector, Resource};
4use opentelemetry_semantic_conventions::resource;
5
6#[derive(Debug, Default)]
18pub struct DetectResource {
19 fallback_service_name: Option<&'static str>,
20 fallback_service_version: Option<&'static str>,
21}
22
23impl DetectResource {
24 #[must_use]
28 pub fn with_fallback_service_name(mut self, fallback_service_name: &'static str) -> Self {
29 self.fallback_service_name = Some(fallback_service_name);
30 self
31 }
32
33 #[must_use]
37 pub fn with_fallback_service_version(mut self, fallback_service_version: &'static str) -> Self {
38 self.fallback_service_version = Some(fallback_service_version);
39 self
40 }
41
42 #[must_use]
43 pub fn build(mut self) -> Resource {
44 let rsrc = Resource::builder()
47 .with_detector(Box::new(ServiceInfoDetector {
48 fallback_service_name: self.fallback_service_name.take(),
49 fallback_service_version: self.fallback_service_version.take(),
50 }))
51 .build();
52 debug_resource(&rsrc);
53 rsrc
54 }
55}
56
57pub fn debug_resource(rsrc: &Resource) {
58 rsrc.iter().for_each(
59 |kv| tracing::debug!(target: "otel::setup::resource", key = %kv.0, value = %kv.1),
60 );
61}
62
63#[derive(Debug)]
64pub struct ServiceInfoDetector {
65 fallback_service_name: Option<&'static str>,
66 fallback_service_version: Option<&'static str>,
67}
68
69impl ResourceDetector for ServiceInfoDetector {
70 fn detect(&self) -> Resource {
71 let service_name = std::env::var("OTEL_SERVICE_NAME")
72 .or_else(|_| std::env::var("SERVICE_NAME"))
73 .or_else(|_| std::env::var("APP_NAME"))
74 .ok()
75 .or_else(|| {
76 self.fallback_service_name
77 .map(std::string::ToString::to_string)
78 })
79 .map(|v| KeyValue::new(resource::SERVICE_NAME, v));
80 let service_version = std::env::var("SERVICE_VERSION")
81 .or_else(|_| std::env::var("APP_VERSION"))
82 .ok()
83 .or_else(|| {
84 self.fallback_service_version
85 .map(std::string::ToString::to_string)
86 })
87 .map(|v| KeyValue::new(resource::SERVICE_VERSION, v));
88 let mut resource = Resource::builder_empty();
89 if let Some(service_name) = service_name {
90 resource = resource.with_attribute(service_name);
91 }
92 if let Some(service_version) = service_version {
93 resource = resource.with_attribute(service_version);
94 }
95 resource.build()
96 }
97}