1use std::path::Path;
2
3#[cfg(feature = "otel")]
4use heck::ToKebabCase;
5#[cfg(feature = "otel")]
6pub use opentelemetry::{
7 global,
8 metrics::{Counter, Gauge, Histogram, Meter, ObservableGauge, UpDownCounter},
9 InstrumentationScope, KeyValue,
10};
11use wasmcloud_core::logging::Level;
12#[cfg(feature = "otel")]
13use wasmcloud_core::tls;
14use wasmcloud_core::OtelConfig;
15
16#[cfg(feature = "otel")]
17pub mod context;
18#[cfg(feature = "otel")]
19pub mod http;
20
21mod traces;
22
23#[cfg(feature = "otel")]
24pub use traces::FlushGuard;
25
26mod metrics;
27
28#[cfg(not(feature = "otel"))]
29pub fn configure_observability(
30 _: &str,
31 _: &OtelConfig,
32 use_structured_logging: bool,
33 flame_graph: Option<impl AsRef<Path>>,
34 log_level_override: Option<&Level>,
35) -> anyhow::Result<(tracing::Dispatch, traces::FlushGuard)> {
36 let otel_config = OtelConfig::default();
38 traces::configure_tracing(
39 "",
40 &otel_config,
41 use_structured_logging,
42 flame_graph,
43 log_level_override,
44 )
45}
46
47#[cfg(feature = "otel")]
49pub fn configure_observability(
50 service_name: &str,
51 otel_config: &OtelConfig,
52 use_structured_logging: bool,
53 flame_graph: Option<impl AsRef<Path>>,
54 log_level_override: Option<&Level>,
55 trace_level_override: Option<&Level>,
56) -> anyhow::Result<(tracing::Dispatch, traces::FlushGuard)> {
57 let normalized_service_name = service_name.to_kebab_case();
58
59 if otel_config.metrics_enabled() {
60 metrics::configure_metrics(&normalized_service_name, otel_config)?;
61 }
62
63 traces::configure_tracing(
64 &normalized_service_name,
65 otel_config,
66 use_structured_logging,
67 flame_graph,
68 log_level_override,
69 trace_level_override,
70 )
71}
72
73#[cfg(feature = "otel")]
75pub(crate) fn get_http_client(otel_config: &OtelConfig) -> anyhow::Result<reqwest::Client> {
76 let mut certs = tls::NATIVE_ROOTS.to_vec();
77 if !otel_config.additional_ca_paths.is_empty() {
78 let additional_certs =
79 wasmcloud_core::tls::load_certs_from_paths(&otel_config.additional_ca_paths)
80 .unwrap_or_default();
81 certs.extend(additional_certs);
82 }
83
84 let builder = certs
85 .iter()
86 .filter_map(|cert| reqwest::tls::Certificate::from_der(cert.as_ref()).ok())
87 .fold(reqwest::ClientBuilder::default(), |builder, cert| {
88 builder.add_root_certificate(cert)
89 });
90
91 Ok(builder
92 .user_agent(tls::REQWEST_USER_AGENT)
93 .build()
94 .expect("failed to build HTTP client"))
95}