wasmcloud_tracing/
lib.rs

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    // if OTEL is not enabled, explicitly do not emit observability
37    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/// Configures observability for each type of signal
48#[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/// Configures a reqwest http client with additional certificates
74#[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}