From ba3ffb92502f9da555224d881cb9393875a9a761 Mon Sep 17 00:00:00 2001 From: Caleb Schoepp Date: Fri, 22 Mar 2024 12:22:48 -0600 Subject: [PATCH 01/10] feat(wasi-observe): A WASI Observe host component Signed-off-by: Caleb Schoepp --- Cargo.toml | 1 + crates/factor-key-value/Cargo.toml | 1 + crates/factor-key-value/src/host.rs | 24 +- crates/factor-key-value/src/lib.rs | 8 +- crates/factor-llm/Cargo.toml | 1 + crates/factor-llm/src/host.rs | 4 + crates/factor-llm/src/lib.rs | 6 +- crates/factor-otel/Cargo.toml | 25 + crates/factor-otel/src/host.rs | 58 ++ crates/factor-otel/src/lib.rs | 203 +++++++ crates/factor-outbound-http/Cargo.toml | 1 + crates/factor-outbound-http/src/lib.rs | 4 + crates/factor-outbound-http/src/spin.rs | 2 + crates/factor-outbound-http/src/wasi.rs | 2 + crates/factor-outbound-mqtt/Cargo.toml | 1 + crates/factor-outbound-mqtt/src/host.rs | 12 +- crates/factor-outbound-mqtt/src/lib.rs | 4 + crates/factor-outbound-mysql/Cargo.toml | 1 + crates/factor-outbound-mysql/src/host.rs | 3 + crates/factor-outbound-mysql/src/lib.rs | 7 + crates/factor-outbound-pg/Cargo.toml | 1 + crates/factor-outbound-pg/src/host.rs | 4 + crates/factor-outbound-pg/src/lib.rs | 6 + crates/factor-outbound-redis/Cargo.toml | 1 + crates/factor-outbound-redis/src/host.rs | 24 +- crates/factor-outbound-redis/src/lib.rs | 4 + crates/factor-sqlite/Cargo.toml | 1 + crates/factor-sqlite/src/host.rs | 6 + crates/factor-sqlite/src/lib.rs | 6 +- crates/factor-variables/Cargo.toml | 1 + crates/factor-variables/src/host.rs | 1 + crates/factor-variables/src/lib.rs | 6 +- crates/runtime-config/Cargo.toml | 1 + crates/runtime-config/src/lib.rs | 7 + crates/runtime-factors/Cargo.toml | 1 + crates/runtime-factors/src/lib.rs | 3 + crates/telemetry/src/env.rs | 18 +- crates/telemetry/src/lib.rs | 12 +- crates/trigger-http/Cargo.toml | 1 + crates/world/Cargo.toml | 3 + crates/world/src/conversions.rs | 216 +++++++ tests/integration.rs | 437 +++++++++++++- tests/test-components/components/Cargo.lock | 560 +++++++++++++++++- .../components/otel-smoke-test/Cargo.toml | 12 + .../components/otel-smoke-test/src/lib.rs | 22 + .../components/wasi-otel-tracing/Cargo.toml | 16 + .../components/wasi-otel-tracing/src/lib.rs | 130 ++++ tests/testcases/otel-smoke-test/spin.toml | 11 +- tests/testcases/wasi-otel-tracing/spin.toml | 19 + wit/deps/otel/tracing.wit | 168 ++++++ wit/deps/otel/world.wit | 5 + wit/world.wit | 1 + 52 files changed, 2036 insertions(+), 36 deletions(-) create mode 100644 crates/factor-otel/Cargo.toml create mode 100644 crates/factor-otel/src/host.rs create mode 100644 crates/factor-otel/src/lib.rs create mode 100644 tests/test-components/components/otel-smoke-test/Cargo.toml create mode 100644 tests/test-components/components/otel-smoke-test/src/lib.rs create mode 100644 tests/test-components/components/wasi-otel-tracing/Cargo.toml create mode 100644 tests/test-components/components/wasi-otel-tracing/src/lib.rs create mode 100644 tests/testcases/wasi-otel-tracing/spin.toml create mode 100644 wit/deps/otel/tracing.wit create mode 100644 wit/deps/otel/world.wit diff --git a/Cargo.toml b/Cargo.toml index 01fddbe860..76bfb5fd6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,6 +83,7 @@ openssl = { version = "0.10" } anyhow = { workspace = true, features = ["backtrace"] } conformance = { path = "tests/conformance-tests" } conformance-tests = { workspace = true } +fake-opentelemetry-collector = "0.21.1" hex = "0.4" http-body-util = { workspace = true } hyper = { workspace = true } diff --git a/crates/factor-key-value/Cargo.toml b/crates/factor-key-value/Cargo.toml index 8327737bd1..f0bdd6a2b9 100644 --- a/crates/factor-key-value/Cargo.toml +++ b/crates/factor-key-value/Cargo.toml @@ -8,6 +8,7 @@ edition = { workspace = true } anyhow = { workspace = true } serde = { workspace = true } spin-core = { path = "../core" } +spin-factor-otel = { path = "../factor-otel" } spin-factors = { path = "../factors" } spin-locked-app = { path = "../locked-app" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-key-value/src/host.rs b/crates/factor-key-value/src/host.rs index ada4ece9b2..a7aef7005c 100644 --- a/crates/factor-key-value/src/host.rs +++ b/crates/factor-key-value/src/host.rs @@ -1,6 +1,7 @@ use super::{Cas, SwapError}; use anyhow::{Context, Result}; use spin_core::{async_trait, wasmtime::component::Resource}; +use spin_factor_otel::OtelContext; use spin_resource_table::Table; use spin_telemetry::traces::{self, Blame}; use spin_world::v2::key_value; @@ -49,23 +50,26 @@ pub struct KeyValueDispatch { manager: Arc, stores: Table>, compare_and_swaps: Table>, + otel_context: Option, } impl KeyValueDispatch { pub fn new(allowed_stores: HashSet, manager: Arc) -> Self { - Self::new_with_capacity(allowed_stores, manager, DEFAULT_STORE_TABLE_CAPACITY) + Self::new_with_capacity(allowed_stores, manager, DEFAULT_STORE_TABLE_CAPACITY, None) } pub fn new_with_capacity( allowed_stores: HashSet, manager: Arc, capacity: u32, + otel_context: Option, ) -> Self { Self { allowed_stores, manager, stores: Table::new(capacity), compare_and_swaps: Table::new(capacity), + otel_context, } } @@ -113,6 +117,9 @@ impl key_value::Host for KeyValueDispatch {} impl key_value::HostStore for KeyValueDispatch { #[instrument(name = "spin_key_value.open", skip(self), err, fields(otel.kind = "client", kv.backend=self.manager.summary(&name).unwrap_or("unknown".to_string())))] async fn open(&mut self, name: String) -> Result, Error>> { + if let Some(otel_context) = self.otel_context.as_ref() { + otel_context.reparent_tracing_span() + } Ok(async { if self.allowed_stores.contains(&name) { let store = self.manager.get(&name).await?; @@ -135,6 +142,9 @@ impl key_value::HostStore for KeyValueDispatch { store: Resource, key: String, ) -> Result>, Error>> { + if let Some(otel_context) = self.otel_context.as_ref() { + otel_context.reparent_tracing_span() + } let store = self.get_store(store)?; Ok(store.get(&key).await.map_err(track_error_on_span)) } @@ -146,6 +156,9 @@ impl key_value::HostStore for KeyValueDispatch { key: String, value: Vec, ) -> Result> { + if let Some(otel_context) = self.otel_context.as_ref() { + otel_context.reparent_tracing_span() + } let store = self.get_store(store)?; Ok(store.set(&key, &value).await.map_err(track_error_on_span)) } @@ -156,6 +169,9 @@ impl key_value::HostStore for KeyValueDispatch { store: Resource, key: String, ) -> Result> { + if let Some(otel_context) = self.otel_context.as_ref() { + otel_context.reparent_tracing_span() + } let store = self.get_store(store)?; Ok(store.delete(&key).await.map_err(track_error_on_span)) } @@ -166,6 +182,9 @@ impl key_value::HostStore for KeyValueDispatch { store: Resource, key: String, ) -> Result> { + if let Some(otel_context) = self.otel_context.as_ref() { + otel_context.reparent_tracing_span() + } let store = self.get_store(store)?; Ok(store.exists(&key).await.map_err(track_error_on_span)) } @@ -175,6 +194,9 @@ impl key_value::HostStore for KeyValueDispatch { &mut self, store: Resource, ) -> Result, Error>> { + if let Some(otel_context) = self.otel_context.as_ref() { + otel_context.reparent_tracing_span() + } let store = self.get_store(store)?; Ok(store.get_keys().await.map_err(track_error_on_span)) } diff --git a/crates/factor-key-value/src/lib.rs b/crates/factor-key-value/src/lib.rs index 792ea18b92..62929a75ff 100644 --- a/crates/factor-key-value/src/lib.rs +++ b/crates/factor-key-value/src/lib.rs @@ -8,6 +8,7 @@ use std::{ }; use anyhow::ensure; +use spin_factor_otel::OtelContext; use spin_factors::{ ConfigureAppContext, Factor, FactorData, FactorInstanceBuilder, InitContext, PrepareContext, RuntimeFactors, @@ -87,7 +88,7 @@ impl Factor for KeyValueFactor { fn prepare( &self, - ctx: PrepareContext, + mut ctx: PrepareContext, ) -> anyhow::Result { let app_state = ctx.app_state(); let allowed_stores = app_state @@ -95,9 +96,11 @@ impl Factor for KeyValueFactor { .get(ctx.app_component().id()) .expect("component should be in component_stores") .clone(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; Ok(InstanceBuilder { store_manager: app_state.store_manager.clone(), allowed_stores, + otel_context, }) } } @@ -177,6 +180,7 @@ pub struct InstanceBuilder { store_manager: Arc, /// The allowed stores for this component instance. allowed_stores: HashSet, + otel_context: OtelContext, } impl FactorInstanceBuilder for InstanceBuilder { @@ -186,11 +190,13 @@ impl FactorInstanceBuilder for InstanceBuilder { let Self { store_manager, allowed_stores, + otel_context, } = self; Ok(KeyValueDispatch::new_with_capacity( allowed_stores, store_manager, u32::MAX, + Some(otel_context), )) } } diff --git a/crates/factor-llm/Cargo.toml b/crates/factor-llm/Cargo.toml index c43a7bbd6c..61121c6a49 100644 --- a/crates/factor-llm/Cargo.toml +++ b/crates/factor-llm/Cargo.toml @@ -17,6 +17,7 @@ llm-cublas = ["llm", "spin-llm-local/cublas"] anyhow = { workspace = true } async-trait = { workspace = true } serde = { workspace = true } +spin-factor-otel = { path = "../factor-otel" } spin-factors = { path = "../factors" } spin-llm-local = { path = "../llm-local", optional = true } spin-llm-remote-http = { path = "../llm-remote-http" } diff --git a/crates/factor-llm/src/host.rs b/crates/factor-llm/src/host.rs index 63a5525146..61c49b5313 100644 --- a/crates/factor-llm/src/host.rs +++ b/crates/factor-llm/src/host.rs @@ -13,6 +13,8 @@ impl v2::Host for InstanceState { prompt: String, params: Option, ) -> Result { + self.otel_context.reparent_tracing_span(); + if !self.allowed_models.contains(&model) { return Err(access_denied_error(&model)); } @@ -40,6 +42,8 @@ impl v2::Host for InstanceState { model: v1::EmbeddingModel, data: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); + if !self.allowed_models.contains(&model) { return Err(access_denied_error(&model)); } diff --git a/crates/factor-llm/src/lib.rs b/crates/factor-llm/src/lib.rs index 4f43feac68..b3e5c6a700 100644 --- a/crates/factor-llm/src/lib.rs +++ b/crates/factor-llm/src/lib.rs @@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use async_trait::async_trait; +use spin_factor_otel::OtelContext; use spin_factors::{ ConfigureAppContext, Factor, FactorData, PrepareContext, RuntimeFactors, SelfInstanceBuilder, }; @@ -73,7 +74,7 @@ impl Factor for LlmFactor { fn prepare( &self, - ctx: PrepareContext, + mut ctx: PrepareContext, ) -> anyhow::Result { let allowed_models = ctx .app_state() @@ -82,10 +83,12 @@ impl Factor for LlmFactor { .cloned() .unwrap_or_default(); let engine = ctx.app_state().engine.clone(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; Ok(InstanceState { engine, allowed_models, + otel_context, }) } } @@ -100,6 +103,7 @@ pub struct AppState { pub struct InstanceState { engine: Arc>, pub allowed_models: Arc>, + otel_context: OtelContext, } /// The runtime configuration for the LLM factor. diff --git a/crates/factor-otel/Cargo.toml b/crates/factor-otel/Cargo.toml new file mode 100644 index 0000000000..22df37e1a4 --- /dev/null +++ b/crates/factor-otel/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "spin-factor-otel" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } + +[dependencies] +anyhow = { workspace = true } +indexmap = "2.2.6" +opentelemetry = { workspace = true } +opentelemetry_sdk = { workspace = true } +opentelemetry-otlp = { version = "0.27", features = ["http-proto", "http", "reqwest-client"] } +spin-core = { path = "../core" } +spin-factors = { path = "../factors" } +spin-resource-table = { path = "../table" } +spin-telemetry = { path = "../telemetry" } +spin-world = { path = "../world" } +tracing = { workspace = true } +tracing-opentelemetry = { workspace = true } + +[dev-dependencies] +toml = "0.5" + +[lints] +workspace = true diff --git a/crates/factor-otel/src/host.rs b/crates/factor-otel/src/host.rs new file mode 100644 index 0000000000..12513ab9e2 --- /dev/null +++ b/crates/factor-otel/src/host.rs @@ -0,0 +1,58 @@ +use anyhow::anyhow; +use anyhow::Result; +use opentelemetry::trace::TraceContextExt; +use opentelemetry_sdk::trace::SpanProcessor; +use spin_world::wasi::otel::tracing as wasi_otel; + +use tracing_opentelemetry::OpenTelemetrySpanExt; + +use crate::InstanceState; + +impl wasi_otel::Host for InstanceState { + async fn on_start(&mut self, context: wasi_otel::SpanContext) -> Result<()> { + let mut state = self.state.write().unwrap(); + + // Before we do anything make sure we track the original host span ID for reparenting + if state.original_host_span_id.is_none() { + state.original_host_span_id = Some( + tracing::Span::current() + .context() + .span() + .span_context() + .span_id(), + ); + } + + // Track the guest spans context in our ordered map + let span_context: opentelemetry::trace::SpanContext = context.into(); + state + .guest_span_contexts + .insert(span_context.span_id(), span_context); + + Ok(()) + } + + async fn on_end(&mut self, span_data: wasi_otel::SpanData) -> Result<()> { + let mut state = self.state.write().unwrap(); + + let span_context: opentelemetry::trace::SpanContext = span_data.span_context.clone().into(); + let span_id: opentelemetry::trace::SpanId = span_context.span_id(); + + if state.guest_span_contexts.shift_remove(&span_id).is_none() { + Err(anyhow!("Trying to end a span that was not started"))?; + } + + self.processor.on_end(span_data.into()); + + Ok(()) + } + + async fn outer_span_context(&mut self) -> Result { + Ok(tracing::Span::current() + .context() + .span() + .span_context() + .clone() + .into()) + } +} diff --git a/crates/factor-otel/src/lib.rs b/crates/factor-otel/src/lib.rs new file mode 100644 index 0000000000..4f36da6125 --- /dev/null +++ b/crates/factor-otel/src/lib.rs @@ -0,0 +1,203 @@ +mod host; + +use std::{ + sync::{Arc, RwLock}, + time::Duration, +}; + +use anyhow::bail; +use indexmap::IndexMap; +use opentelemetry::{ + trace::{SpanContext, SpanId, TraceContextExt}, + Context, +}; +use opentelemetry_sdk::{ + resource::{EnvResourceDetector, TelemetryResourceDetector}, + runtime::Tokio, + trace::{BatchSpanProcessor, SpanProcessor}, + Resource, +}; +use spin_factors::{Factor, PrepareContext, RuntimeFactors, SelfInstanceBuilder}; +use spin_telemetry::{detector::SpinResourceDetector, env::OtlpProtocol}; +use tracing_opentelemetry::OpenTelemetrySpanExt; + +pub struct OtelFactor { + processor: Arc>, +} + +impl Factor for OtelFactor { + type RuntimeConfig = (); + type AppState = (); + type InstanceBuilder = InstanceState; + + fn init( + &mut self, + mut ctx: spin_factors::InitContext, + ) -> anyhow::Result<()> { + ctx.link_bindings(spin_world::wasi::otel::tracing::add_to_linker)?; + Ok(()) + } + + fn configure_app( + &self, + _ctx: spin_factors::ConfigureAppContext, + ) -> anyhow::Result { + Ok(()) + } + + fn prepare( + &self, + _: spin_factors::PrepareContext, + ) -> anyhow::Result { + Ok(InstanceState { + state: Arc::new(RwLock::new(State { + guest_span_contexts: Default::default(), + original_host_span_id: None, + })), + processor: self.processor.clone(), + }) + } +} + +impl OtelFactor { + pub fn new() -> anyhow::Result { + // This will configure the exporter based on the OTEL_EXPORTER_* environment variables. + let exporter = match OtlpProtocol::traces_protocol_from_env() { + OtlpProtocol::Grpc => opentelemetry_otlp::SpanExporter::builder() + .with_tonic() + .build()?, + OtlpProtocol::HttpProtobuf => opentelemetry_otlp::SpanExporter::builder() + .with_http() + .build()?, + OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"), + }; + let mut processor = opentelemetry_sdk::trace::BatchSpanProcessor::builder( + exporter, + opentelemetry_sdk::runtime::Tokio, + ) + .build(); + // This is a hack b/c we know the version of this crate will be the same as the version of Spin + let spin_version = env!("CARGO_PKG_VERSION").to_string(); + processor.set_resource(&Resource::from_detectors( + Duration::from_secs(5), + vec![ + // Set service.name from env OTEL_SERVICE_NAME > env OTEL_RESOURCE_ATTRIBUTES > spin + // Set service.version from Spin metadata + Box::new(SpinResourceDetector::new(spin_version)), + // Sets fields from env OTEL_RESOURCE_ATTRIBUTES + Box::new(EnvResourceDetector::new()), + // Sets telemetry.sdk{name, language, version} + Box::new(TelemetryResourceDetector), + ], + )); + Ok(Self { + processor: Arc::new(processor), + }) + } +} + +pub struct InstanceState { + pub(crate) state: Arc>, + pub(crate) processor: Arc>, +} + +impl SelfInstanceBuilder for InstanceState {} + +/// Internal state of the OtelFactor instance state. +/// +/// This data lives here rather than directly on InstanceState so that we can have multiple things +/// take Arc references to it. +pub(crate) struct State { + /// An order-preserved mapping between immutable [SpanId]s of guest created spans and their + /// corresponding [SpanContext]. + /// + /// The topmost [SpanId] is the last active span. When a span is ended it is removed from this + /// map (regardless of whether it is the active span) and all other spans are shifted back to + /// retain relative order. + pub(crate) guest_span_contexts: IndexMap, + + /// Id of the last span emitted from within the host before entering the guest. + /// + /// We use this to avoid accidentally reparenting the original host span as a child of a guest + /// span. + pub(crate) original_host_span_id: Option, +} + +/// Manages access to the OtelFactor state for the purpose of maintaining proper span +/// parent/child relationships when WASI Otel spans are being created. +pub struct OtelContext { + pub(crate) state: Option>>, +} + +impl OtelContext { + /// Creates an [`OtelContext`] from a [`PrepareContext`]. + /// + /// If [`RuntimeFactors`] does not contain an [`OtelFactor`], then calling + /// [`OtelContext::reparent_tracing_span`] will be a no-op. + pub fn from_prepare_context( + prepare_context: &mut PrepareContext, + ) -> anyhow::Result { + let state = match prepare_context.instance_builder::() { + Ok(instance_state) => Some(instance_state.state.clone()), + Err(spin_factors::Error::NoSuchFactor(_)) => None, + Err(e) => return Err(e.into()), + }; + Ok(Self { state }) + } + + /// Reparents the current [tracing] span to be a child of the last active guest span. + /// + /// The otel factor enables guests to emit spans that should be part of the same trace as the + /// host is producing for a request. Below is an example trace. A request is made to an app, a + /// guest span is created and then the host is re-entered to fetch a key value. + /// + /// ```text + /// | GET /... _________________________________| + /// | execute_wasm_component foo ___________| + /// | my_guest_span ___________________| + /// | spin_key_value.get | + /// ``` + /// + /// Setting the guest spans parent as the host is enabled through current_span_context. + /// However, the more difficult task is having the host factor spans be children of the guest + /// span. [`OtelContext::reparent_tracing_span`] handles this by reparenting the current span to + /// be a child of the last active guest span (which is tracked internally in the otel factor). + /// + /// Note that if the otel factor is not in your [`RuntimeFactors`] than this is effectively a + /// no-op. + /// + /// This MUST only be called from a factor host implementation function that is instrumented. + /// + /// This MUST be called at the very start of the function before any awaits. + pub fn reparent_tracing_span(&self) { + // If state is None then we want to return early b/c the factor doesn't depend on the + // Otel factor and therefore there is nothing to do + let state = if let Some(state) = self.state.as_ref() { + state.read().unwrap() + } else { + return; + }; + + // If there are no active guest spans then there is nothing to do + let Some((_, active_span_context)) = state.guest_span_contexts.last() else { + return; + }; + + // Ensure that we are not reparenting the original host span + if let Some(original_host_span_id) = state.original_host_span_id { + if tracing::Span::current() + .context() + .span() + .span_context() + .span_id() + .eq(&original_host_span_id) + { + panic!("Incorrectly attempting to reparent the original host span. Likely `reparent_tracing_span` was called in an incorrect location.") + } + } + + // Now reparent the current span to the last active guest span + let parent_context = Context::new().with_remote_span_context(active_span_context.clone()); + tracing::Span::current().set_parent(parent_context); + } +} diff --git a/crates/factor-outbound-http/Cargo.toml b/crates/factor-outbound-http/Cargo.toml index 2dba3e9f13..23da53694c 100644 --- a/crates/factor-outbound-http/Cargo.toml +++ b/crates/factor-outbound-http/Cargo.toml @@ -14,6 +14,7 @@ hyper-util = { workspace = true } reqwest = { workspace = true, features = ["gzip"] } rustls = { workspace = true } serde = { workspace = true } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-networking = { path = "../factor-outbound-networking" } spin-factors = { path = "../factors" } spin-telemetry = { path = "../telemetry" } diff --git a/crates/factor-outbound-http/src/lib.rs b/crates/factor-outbound-http/src/lib.rs index 4fc368de55..600fd38ff0 100644 --- a/crates/factor-outbound-http/src/lib.rs +++ b/crates/factor-outbound-http/src/lib.rs @@ -14,6 +14,7 @@ use http::{ }; use intercept::OutboundHttpInterceptor; use runtime_config::RuntimeConfig; +use spin_factor_otel::OtelContext; use spin_factor_outbound_networking::{ config::{allowed_hosts::OutboundAllowedHosts, blocked_networks::BlockedNetworks}, ComponentTlsClientConfigs, OutboundNetworkingFactor, @@ -68,6 +69,7 @@ impl Factor for OutboundHttpFactor { let allowed_hosts = outbound_networking.allowed_hosts(); let blocked_networks = outbound_networking.blocked_networks(); let component_tls_configs = outbound_networking.component_tls_configs(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; Ok(InstanceState { wasi_http_ctx: WasiHttpCtx::new(), allowed_hosts, @@ -78,6 +80,7 @@ impl Factor for OutboundHttpFactor { spin_http_client: None, wasi_http_clients: ctx.app_state().wasi_http_clients.clone(), connection_pooling: ctx.app_state().connection_pooling, + otel_context, }) } } @@ -101,6 +104,7 @@ pub struct InstanceState { // among all instances of the app. wasi_http_clients: wasi::HttpClients, connection_pooling: bool, + otel_context: OtelContext, } impl InstanceState { diff --git a/crates/factor-outbound-http/src/spin.rs b/crates/factor-outbound-http/src/spin.rs index 2f8fc428fa..d7ec8f3275 100644 --- a/crates/factor-outbound-http/src/spin.rs +++ b/crates/factor-outbound-http/src/spin.rs @@ -12,6 +12,8 @@ impl spin_http::Host for crate::InstanceState { fields(otel.kind = "client", url.full = Empty, http.request.method = Empty, http.response.status_code = Empty, otel.name = Empty, server.address = Empty, server.port = Empty))] async fn send_request(&mut self, req: Request) -> Result { + self.otel_context.reparent_tracing_span(); + let span = Span::current(); record_request_fields(&span, &req); diff --git a/crates/factor-outbound-http/src/wasi.rs b/crates/factor-outbound-http/src/wasi.rs index c141be76b5..5413e803ea 100644 --- a/crates/factor-outbound-http/src/wasi.rs +++ b/crates/factor-outbound-http/src/wasi.rs @@ -149,6 +149,8 @@ impl WasiHttpView for WasiHttpImplInner<'_> { request: Request, config: wasmtime_wasi_http::types::OutgoingRequestConfig, ) -> wasmtime_wasi_http::HttpResult { + self.state.otel_context.reparent_tracing_span(); + Ok(HostFutureIncomingResponse::Pending( wasmtime_wasi::runtime::spawn( send_request_impl( diff --git a/crates/factor-outbound-mqtt/Cargo.toml b/crates/factor-outbound-mqtt/Cargo.toml index bd5222881c..962b5efb0a 100644 --- a/crates/factor-outbound-mqtt/Cargo.toml +++ b/crates/factor-outbound-mqtt/Cargo.toml @@ -8,6 +8,7 @@ edition = { workspace = true } anyhow = { workspace = true } rumqttc = { version = "0.24", features = ["url"] } spin-core = { path = "../core" } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-networking = { path = "../factor-outbound-networking" } spin-factors = { path = "../factors" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-outbound-mqtt/src/host.rs b/crates/factor-outbound-mqtt/src/host.rs index 28ca42885d..6fb17182f2 100644 --- a/crates/factor-outbound-mqtt/src/host.rs +++ b/crates/factor-outbound-mqtt/src/host.rs @@ -12,14 +12,20 @@ pub struct InstanceState { allowed_hosts: OutboundAllowedHosts, connections: spin_resource_table::Table>, create_client: Arc, + otel_context: OtelContext, } impl InstanceState { - pub fn new(allowed_hosts: OutboundAllowedHosts, create_client: Arc) -> Self { + pub fn new( + allowed_hosts: OutboundAllowedHosts, + create_client: Arc, + otel_context: OtelContext, + ) -> Self { Self { allowed_hosts, create_client, connections: spin_resource_table::Table::new(1024), + otel_context, } } } @@ -72,6 +78,8 @@ impl v2::HostConnection for InstanceState { password: String, keep_alive_interval: u64, ) -> Result, Error> { + self.otel_context.reparent_tracing_span(); + if !self .is_address_allowed(&address) .await @@ -105,6 +113,8 @@ impl v2::HostConnection for InstanceState { payload: Vec, qos: Qos, ) -> Result<(), Error> { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; conn.publish_bytes(topic, qos, payload).await?; diff --git a/crates/factor-outbound-mqtt/src/lib.rs b/crates/factor-outbound-mqtt/src/lib.rs index a5de2696b9..250aa09d5c 100644 --- a/crates/factor-outbound-mqtt/src/lib.rs +++ b/crates/factor-outbound-mqtt/src/lib.rs @@ -7,6 +7,7 @@ use host::other_error; use host::InstanceState; use rumqttc::{AsyncClient, Event, Incoming, Outgoing, QoS}; use spin_core::async_trait; +use spin_factor_otel::OtelContext; use spin_factor_outbound_networking::OutboundNetworkingFactor; use spin_factors::{ ConfigureAppContext, Factor, FactorData, PrepareContext, RuntimeFactors, SelfInstanceBuilder, @@ -50,9 +51,12 @@ impl Factor for OutboundMqttFactor { let allowed_hosts = ctx .instance_builder::()? .allowed_hosts(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; + Ok(InstanceState::new( allowed_hosts, self.create_client.clone(), + otel_context, )) } } diff --git a/crates/factor-outbound-mysql/Cargo.toml b/crates/factor-outbound-mysql/Cargo.toml index 4ae73f9fbc..ed6a0b01a0 100644 --- a/crates/factor-outbound-mysql/Cargo.toml +++ b/crates/factor-outbound-mysql/Cargo.toml @@ -14,6 +14,7 @@ mysql_async = { version = "0.35", default-features = false, features = [ "native-tls-tls", ] } spin-core = { path = "../core" } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-networking = { path = "../factor-outbound-networking" } spin-factors = { path = "../factors" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-outbound-mysql/src/host.rs b/crates/factor-outbound-mysql/src/host.rs index e562d4d741..ca113206aa 100644 --- a/crates/factor-outbound-mysql/src/host.rs +++ b/crates/factor-outbound-mysql/src/host.rs @@ -38,6 +38,7 @@ impl v2::Host for InstanceState {} impl v2::HostConnection for InstanceState { #[instrument(name = "spin_outbound_mysql.open", skip(self, address), err(level = Level::INFO), fields(otel.kind = "client", db.system = "mysql", db.address = Empty, server.port = Empty, db.namespace = Empty))] async fn open(&mut self, address: String) -> Result, v2::Error> { + self.otel_context.reparent_tracing_span(); spin_factor_outbound_networking::record_address_fields(&address); if !self @@ -59,6 +60,7 @@ impl v2::HostConnection for InstanceState { statement: String, params: Vec, ) -> Result<(), v2::Error> { + self.otel_context.reparent_tracing_span(); self.get_client(connection) .await? .execute(statement, params) @@ -72,6 +74,7 @@ impl v2::HostConnection for InstanceState { statement: String, params: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); self.get_client(connection) .await? .query(statement, params) diff --git a/crates/factor-outbound-mysql/src/lib.rs b/crates/factor-outbound-mysql/src/lib.rs index fbe213bf9e..0bf63805ef 100644 --- a/crates/factor-outbound-mysql/src/lib.rs +++ b/crates/factor-outbound-mysql/src/lib.rs @@ -3,10 +3,13 @@ mod host; use client::Client; use mysql_async::Conn as MysqlClient; +use spin_factor_otel::OtelContext; use spin_factor_outbound_networking::{ config::allowed_hosts::OutboundAllowedHosts, OutboundNetworkingFactor, }; +use spin_factor_outbound_networking::{OutboundAllowedHosts, OutboundNetworkingFactor}; use spin_factors::{Factor, FactorData, InitContext, RuntimeFactors, SelfInstanceBuilder}; +use spin_factors::{Factor, InitContext, RuntimeFactors, SelfInstanceBuilder}; use spin_world::v1::mysql as v1; use spin_world::v2::mysql::{self as v2}; @@ -39,9 +42,12 @@ impl Factor for OutboundMysqlFactor { let allowed_hosts = ctx .instance_builder::()? .allowed_hosts(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; + Ok(InstanceState { allowed_hosts, connections: Default::default(), + otel_context, }) } } @@ -63,6 +69,7 @@ impl OutboundMysqlFactor { pub struct InstanceState { allowed_hosts: OutboundAllowedHosts, connections: spin_resource_table::Table, + otel_context: OtelContext, } impl SelfInstanceBuilder for InstanceState {} diff --git a/crates/factor-outbound-pg/Cargo.toml b/crates/factor-outbound-pg/Cargo.toml index 6b8f32bb4c..6436d55268 100644 --- a/crates/factor-outbound-pg/Cargo.toml +++ b/crates/factor-outbound-pg/Cargo.toml @@ -16,6 +16,7 @@ postgres_range = "0.11" rust_decimal = { version = "1.37", features = ["db-tokio-postgres"] } serde_json = { workspace = true } spin-core = { path = "../core" } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-networking = { path = "../factor-outbound-networking" } spin-factors = { path = "../factors" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-outbound-pg/src/host.rs b/crates/factor-outbound-pg/src/host.rs index 111df6f998..81dda9bbe6 100644 --- a/crates/factor-outbound-pg/src/host.rs +++ b/crates/factor-outbound-pg/src/host.rs @@ -219,6 +219,7 @@ impl v2::Host for InstanceState {} impl v2::HostConnection for InstanceState { #[instrument(name = "spin_outbound_pg.open", skip(self, address), err(level = Level::INFO), fields(otel.kind = "client", db.system = "postgresql", db.address = Empty, server.port = Empty, db.namespace = Empty))] async fn open(&mut self, address: String) -> Result, v2::Error> { + self.otel_context.reparent_tracing_span(); spin_factor_outbound_networking::record_address_fields(&address); if !self @@ -240,6 +241,8 @@ impl v2::HostConnection for InstanceState { statement: String, params: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); + Ok(self .get_client(connection) .await? @@ -254,6 +257,7 @@ impl v2::HostConnection for InstanceState { statement: String, params: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); Ok(self .get_client(connection) .await? diff --git a/crates/factor-outbound-pg/src/lib.rs b/crates/factor-outbound-pg/src/lib.rs index b3a433946e..a793271fef 100644 --- a/crates/factor-outbound-pg/src/lib.rs +++ b/crates/factor-outbound-pg/src/lib.rs @@ -4,7 +4,9 @@ mod types; use std::sync::Arc; +use client::Client; use client::ClientFactory; +use spin_factor_otel::OtelContext; use spin_factor_outbound_networking::{ config::allowed_hosts::OutboundAllowedHosts, OutboundNetworkingFactor, }; @@ -48,10 +50,13 @@ impl Factor for OutboundPgFactor { let allowed_hosts = ctx .instance_builder::()? .allowed_hosts(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; + Ok(InstanceState { allowed_hosts, client_factory: ctx.app_state().clone(), connections: Default::default(), + otel_context, }) } } @@ -74,6 +79,7 @@ pub struct InstanceState { allowed_hosts: OutboundAllowedHosts, client_factory: Arc, connections: spin_resource_table::Table, + otel_context: OtelContext, } impl SelfInstanceBuilder for InstanceState {} diff --git a/crates/factor-outbound-redis/Cargo.toml b/crates/factor-outbound-redis/Cargo.toml index 092363069d..76ccc73958 100644 --- a/crates/factor-outbound-redis/Cargo.toml +++ b/crates/factor-outbound-redis/Cargo.toml @@ -8,6 +8,7 @@ edition = { workspace = true } anyhow = { workspace = true } redis = { version = "0.25", features = ["tokio-comp", "tokio-native-tls-comp", "aio"] } spin-core = { path = "../core" } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-networking = { path = "../factor-outbound-networking" } spin-factors = { path = "../factors" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-outbound-redis/src/host.rs b/crates/factor-outbound-redis/src/host.rs index d938cf9c31..c260b453d1 100644 --- a/crates/factor-outbound-redis/src/host.rs +++ b/crates/factor-outbound-redis/src/host.rs @@ -2,6 +2,8 @@ use anyhow::Result; use redis::{aio::MultiplexedConnection, AsyncCommands, FromRedisValue, Value}; use spin_core::wasmtime::component::Resource; use spin_factor_outbound_networking::config::allowed_hosts::OutboundAllowedHosts; +use spin_factor_otel::OtelContext; +use spin_factor_outbound_networking::OutboundAllowedHosts; use spin_world::v1::{redis as v1, redis_types}; use spin_world::v2::redis::{ self as v2, Connection as RedisConnection, Error, RedisParameter, RedisResult, @@ -12,6 +14,7 @@ use tracing::{instrument, Level}; pub struct InstanceState { pub allowed_hosts: OutboundAllowedHosts, pub connections: spin_resource_table::Table, + pub otel_context: OtelContext, } impl InstanceState { @@ -55,8 +58,7 @@ impl v2::Host for crate::InstanceState { impl v2::HostConnection for crate::InstanceState { #[instrument(name = "spin_outbound_redis.open_connection", skip(self, address), err(level = Level::INFO), fields(otel.kind = "client", db.system = "redis", db.address = Empty, server.port = Empty, db.namespace = Empty))] async fn open(&mut self, address: String) -> Result, Error> { - spin_factor_outbound_networking::record_address_fields(&address); - + self.otel_context.reparent_tracing_span(); if !self .is_address_allowed(&address) .await @@ -75,6 +77,8 @@ impl v2::HostConnection for crate::InstanceState { channel: String, payload: Vec, ) -> Result<(), Error> { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; // The `let () =` syntax is needed to suppress a warning when the result type is inferred. // You can read more about the issue here: @@ -91,6 +95,8 @@ impl v2::HostConnection for crate::InstanceState { connection: Resource, key: String, ) -> Result>, Error> { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; let value = conn.get(&key).await.map_err(other_error)?; Ok(value) @@ -103,6 +109,8 @@ impl v2::HostConnection for crate::InstanceState { key: String, value: Vec, ) -> Result<(), Error> { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; // The `let () =` syntax is needed to suppress a warning when the result type is inferred. // You can read more about the issue here: @@ -116,6 +124,8 @@ impl v2::HostConnection for crate::InstanceState { connection: Resource, key: String, ) -> Result { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; let value = conn.incr(&key, 1).await.map_err(other_error)?; Ok(value) @@ -127,6 +137,8 @@ impl v2::HostConnection for crate::InstanceState { connection: Resource, keys: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; let value = conn.del(&keys).await.map_err(other_error)?; Ok(value) @@ -139,6 +151,8 @@ impl v2::HostConnection for crate::InstanceState { key: String, values: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; let value = conn.sadd(&key, &values).await.map_err(|e| { if e.kind() == redis::ErrorKind::TypeError { @@ -156,6 +170,8 @@ impl v2::HostConnection for crate::InstanceState { connection: Resource, key: String, ) -> Result, Error> { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; let value = conn.smembers(&key).await.map_err(other_error)?; Ok(value) @@ -168,6 +184,8 @@ impl v2::HostConnection for crate::InstanceState { key: String, values: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await.map_err(other_error)?; let value = conn.srem(&key, &values).await.map_err(other_error)?; Ok(value) @@ -180,6 +198,8 @@ impl v2::HostConnection for crate::InstanceState { command: String, arguments: Vec, ) -> Result, Error> { + self.otel_context.reparent_tracing_span(); + let conn = self.get_conn(connection).await?; let mut cmd = redis::cmd(&command); arguments.iter().for_each(|value| match value { diff --git a/crates/factor-outbound-redis/src/lib.rs b/crates/factor-outbound-redis/src/lib.rs index 7986d0621a..08e7c3dd5c 100644 --- a/crates/factor-outbound-redis/src/lib.rs +++ b/crates/factor-outbound-redis/src/lib.rs @@ -1,6 +1,7 @@ mod host; use host::InstanceState; +use spin_factor_otel::OtelContext; use spin_factor_outbound_networking::OutboundNetworkingFactor; use spin_factors::{ anyhow, ConfigureAppContext, Factor, FactorData, PrepareContext, RuntimeFactors, @@ -44,9 +45,12 @@ impl Factor for OutboundRedisFactor { let allowed_hosts = ctx .instance_builder::()? .allowed_hosts(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; + Ok(InstanceState { allowed_hosts, connections: spin_resource_table::Table::new(1024), + otel_context, }) } } diff --git a/crates/factor-sqlite/Cargo.toml b/crates/factor-sqlite/Cargo.toml index ee945ed4fa..98a6325ad7 100644 --- a/crates/factor-sqlite/Cargo.toml +++ b/crates/factor-sqlite/Cargo.toml @@ -10,6 +10,7 @@ rust-version.workspace = true [dependencies] async-trait = { workspace = true } +spin-factor-otel = { path = "../factor-otel" } spin-factors = { path = "../factors" } spin-locked-app = { path = "../locked-app" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-sqlite/src/host.rs b/crates/factor-sqlite/src/host.rs index 953ee70cc4..e6ed819a54 100644 --- a/crates/factor-sqlite/src/host.rs +++ b/crates/factor-sqlite/src/host.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; +use spin_factor_otel::OtelContext; use spin_factors::wasmtime::component::Resource; use spin_factors::{anyhow, SelfInstanceBuilder}; use spin_world::spin::sqlite::sqlite as v3; @@ -17,6 +18,7 @@ pub struct InstanceState { connections: spin_resource_table::Table>, /// A map from database label to connection creators. connection_creators: HashMap>, + otel_context: OtelContext, } impl InstanceState { @@ -26,11 +28,13 @@ impl InstanceState { pub fn new( allowed_databases: Arc>, connection_creators: HashMap>, + otel_context: OtelContext, ) -> Self { Self { allowed_databases, connections: spin_resource_table::Table::new(256), connection_creators, + otel_context, } } @@ -154,6 +158,7 @@ impl v2::Host for InstanceState { impl v2::HostConnection for InstanceState { #[instrument(name = "spin_sqlite.open", skip(self), err(level = Level::INFO), fields(otel.kind = "client", db.system = "sqlite", sqlite.backend = Empty))] async fn open(&mut self, database: String) -> Result, v2::Error> { + self.otel_context.reparent_tracing_span(); self.open_impl(database).await.map_err(to_v2_error) } @@ -164,6 +169,7 @@ impl v2::HostConnection for InstanceState { query: String, parameters: Vec, ) -> Result { + self.otel_context.reparent_tracing_span(); self.execute_impl( connection, query, diff --git a/crates/factor-sqlite/src/lib.rs b/crates/factor-sqlite/src/lib.rs index 9fafdb796a..6298d6ae7a 100644 --- a/crates/factor-sqlite/src/lib.rs +++ b/crates/factor-sqlite/src/lib.rs @@ -8,6 +8,8 @@ use host::InstanceState; use async_trait::async_trait; use spin_factors::{anyhow, Factor, FactorData}; +use spin_factor_otel::OtelContext; +use spin_factors::{anyhow, Factor}; use spin_locked_app::MetadataKey; use spin_world::spin::sqlite::sqlite as v3; use spin_world::v1::sqlite as v1; @@ -74,7 +76,7 @@ impl Factor for SqliteFactor { fn prepare( &self, - ctx: spin_factors::PrepareContext, + mut ctx: spin_factors::PrepareContext, ) -> spin_factors::anyhow::Result { let allowed_databases = ctx .app_state() @@ -82,9 +84,11 @@ impl Factor for SqliteFactor { .get(ctx.app_component().id()) .cloned() .unwrap_or_default(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; Ok(InstanceState::new( allowed_databases, ctx.app_state().connection_creators.clone(), + otel_context, )) } } diff --git a/crates/factor-variables/Cargo.toml b/crates/factor-variables/Cargo.toml index 4a1a76f83e..c24c6ebb7c 100644 --- a/crates/factor-variables/Cargo.toml +++ b/crates/factor-variables/Cargo.toml @@ -6,6 +6,7 @@ edition = { workspace = true } [dependencies] spin-expressions = { path = "../expressions" } +spin-factor-otel = { path = "../factor-otel" } spin-factors = { path = "../factors" } spin-telemetry = { path = "../telemetry" } spin-world = { path = "../world" } diff --git a/crates/factor-variables/src/host.rs b/crates/factor-variables/src/host.rs index 31706af0ca..784cebd280 100644 --- a/crates/factor-variables/src/host.rs +++ b/crates/factor-variables/src/host.rs @@ -8,6 +8,7 @@ use crate::InstanceState; impl variables::Host for InstanceState { #[instrument(name = "spin_variables.get", skip(self), fields(otel.kind = "client"))] async fn get(&mut self, key: String) -> Result { + self.otel_context.reparent_tracing_span(); let key = spin_expressions::Key::new(&key).map_err(expressions_to_variables_err)?; self.expression_resolver .resolve(&self.component_id, key) diff --git a/crates/factor-variables/src/lib.rs b/crates/factor-variables/src/lib.rs index fc60dfed24..e8cbeb7410 100644 --- a/crates/factor-variables/src/lib.rs +++ b/crates/factor-variables/src/lib.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use runtime_config::RuntimeConfig; use spin_expressions::{ProviderResolver as ExpressionResolver, Template}; +use spin_factor_otel::OtelContext; use spin_factors::{ anyhow, ConfigureAppContext, Factor, FactorData, InitContext, PrepareContext, RuntimeFactors, SelfInstanceBuilder, @@ -62,13 +63,15 @@ impl Factor for VariablesFactor { fn prepare( &self, - ctx: PrepareContext, + mut ctx: PrepareContext, ) -> anyhow::Result { let component_id = ctx.app_component().id().to_string(); let expression_resolver = ctx.app_state().expression_resolver.clone(); + let otel_context = OtelContext::from_prepare_context(&mut ctx)?; Ok(InstanceState { component_id, expression_resolver, + otel_context, }) } } @@ -90,6 +93,7 @@ impl AppState { pub struct InstanceState { component_id: String, expression_resolver: Arc, + otel_context: OtelContext, } impl InstanceState { diff --git a/crates/runtime-config/Cargo.toml b/crates/runtime-config/Cargo.toml index 5a8aa05ad0..1b08cda8f7 100644 --- a/crates/runtime-config/Cargo.toml +++ b/crates/runtime-config/Cargo.toml @@ -15,6 +15,7 @@ spin-common = { path = "../common" } spin-expressions = { path = "../expressions" } spin-factor-key-value = { path = "../factor-key-value" } spin-factor-llm = { path = "../factor-llm" } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-http = { path = "../factor-outbound-http" } spin-factor-outbound-mqtt = { path = "../factor-outbound-mqtt" } spin-factor-outbound-mysql = { path = "../factor-outbound-mysql" } diff --git a/crates/runtime-config/src/lib.rs b/crates/runtime-config/src/lib.rs index d8bbc49a19..23109b87d8 100644 --- a/crates/runtime-config/src/lib.rs +++ b/crates/runtime-config/src/lib.rs @@ -5,6 +5,7 @@ use spin_common::ui::quoted_path; use spin_factor_key_value::runtime_config::spin::{self as key_value}; use spin_factor_key_value::KeyValueFactor; use spin_factor_llm::{spin as llm, LlmFactor}; +use spin_factor_otel::OtelFactor; use spin_factor_outbound_http::OutboundHttpFactor; use spin_factor_outbound_mqtt::OutboundMqttFactor; use spin_factor_outbound_mysql::OutboundMysqlFactor; @@ -398,6 +399,12 @@ impl FactorRuntimeConfigSource for TomlRuntimeConfigSource<'_, '_> } } +impl FactorRuntimeConfigSource for TomlRuntimeConfigSource<'_, '_> { + fn get_runtime_config(&mut self) -> anyhow::Result> { + Ok(None) + } +} + impl RuntimeConfigSourceFinalizer for TomlRuntimeConfigSource<'_, '_> { fn finalize(&mut self) -> anyhow::Result<()> { Ok(self.toml.validate_all_keys_used()?) diff --git a/crates/runtime-factors/Cargo.toml b/crates/runtime-factors/Cargo.toml index 257c3f36fa..4e36fccca2 100644 --- a/crates/runtime-factors/Cargo.toml +++ b/crates/runtime-factors/Cargo.toml @@ -19,6 +19,7 @@ clap = { workspace = true, features = ["derive", "env"] } spin-common = { path = "../common" } spin-factor-key-value = { path = "../factor-key-value" } spin-factor-llm = { path = "../factor-llm" } +spin-factor-otel = { path = "../factor-otel" } spin-factor-outbound-http = { path = "../factor-outbound-http" } spin-factor-outbound-mqtt = { path = "../factor-outbound-mqtt" } spin-factor-outbound-mysql = { path = "../factor-outbound-mysql" } diff --git a/crates/runtime-factors/src/lib.rs b/crates/runtime-factors/src/lib.rs index c0b8baf4d4..dc7ccdc3f2 100644 --- a/crates/runtime-factors/src/lib.rs +++ b/crates/runtime-factors/src/lib.rs @@ -10,6 +10,7 @@ use anyhow::Context as _; use spin_common::arg_parser::parse_kv; use spin_factor_key_value::KeyValueFactor; use spin_factor_llm::LlmFactor; +use spin_factor_otel::OtelFactor; use spin_factor_outbound_http::OutboundHttpFactor; use spin_factor_outbound_mqtt::{NetworkedMqttClient, OutboundMqttFactor}; use spin_factor_outbound_mysql::OutboundMysqlFactor; @@ -25,6 +26,7 @@ use spin_variables_static::VariableSource; #[derive(RuntimeFactors)] pub struct TriggerFactors { + pub otel: OtelFactor, pub wasi: WasiFactor, pub variables: VariablesFactor, pub key_value: KeyValueFactor, @@ -45,6 +47,7 @@ impl TriggerFactors { allow_transient_writes: bool, ) -> anyhow::Result { Ok(Self { + otel: OtelFactor::new()?, wasi: wasi_factor(working_dir, allow_transient_writes), variables: VariablesFactor::default(), key_value: KeyValueFactor::new(), diff --git a/crates/telemetry/src/env.rs b/crates/telemetry/src/env.rs index 5786e236df..487aad6227 100644 --- a/crates/telemetry/src/env.rs +++ b/crates/telemetry/src/env.rs @@ -19,7 +19,7 @@ const SPIN_DISABLE_LOG_TO_TRACING: &str = "SPIN_DISABLE_LOG_TO_TRACING"; /// - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` /// /// Note that this is overridden if OTEL_SDK_DISABLED is set and not empty. -pub(crate) fn otel_tracing_enabled() -> bool { +pub fn otel_tracing_enabled() -> bool { any_vars_set(&[ OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, @@ -33,7 +33,7 @@ pub(crate) fn otel_tracing_enabled() -> bool { /// - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` /// /// Note that this is overridden if OTEL_SDK_DISABLED is set and not empty. -pub(crate) fn otel_metrics_enabled() -> bool { +pub fn otel_metrics_enabled() -> bool { any_vars_set(&[ OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, @@ -47,7 +47,7 @@ pub(crate) fn otel_metrics_enabled() -> bool { /// - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` /// /// Note that this is overridden if OTEL_SDK_DISABLED is set and not empty. -pub(crate) fn otel_logs_enabled() -> bool { +pub fn otel_logs_enabled() -> bool { any_vars_set(&[ OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, @@ -59,7 +59,7 @@ pub(crate) fn otel_logs_enabled() -> bool { /// /// It is considered disabled if the environment variable `SPIN_DISABLED_LOG_TO_TRACING` is set and not /// empty. By default the features is enabled. -pub(crate) fn spin_disable_log_to_tracing() -> bool { +pub fn spin_disable_log_to_tracing() -> bool { any_vars_set(&[SPIN_DISABLE_LOG_TO_TRACING]) } @@ -72,13 +72,13 @@ fn any_vars_set(enabling_vars: &[&str]) -> bool { /// Returns a boolean indicating if the OTEL SDK should be disabled for all signals. /// /// It is considered disabled if the environment variable `OTEL_SDK_DISABLED` is set and not empty. -pub(crate) fn otel_sdk_disabled() -> bool { +pub fn otel_sdk_disabled() -> bool { std::env::var_os(OTEL_SDK_DISABLED).is_some_and(|val| !val.is_empty()) } /// The protocol to use for OTLP exporter. #[derive(Debug)] -pub(crate) enum OtlpProtocol { +pub enum OtlpProtocol { Grpc, HttpProtobuf, HttpJson, @@ -86,7 +86,7 @@ pub(crate) enum OtlpProtocol { impl OtlpProtocol { /// Returns the protocol to be used for exporting traces as defined by the environment. - pub(crate) fn traces_protocol_from_env() -> Self { + pub fn traces_protocol_from_env() -> Self { Self::protocol_from_env( std::env::var(OTEL_EXPORTER_OTLP_TRACES_PROTOCOL), std::env::var(OTEL_EXPORTER_OTLP_PROTOCOL), @@ -94,7 +94,7 @@ impl OtlpProtocol { } /// Returns the protocol to be used for exporting metrics as defined by the environment. - pub(crate) fn metrics_protocol_from_env() -> Self { + pub fn metrics_protocol_from_env() -> Self { Self::protocol_from_env( std::env::var(OTEL_EXPORTER_OTLP_METRICS_PROTOCOL), std::env::var(OTEL_EXPORTER_OTLP_PROTOCOL), @@ -102,7 +102,7 @@ impl OtlpProtocol { } /// Returns the protocol to be used for exporting logs as defined by the environment. - pub(crate) fn logs_protocol_from_env() -> Self { + pub fn logs_protocol_from_env() -> Self { Self::protocol_from_env( std::env::var(OTEL_EXPORTER_OTLP_LOGS_PROTOCOL), std::env::var(OTEL_EXPORTER_OTLP_PROTOCOL), diff --git a/crates/telemetry/src/lib.rs b/crates/telemetry/src/lib.rs index 4c5c99074e..dd1343e13d 100644 --- a/crates/telemetry/src/lib.rs +++ b/crates/telemetry/src/lib.rs @@ -9,7 +9,7 @@ use tracing_subscriber::{fmt, prelude::*, registry, EnvFilter, Layer}; mod alert_in_dev; pub mod detector; -mod env; +pub mod env; pub mod logs; pub mod metrics; mod propagation; @@ -53,6 +53,15 @@ pub use propagation::inject_trace_context; /// spin_telemetry::metrics::monotonic_counter!(spin.metric_name = 1, metric_attribute = "value"); /// ``` pub fn init(spin_version: String) -> anyhow::Result<()> { + // This filter globally filters out spans produced by wasi_http so that they don't conflict with + // the behaviour of the wasi-otel factor. + let wasi_http_trace_filter = tracing_subscriber::filter::filter_fn(|metadata| { + if metadata.is_span() && metadata.name() == "wit-bindgen export" { + return false; + } + true + }); + // This layer will print all tracing library log messages to stderr. let fmt_layer = fmt::layer() .with_writer(std::io::stderr) @@ -91,6 +100,7 @@ pub fn init(spin_version: String) -> anyhow::Result<()> { // Build a registry subscriber with the layers we want to use. registry() + .with(wasi_http_trace_filter) .with(otel_tracing_layer) .with(otel_metrics_layer) .with(fmt_layer) diff --git a/crates/trigger-http/Cargo.toml b/crates/trigger-http/Cargo.toml index 6374597910..97b0a23d77 100644 --- a/crates/trigger-http/Cargo.toml +++ b/crates/trigger-http/Cargo.toml @@ -29,6 +29,7 @@ spin-http = { path = "../http" } spin-telemetry = { path = "../telemetry" } spin-trigger = { path = "../trigger" } spin-world = { path = "../world" } +spin-factor-otel = { path = "../factor-otel" } terminal = { path = "../terminal" } tokio = { workspace = true, features = ["full"] } tokio-rustls = { workspace = true } diff --git a/crates/world/Cargo.toml b/crates/world/Cargo.toml index fd4763100d..4508fb7e6a 100644 --- a/crates/world/Cargo.toml +++ b/crates/world/Cargo.toml @@ -5,5 +5,8 @@ authors = { workspace = true } edition = { workspace = true } [dependencies] +anyhow = { workspace = true } async-trait = { workspace = true } +opentelemetry = { workspace = true } +opentelemetry_sdk = { workspace = true } wasmtime = { workspace = true } diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index 8177b623b2..b9145f8d09 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -553,3 +553,219 @@ mod llm { } } } + +mod otel { + use super::*; + use opentelemetry::StringValue; + use opentelemetry_sdk::trace::{SpanEvents, SpanLinks}; + use std::time::{Duration, SystemTime, UNIX_EPOCH}; + use wasi::clocks0_2_0::wall_clock; + use wasi::otel::tracing as wasi_otel; + + impl From for opentelemetry_sdk::export::trace::SpanData { + fn from(value: wasi_otel::SpanData) -> Self { + let mut span_events = SpanEvents::default(); + span_events.events = value.events.into_iter().map(Into::into).collect(); + span_events.dropped_count = value.dropped_events; + let mut span_links = SpanLinks::default(); + span_links.links = value.links.into_iter().map(Into::into).collect(); + span_links.dropped_count = value.dropped_links; + Self { + span_context: value.span_context.into(), + parent_span_id: opentelemetry::trace::SpanId::from_hex(&value.parent_span_id) + .unwrap_or(opentelemetry::trace::SpanId::INVALID), + span_kind: value.span_kind.into(), + name: value.name.into(), + start_time: value.start_time.into(), + end_time: value.end_time.into(), + attributes: value.attributes.into_iter().map(Into::into).collect(), + dropped_attributes_count: value.dropped_attributes, + events: span_events, + links: span_links, + status: value.status.into(), + instrumentation_scope: value.instrumentation_scope.into(), + } + } + } + + impl From for opentelemetry::trace::SpanContext { + fn from(sc: wasi_otel::SpanContext) -> Self { + let trace_id = opentelemetry::trace::TraceId::from_hex(&sc.trace_id) + .unwrap_or(opentelemetry::trace::TraceId::INVALID); + let span_id = opentelemetry::trace::SpanId::from_hex(&sc.span_id) + .unwrap_or(opentelemetry::trace::SpanId::INVALID); + let trace_state = opentelemetry::trace::TraceState::from_key_value(sc.trace_state) + .unwrap_or_else(|_| opentelemetry::trace::TraceState::default()); + Self::new( + trace_id, + span_id, + sc.trace_flags.into(), + sc.is_remote, + trace_state, + ) + } + } + + impl From for wasi_otel::SpanContext { + fn from(sc: opentelemetry::trace::SpanContext) -> Self { + Self { + trace_id: format!("{:x}", sc.trace_id()), + span_id: format!("{:x}", sc.span_id()), + trace_flags: sc.trace_flags().into(), + is_remote: sc.is_remote(), + trace_state: sc + .trace_state() + .header() + .split(',') + .filter_map(|s| { + if let Some((key, value)) = s.split_once('=') { + Some((key.to_string(), value.to_string())) + } else { + None + } + }) + .collect(), + } + } + } + + impl From for opentelemetry::trace::TraceFlags { + fn from(flags: wasi_otel::TraceFlags) -> Self { + Self::new(flags.as_array()[0] as u8) + } + } + + impl From for wasi_otel::TraceFlags { + fn from(flags: opentelemetry::trace::TraceFlags) -> Self { + if flags.is_sampled() { + wasi_otel::TraceFlags::SAMPLED + } else { + wasi_otel::TraceFlags::empty() + } + } + } + + impl From for opentelemetry::trace::SpanKind { + fn from(kind: wasi_otel::SpanKind) -> Self { + match kind { + wasi_otel::SpanKind::Client => opentelemetry::trace::SpanKind::Client, + wasi_otel::SpanKind::Server => opentelemetry::trace::SpanKind::Server, + wasi_otel::SpanKind::Producer => opentelemetry::trace::SpanKind::Producer, + wasi_otel::SpanKind::Consumer => opentelemetry::trace::SpanKind::Consumer, + wasi_otel::SpanKind::Internal => opentelemetry::trace::SpanKind::Internal, + } + } + } + + impl From for opentelemetry::KeyValue { + fn from(kv: wasi_otel::KeyValue) -> Self { + opentelemetry::KeyValue::new(kv.key, kv.value) + } + } + + impl From for opentelemetry::Value { + fn from(value: wasi_otel::Value) -> Self { + match value { + wasi_otel::Value::String(v) => v.into(), + wasi_otel::Value::Bool(v) => v.into(), + wasi_otel::Value::F64(v) => v.into(), + wasi_otel::Value::S64(v) => v.into(), + wasi_otel::Value::StringArray(v) => opentelemetry::Value::Array( + v.into_iter() + .map(StringValue::from) + .collect::>() + .into(), + ), + wasi_otel::Value::BoolArray(v) => opentelemetry::Value::Array(v.into()), + wasi_otel::Value::F64Array(v) => opentelemetry::Value::Array(v.into()), + wasi_otel::Value::S64Array(v) => opentelemetry::Value::Array(v.into()), + } + } + } + + impl From for opentelemetry::trace::Event { + fn from(event: wasi_otel::Event) -> Self { + Self::new( + event.name, + event.time.into(), + event.attributes.into_iter().map(Into::into).collect(), + 0, + ) + } + } + + impl From for opentelemetry::trace::Link { + fn from(link: wasi_otel::Link) -> Self { + Self::new( + link.span_context.into(), + link.attributes.into_iter().map(Into::into).collect(), + 0, + ) + } + } + + impl From for opentelemetry::trace::Status { + fn from(status: wasi_otel::Status) -> Self { + match status { + wasi_otel::Status::Unset => Self::Unset, + wasi_otel::Status::Ok => Self::Ok, + wasi_otel::Status::Error(s) => Self::Error { + description: s.into(), + }, + } + } + } + + impl From for opentelemetry::InstrumentationScope { + fn from(value: wasi_otel::InstrumentationScope) -> Self { + let builder = Self::builder(value.name) + .with_attributes(value.attributes.into_iter().map(Into::into)); + match (value.version, value.schema_url) { + (Some(version), Some(schema_url)) => builder + .with_version(version) + .with_schema_url(schema_url) + .build(), + (Some(version), None) => builder.with_version(version).build(), + (None, Some(schema_url)) => builder.with_schema_url(schema_url).build(), + (None, None) => builder.build(), + } + } + } + + impl From for SystemTime { + fn from(timestamp: wall_clock::Datetime) -> Self { + UNIX_EPOCH + + Duration::from_secs(timestamp.seconds) + + Duration::from_nanos(timestamp.nanoseconds as u64) + } + } + + mod test { + #[test] + fn trace_flags() { + let flags = opentelemetry::trace::TraceFlags::SAMPLED; + let flags2 = crate::wasi::otel::tracing::TraceFlags::from(flags); + let flags3 = opentelemetry::trace::TraceFlags::from(flags2); + assert_eq!(flags, flags3); + } + + #[test] + fn span_context() { + let sc = opentelemetry::trace::SpanContext::new( + opentelemetry::trace::TraceId::from_hex("4fb34cb4484029f7881399b149e41e98") + .unwrap(), + opentelemetry::trace::SpanId::from_hex("9ffd58d3cd4dd90b").unwrap(), + opentelemetry::trace::TraceFlags::SAMPLED, + false, + opentelemetry::trace::TraceState::from_key_value(vec![ + ("foo", "bar"), + ("baz", "qux"), + ]) + .unwrap(), + ); + let sc2 = crate::wasi::otel::tracing::SpanContext::from(sc.clone()); + let sc3 = opentelemetry::trace::SpanContext::from(sc2); + assert_eq!(sc, sc3); + } + } +} diff --git a/tests/integration.rs b/tests/integration.rs index a2e358195c..b5af15f952 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,6 +1,7 @@ -mod testcases; +pub mod testcases; mod integration_tests { + use anyhow::Context; use sha2::Digest; use std::collections::HashMap; use test_environment::{ @@ -9,13 +10,12 @@ mod integration_tests { }; use testing_framework::runtimes::{spin_cli::SpinConfig, SpinAppType}; - use super::testcases::{ + pub use super::testcases::{ assert_spin_request, bootstap_env, http_smoke_test_template, run_test, spin_binary, }; - use anyhow::Context; - /// Helper macro to assert that a condition is true eventually #[cfg(feature = "extern-dependencies-tests")] + /// Helper macro to assert that a condition is true eventually macro_rules! assert_eventually { ($e:expr, $t:expr) => { let mut i = 0; @@ -1582,3 +1582,432 @@ route = "/..." Ok(()) } } + +mod otel_integration_tests { + use fake_opentelemetry_collector::FakeCollectorServer; + use std::time::Duration; + use test_environment::{ + http::{Method, Request, Response}, + services::ServicesConfig, + }; + use testing_framework::runtimes::{spin_cli::SpinConfig, SpinAppType}; + + use crate::testcases::run_test_inited; + + use super::testcases::{assert_spin_request, spin_binary}; + + #[test] + // Test that basic otel tracing and inbound/outbound context propagation works + fn otel_smoke_test() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "otel-smoke-test", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request(spin, Request::new(Method::Get, "/one"), Response::new(200))?; + + let spans = rt.block_on(collector.exported_spans(5, Duration::from_secs(5))); + + assert_eq!(spans.len(), 5); + + // They're all part of the same trace which implies context propagation is working + assert!(spans + .iter() + .map(|s| s.trace_id.clone()) + .all(|t| t == spans[0].trace_id)); + + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + fn wasi_otel_nested_spans() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "wasi-otel-tracing", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + Request::new(Method::Get, "/nested-spans"), + Response::new(200), + )?; + + let spans = rt.block_on(collector.exported_spans(4, Duration::from_secs(5))); + + assert_eq!(spans.len(), 4); + + let handle_request_span = spans + .iter() + .find(|s| s.name == "GET /...") + .expect("'GET /...' span should exist"); + let exec_component_span = spans + .iter() + .find(|s| s.name == "execute_wasm_component wasi-otel-tracing") + .expect("'execute_wasm_component wasi-otel-tracing' span should exist"); + let outer_span = spans + .iter() + .find(|s| s.name == "outer_func") + .expect("'outer_func' span should exist"); + let inner_span = spans + .iter() + .find(|s| s.name == "inner_func") + .expect("'inner_func' span should exist"); + + assert!( + handle_request_span.trace_id == exec_component_span.trace_id + && exec_component_span.trace_id == outer_span.trace_id + && outer_span.trace_id == inner_span.trace_id + ); + assert_eq!( + exec_component_span.parent_span_id, + handle_request_span.span_id + ); + assert_eq!(outer_span.parent_span_id, exec_component_span.span_id); + assert_eq!(inner_span.parent_span_id, outer_span.span_id); + + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + fn wasi_otel_setting_attributes() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "wasi-otel-tracing", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + Request::new(Method::Get, "/setting-attributes"), + Response::new(200), + )?; + + let spans = rt.block_on(collector.exported_spans(3, Duration::from_secs(5))); + + assert_eq!(spans.len(), 3); + + let attr_span = spans + .iter() + .find(|s| s.name == "setting_attributes") + .expect("'setting_attributes' span should exist"); + + // There are some other attributes already set on the span + assert_eq!(attr_span.attributes.len(), 2); + + assert_eq!( + attr_span + .attributes + .get("foo") + .expect("'foo' attribute should exist"), + "Some(AnyValue { value: Some(StringValue(\"baz\")) })" + ); + assert_eq!( + attr_span.attributes.get("qux").expect("'qux' attribute should exist"), + "Some(AnyValue { value: Some(ArrayValue(ArrayValue { values: [AnyValue { value: Some(StringValue(\"qaz\")) }, AnyValue { value: Some(StringValue(\"thud\")) }] })) })" + ); + + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + fn wasi_otel_host_guest_host() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "wasi-otel-tracing", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + Request::new(Method::Get, "/host-guest-host"), + Response::new(200), + )?; + + let spans = rt.block_on(collector.exported_spans(4, Duration::from_secs(5))); + + assert_eq!(spans.len(), 4); + + assert!(spans + .iter() + .map(|s| s.trace_id.clone()) + .all(|t| t == spans[0].trace_id)); + + let exec_component_span = spans + .iter() + .find(|s| s.name == "execute_wasm_component wasi-otel-tracing") + .expect("'execute_wasm_component wasi-otel-tracing' span should exist"); + let guest_span = spans + .iter() + .find(|s| s.name == "guest") + .expect("'guest' span should exist"); + let get_span = spans + .iter() + .find(|s| s.name == "GET") + .expect("'GET' span should exist"); + + assert_eq!(guest_span.parent_span_id, exec_component_span.span_id); + assert_eq!(get_span.parent_span_id, guest_span.span_id); + + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + fn wasi_otel_events() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "wasi-otel-tracing", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + Request::new(Method::Get, "/events"), + Response::new(200), + )?; + + let spans = rt.block_on(collector.exported_spans(3, Duration::from_secs(5))); + + assert_eq!(spans.len(), 3); + + let event_span = spans + .iter() + .find(|s| s.name == "events") + .expect("'events' span should exist"); + + let events = event_span.events.clone(); + assert_eq!(events.len(), 3); + + let basic_event = events + .iter() + .find(|e| e.name == "basic-event") + .expect("'basic' event should exist"); + let event_with_attributes = events + .iter() + .find(|e| e.name == "event-with-attributes") + .expect("'event_with_attributes' event should exist"); + let event_with_timestamp = events + .iter() + .find(|e| e.name == "event-with-timestamp") + .expect("'event_with_timestamp' event should exist"); + + assert!(basic_event.time_unix_nano < event_with_attributes.time_unix_nano); + assert_eq!(event_with_attributes.attributes.len(), 1); + assert!(event_with_attributes.time_unix_nano < event_with_timestamp.time_unix_nano); + + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + fn wasi_otel_links() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "wasi-otel-tracing", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + Request::new(Method::Get, "/links"), + Response::new(200), + )?; + + let spans = rt.block_on(collector.exported_spans(4, Duration::from_secs(5))); + + assert_eq!(spans.len(), 4); + + let first_span = spans + .iter() + .find(|s| s.name == "first") + .expect("'first' span should exist"); + let second_span = spans + .iter() + .find(|s| s.name == "second") + .expect("'second' span should exist"); + + assert_eq!(first_span.links.len(), 0); + assert_eq!(second_span.links.len(), 1); + assert_eq!( + second_span.links.first().unwrap().span_id, + first_span.span_id + ); + assert_eq!(second_span.links.first().unwrap().attributes.len(), 1); + + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + fn wasi_otel_root_span() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + let mut collector = rt + .block_on(FakeCollectorServer::start()) + .expect("fake collector server should start"); + let collector_endpoint = collector.endpoint().clone(); + + run_test_inited( + "wasi-otel-tracing", + SpinConfig { + binary_path: spin_binary(), + spin_up_args: Vec::new(), + app_type: SpinAppType::Http, + }, + ServicesConfig::none(), + |env| { + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", collector_endpoint); + env.set_env_var("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "grpc"); + env.set_env_var("OTEL_BSP_SCHEDULE_DELAY", "5"); + Ok(()) + }, + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + Request::new(Method::Get, "/root-span"), + Response::new(200), + )?; + + let spans = rt.block_on(collector.exported_spans(7, Duration::from_secs(5))); + + assert_eq!(spans.len(), 4); + + let root_span = spans + .iter() + .find(|s| s.name == "root") + .expect("'root' span should exist"); + let request_span = spans + .iter() + .find(|s| s.name == "GET") + .expect("'GET' span should exist"); + + assert_eq!(root_span.trace_id, request_span.trace_id); + assert_eq!(root_span.span_id, request_span.parent_span_id); + assert_eq!(root_span.parent_span_id, "".to_string()); + + Ok(()) + }, + )?; + + Ok(()) + } +} diff --git a/tests/test-components/components/Cargo.lock b/tests/test-components/components/Cargo.lock index db79baac4d..54ff180e7c 100644 --- a/tests/test-components/components/Cargo.lock +++ b/tests/test-components/components/Cargo.lock @@ -22,6 +22,21 @@ dependencies = [ "wit-bindgen 0.34.0", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.89" @@ -60,18 +75,59 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "cc" +version = "1.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -221,6 +277,23 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "hashbrown" version = "0.14.3" @@ -316,6 +389,29 @@ dependencies = [ "spin-sdk 2.2.0", ] +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "id-arena" version = "2.2.1" @@ -424,7 +520,7 @@ dependencies = [ "anyhow", "futures", "helper", - "spin-sdk 3.0.0", + "spin-sdk 3.1.0", ] [[package]] @@ -433,6 +529,16 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "key-value" version = "0.1.0" @@ -458,9 +564,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "log" @@ -496,12 +602,74 @@ dependencies = [ "ryu", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opentelemetry" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab70038c28ed37b97d8ed414b6429d343a8bbf44c9f79ec854f3a643029ba6d7" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror", + "tracing", +] + +[[package]] +name = "opentelemetry-wasi" +version = "0.27.0" +source = "git+https://github.com/calebschoepp/opentelemetry-wasi?rev=bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed#bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed" +dependencies = [ + "anyhow", + "opentelemetry", + "opentelemetry_sdk", + "wit-bindgen 0.30.0", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" +dependencies = [ + "async-trait", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "opentelemetry", + "percent-encoding", + "rand", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "otel-smoke-test" +version = "0.1.0" +dependencies = [ + "anyhow", + "http 0.2.11", + "spin-sdk 2.2.0", +] + [[package]] name = "outbound-http-component" version = "0.1.0" @@ -561,6 +729,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "prettyplease" version = "0.2.29" @@ -589,6 +766,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "routefinder" version = "0.5.3" @@ -599,6 +806,12 @@ dependencies = [ "smartstring", ] +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + [[package]] name = "ryu" version = "1.0.16" @@ -664,6 +877,12 @@ dependencies = [ "digest", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "slab" version = "0.4.9" @@ -708,6 +927,17 @@ dependencies = [ "smallvec", ] +[[package]] +name = "spin-executor" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7298013c6a0dc3361331cec17c744e45d76df7696d59b87801a9a3f5edbe0f54" +dependencies = [ + "futures", + "once_cell", + "wit-bindgen 0.16.0", +] + [[package]] name = "spin-macro" version = "2.2.0" @@ -724,9 +954,9 @@ dependencies = [ [[package]] name = "spin-macro" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a161ae2fefde8582ef555ead81d87cf897cd31a23a1d1e0c22a9c43fd9af421a" +checksum = "f3953755ea3415f4c0ecba8c5cdab51f05a5d2480b9bb8f2f42bf5a0ffaf18e6" dependencies = [ "anyhow", "bytes", @@ -766,13 +996,14 @@ dependencies = [ [[package]] name = "spin-sdk" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c02cf00c243c03fb330cb5be7bf4eb3c8db7c5476425068c7385ddff1567aa" +checksum = "eac0de7538d3986cc989ce3649d50b1d8f50ec46a0c9e62b4a14b911db6fe0de" dependencies = [ "anyhow", "async-trait", "bytes", + "chrono", "form_urlencoded", "futures", "http 1.1.0", @@ -780,7 +1011,8 @@ dependencies = [ "routefinder", "serde", "serde_json", - "spin-macro 3.0.0", + "spin-executor", + "spin-macro 3.1.0", "thiserror", "wit-bindgen 0.16.0", ] @@ -864,6 +1096,22 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" + [[package]] name = "typenum" version = "1.17.0" @@ -937,6 +1185,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasi-config" version = "0.1.0" @@ -978,6 +1232,77 @@ dependencies = [ "wit-bindgen 0.34.0", ] +[[package]] +name = "wasi-otel-tracing" +version = "0.1.0" +dependencies = [ + "anyhow", + "http 0.2.11", + "opentelemetry", + "opentelemetry-wasi", + "opentelemetry_sdk", + "spin-sdk 3.1.0", + "wit-bindgen 0.30.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.98", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + [[package]] name = "wasm-encoder" version = "0.36.2" @@ -1005,6 +1330,16 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb56df3e06b8e6b77e37d2969a50ba51281029a9aeb3855e76b7f49b6418847" +dependencies = [ + "leb128", + "wasmparser 0.215.0", +] + [[package]] name = "wasm-encoder" version = "0.219.2" @@ -1031,6 +1366,22 @@ dependencies = [ "wasmparser 0.121.2", ] +[[package]] +name = "wasm-metadata" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6bb07c5576b608f7a2a9baa2294c1a3584a249965d695a9814a496cb6d232f" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_derive", + "serde_json", + "spdx", + "wasm-encoder 0.215.0", + "wasmparser 0.215.0", +] + [[package]] name = "wasm-metadata" version = "0.219.2" @@ -1078,6 +1429,19 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fbde0881f24199b81cf49b6ff8f9c145ac8eb1b7fc439adb5c099734f7d90e" +dependencies = [ + "ahash", + "bitflags", + "hashbrown", + "indexmap", + "semver", +] + [[package]] name = "wasmparser" version = "0.219.2" @@ -1091,6 +1455,85 @@ dependencies = [ "semver", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "wit-bindgen" version = "0.13.1" @@ -1111,13 +1554,23 @@ dependencies = [ "wit-bindgen-rust-macro 0.16.0", ] +[[package]] +name = "wit-bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4bac478334a647374ff24a74b66737a4cb586dc8288bc3080a93252cd1105c" +dependencies = [ + "wit-bindgen-rt 0.30.0", + "wit-bindgen-rust-macro 0.30.0", +] + [[package]] name = "wit-bindgen" version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e11ad55616555605a60a8b2d1d89e006c2076f46c465c892cc2c153b20d4b30" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen-rt 0.34.0", "wit-bindgen-rust-macro 0.34.0", ] @@ -1143,6 +1596,17 @@ dependencies = [ "wit-parser 0.13.0", ] +[[package]] +name = "wit-bindgen-core" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7e3df01cd43cfa1cb52602e4fc05cb2b62217655f6705639b6953eb0a3fed2" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser 0.215.0", +] + [[package]] name = "wit-bindgen-core" version = "0.34.0" @@ -1154,6 +1618,15 @@ dependencies = [ "wit-parser 0.219.2", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2de7a3b06b9725d129b5cbd1beca968feed919c433305a23da46843185ecdd6" +dependencies = [ + "bitflags", +] + [[package]] name = "wit-bindgen-rt" version = "0.34.0" @@ -1189,6 +1662,22 @@ dependencies = [ "wit-component 0.18.2", ] +[[package]] +name = "wit-bindgen-rust" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a767d1a8eb4e908bfc53febc48b87ada545703b16fe0148ee7736a29a01417" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap", + "prettyplease", + "syn 2.0.98", + "wasm-metadata 0.215.0", + "wit-bindgen-core 0.30.0", + "wit-component 0.215.0", +] + [[package]] name = "wit-bindgen-rust" version = "0.34.0" @@ -1235,6 +1724,21 @@ dependencies = [ "wit-component 0.18.2", ] +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b185c342d0d27bd83d4080f5a66cf3b4f247fa49d679bceb66e11cc7eb58b99" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.98", + "wit-bindgen-core 0.30.0", + "wit-bindgen-rust 0.30.0", +] + [[package]] name = "wit-bindgen-rust-macro" version = "0.34.0" @@ -1288,6 +1792,25 @@ dependencies = [ "wit-parser 0.13.0", ] +[[package]] +name = "wit-component" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f725e3885fc5890648be5c5cbc1353b755dc932aa5f1aa7de968b912a3280743" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder 0.215.0", + "wasm-metadata 0.215.0", + "wasmparser 0.215.0", + "wit-parser 0.215.0", +] + [[package]] name = "wit-component" version = "0.219.2" @@ -1341,6 +1864,24 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "wit-parser" +version = "0.215.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935a97eaffd57c3b413aa510f8f0b550a4a9fe7d59e79cd8b89a83dcb860321f" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.215.0", +] + [[package]] name = "wit-parser" version = "0.219.2" @@ -1365,6 +1906,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/tests/test-components/components/otel-smoke-test/Cargo.toml b/tests/test-components/components/otel-smoke-test/Cargo.toml new file mode 100644 index 0000000000..521468b790 --- /dev/null +++ b/tests/test-components/components/otel-smoke-test/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "otel-smoke-test" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +anyhow = "1" +http = "0.2" +spin-sdk = "2.2.0" diff --git a/tests/test-components/components/otel-smoke-test/src/lib.rs b/tests/test-components/components/otel-smoke-test/src/lib.rs new file mode 100644 index 0000000000..85c4326102 --- /dev/null +++ b/tests/test-components/components/otel-smoke-test/src/lib.rs @@ -0,0 +1,22 @@ +use spin_sdk::{ + http::{Method, Params, Request, Response, Router}, + http_component, +}; + +#[http_component] +fn handle(req: http::Request<()>) -> Response { + let mut router = Router::new(); + router.get_async("/one", one); + router.get_async("/two", two); + router.handle(req) +} + +async fn one(_req: Request, _params: Params) -> Response { + let req = Request::builder().method(Method::Get).uri("/two").build(); + let _res: Response = spin_sdk::http::send(req).await.unwrap(); + Response::new(200, "") +} + +async fn two(_req: Request, _params: Params) -> Response { + Response::new(201, "") +} diff --git a/tests/test-components/components/wasi-otel-tracing/Cargo.toml b/tests/test-components/components/wasi-otel-tracing/Cargo.toml new file mode 100644 index 0000000000..e4356e29e1 --- /dev/null +++ b/tests/test-components/components/wasi-otel-tracing/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "wasi-otel-tracing" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +anyhow = "1" +http = "0.2" +opentelemetry = "0.27.0" +opentelemetry_sdk = "0.27.0" +opentelemetry-wasi = { git = "https://github.com/calebschoepp/opentelemetry-wasi", rev = "bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed" } +spin-sdk = "3.1.0" +wit-bindgen = "0.30.0" diff --git a/tests/test-components/components/wasi-otel-tracing/src/lib.rs b/tests/test-components/components/wasi-otel-tracing/src/lib.rs new file mode 100644 index 0000000000..8fc55e4e43 --- /dev/null +++ b/tests/test-components/components/wasi-otel-tracing/src/lib.rs @@ -0,0 +1,130 @@ +use std::time; + +use opentelemetry::{ + global::{self, BoxedTracer, ObjectSafeSpan}, + trace::{TraceContextExt, Tracer}, + Array, Context, ContextGuard, KeyValue, Value, +}; +use opentelemetry_sdk::trace::TracerProvider; +use opentelemetry_wasi::WasiPropagator; +use spin_sdk::{ + http::{IntoResponse, Method, Params, Request, Response, Router}, + http_component, +}; + +#[http_component] +fn handle(req: Request) -> anyhow::Result { + let mut router = Router::new(); + router.get("/nested-spans", nested_spans); + router.get("/setting-attributes", setting_attributes); + router.get_async("/host-guest-host", host_guest_host); + router.get("/events", events); + router.get("/links", links); + router.get_async("/root-span", root_span); + Ok(router.handle(req)) +} + +fn setup_tracer(propagate_context: bool) -> (BoxedTracer, Option) { + // Set up a tracer using the WASI processor + let wasi_processor = opentelemetry_wasi::WasiProcessor::new(); + let tracer_provider = TracerProvider::builder() + .with_span_processor(wasi_processor) + .build(); + global::set_tracer_provider(tracer_provider); + let tracer = global::tracer("wasi-otel-tracing"); + + if propagate_context { + let wasi_propagator = opentelemetry_wasi::TraceContextPropagator::new(); + ( + tracer, + Some(wasi_propagator.extract(&Context::current()).attach()), + ) + } else { + (tracer, None) + } +} + +fn nested_spans(_req: Request, _params: Params) -> Response { + let (tracer, _ctx) = setup_tracer(true); + tracer.in_span("outer_func", |_| { + tracer.in_span("inner_func", |_| {}); + }); + Response::new(200, "") +} + +fn setting_attributes(_req: Request, _params: Params) -> Response { + let (tracer, _ctx) = setup_tracer(true); + tracer.in_span("setting_attributes", |cx| { + let span = cx.span(); + span.set_attribute(KeyValue::new("foo", "bar")); + span.set_attribute(KeyValue::new("foo", "baz")); + span.set_attribute(KeyValue::new( + "qux", + Value::Array(Array::String(vec!["qaz".into(), "thud".into()])), + )); + }); + + Response::new(200, "") +} + +async fn host_guest_host(_req: Request, _params: Params) -> Response { + let (tracer, _ctx) = setup_tracer(true); + let mut span = tracer.start("guest"); + make_request().await; + span.end(); + + Response::new(200, "") +} + +fn events(_req: Request, _params: Params) -> Response { + let (tracer, _ctx) = setup_tracer(true); + tracer.in_span("events", |cx| { + let span = cx.span(); + span.add_event("basic-event".to_string(), vec![]); + span.add_event( + "event-with-attributes".to_string(), + vec![KeyValue::new("foo", true)], + ); + let time = time::SystemTime::now() + .duration_since(time::UNIX_EPOCH) + .unwrap(); + let time = time.as_secs_f64(); + let time = time::Duration::from_secs_f64(time + 1.0); + let time = time::SystemTime::UNIX_EPOCH + time; + span.add_event_with_timestamp("event-with-timestamp", time, vec![]); + }); + Response::new(200, "") +} + +fn links(_req: Request, _params: Params) -> Response { + let (tracer, _ctx) = setup_tracer(true); + let mut first = tracer.start("first"); + first.end(); + let mut second = tracer.start("second"); + second.add_link( + first.span_context().clone(), + vec![KeyValue::new("foo", "bar")], + ); + second.end(); + Response::new(200, "") +} + +async fn root_span(_req: Request, _params: Params) -> Response { + let (tracer, _ctx) = setup_tracer(false); + let mut span = tracer.start("root"); + make_request().await; + span.end(); + Response::new(200, "") +} + +async fn make_request() { + let req = Request::builder() + .method(Method::Get) + .uri("https://asdf.com") + .build(); + let _res: Response = spin_sdk::http::send(req).await.unwrap(); +} + +// TODO: Test what happens if start is called but not end +// TODO: Test what happens if end is called but not start +// TODO: What happens if child span outlives parent diff --git a/tests/testcases/otel-smoke-test/spin.toml b/tests/testcases/otel-smoke-test/spin.toml index a4eb09f671..909149421f 100644 --- a/tests/testcases/otel-smoke-test/spin.toml +++ b/tests/testcases/otel-smoke-test/spin.toml @@ -1,12 +1,13 @@ spin_version = "1" authors = ["Fermyon Engineering "] -description = "A simple application that returns hello and goodbye." -name = "head-rust-sdk-http" +description = "A simple application that tests otel." +name = "otel-smoke-test" trigger = { type = "http" } version = "1.0.0" [[component]] -id = "hello" -source = "%{source=hello-world}" +id = "otel" +source = "%{source=otel-smoke-test}" +allowed_outbound_hosts = ["http://self"] [component.trigger] -route = "/hello/..." +route = "/..." diff --git a/tests/testcases/wasi-otel-tracing/spin.toml b/tests/testcases/wasi-otel-tracing/spin.toml new file mode 100644 index 0000000000..a54f57210b --- /dev/null +++ b/tests/testcases/wasi-otel-tracing/spin.toml @@ -0,0 +1,19 @@ +spin_manifest_version = 2 + +[application] +authors = ["Fermyon Engineering "] +description = "An application to exercise wasi-otel tracing functionality." +name = "wasi-otel-tracing" +version = "1.0.0" + +[[trigger.http]] +route = "/..." +component = "wasi-otel-tracing" + +[component.wasi-otel-tracing] +source = "%{source=wasi-otel-tracing}" +key_value_stores = ["default"] +allowed_outbound_hosts = ["http://self", "https://asdf.com"] +[component.wasi-otel-tracing.build] +command = "cargo build --target wasm32-wasi --release" +watch = ["src/**/*.rs", "Cargo.toml"] diff --git a/wit/deps/otel/tracing.wit b/wit/deps/otel/tracing.wit new file mode 100644 index 0000000000..8ac7385652 --- /dev/null +++ b/wit/deps/otel/tracing.wit @@ -0,0 +1,168 @@ +interface tracing { + use wasi:clocks/wall-clock@0.2.0.{datetime}; + + /// Called when a span is started. + on-start: func(context: span-context); + + /// Called when a span is ended. + on-end: func(span: span-data); + + /// Returns the span context of the host. + outer-span-context: func() -> span-context; + + /// The data associated with a span. + record span-data { + /// Span context. + span-context: span-context, + /// Span parent id. + parent-span-id: string, + /// Span kind. + span-kind: span-kind, + // Span name. + name: string, + /// Span start time. + start-time: datetime, + /// Span end time. + end-time: datetime, + /// Span attributes. + attributes: list, + /// Span events. + events: list, + /// Span Links. + links: list, + /// Span status. + status: status, + /// Instrumentation scope that produced this span. + instrumentation-scope: instrumentation-scope, + /// Number of attributes dropped by the span due to limits being reached. + dropped-attributes: u32, + /// Number of events dropped by the span due to limits being reached. + dropped-events: u32, + /// Number of links dropped by the span due to limits being reached. + dropped-links: u32, + } + + /// Identifying trace information about a span that can be serialized and propagated. + record span-context { + /// The `trace-id` for this `span-context`. + trace-id: trace-id, + /// The `span-id` for this `span-context`. + span-id: span-id, + /// The `trace-flags` for this `span-context`. + trace-flags: trace-flags, + /// Whether this `span-context` was propagated from a remote parent. + is-remote: bool, + /// The `trace-state` for this `span-context`. + trace-state: trace-state, + } + + /// The trace that this `span-context` belongs to. + /// + /// 16 bytes encoded as a hexadecimal string. + type trace-id = string; + + /// The id of this `span-context`. + /// + /// 8 bytes encoded as a hexadecimal string. + type span-id = string; + + /// Flags that can be set on a `span-context`. + flags trace-flags { + /// Whether the `span` should be sampled or not. + sampled, + } + + /// Carries system-specific configuration data, represented as a list of key-value pairs. `trace-state` allows multiple tracing systems to participate in the same trace. + /// + /// If any invalid keys or values are provided then the `trace-state` will be treated as an empty list. + type trace-state = list>; + + /// Describes the relationship between the Span, its parents, and its children in a trace. + enum span-kind { + /// Indicates that the span describes a request to some remote service. This span is usually the parent of a remote server span and does not end until the response is received. + client, + /// Indicates that the span covers server-side handling of a synchronous RPC or other remote request. This span is often the child of a remote client span that was expected to wait for a response. + server, + /// Indicates that the span describes the initiators of an asynchronous request. This parent span will often end before the corresponding child consumer span, possibly even before the child span starts. In messaging scenarios with batching, tracing individual messages requires a new producer span per message to be created. + producer, + /// Indicates that the span describes a child of an asynchronous consumer request. + consumer, + /// Default value. Indicates that the span represents an internal operation within an application, as opposed to an operations with remote parents or children. + internal + } + + /// A key-value pair describing an attribute. + record key-value { + /// The attribute name. + key: key, + /// The attribute value. + value: value, + } + + /// The key part of attribute `key-value` pairs. + type key = string; + + /// The value part of attribute `key-value` pairs. + variant value { + /// A string value. + %string(string), + /// A boolean value. + %bool(bool), + /// A double precision floating point value. + %f64(f64), + /// A signed 64 bit integer value. + %s64(s64), + /// A homogeneous array of string values. + string-array(list), + /// A homogeneous array of boolean values. + bool-array(list), + /// A homogeneous array of double precision floating point values. + f64-array(list), + /// A homogeneous array of 64 bit integer values. + s64-array(list), + } + + /// An event describing a specific moment in time on a span and associated attributes. + record event { + /// Event name. + name: string, + /// Event time. + time: datetime, + /// Event attributes. + attributes: list, + } + + /// Describes a relationship to another `span`. + record link { + /// Denotes which `span` to link to. + span-context: span-context, + /// Attributes describing the link. + attributes: list, + } + + /// The `status` of a `span`. + variant status { + /// The default status. + unset, + /// The operation has been validated by an Application developer or Operator to have completed successfully. + ok, + /// The operation contains an error with a description. + error(string), + } + + /// Describes the instrumentation scope that produced a span. + record instrumentation-scope { + /// Name of the instrumentation scope. + name: string, + + /// The library version. + version: option, + + /// Schema URL used by this library. + /// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/schemas/overview.md#schema-url + schema-url: option, + + /// Specifies the instrumentation scope attributes to associate with emitted telemetry. + attributes: list, + } +} diff --git a/wit/deps/otel/world.wit b/wit/deps/otel/world.wit new file mode 100644 index 0000000000..d1d9701abf --- /dev/null +++ b/wit/deps/otel/world.wit @@ -0,0 +1,5 @@ +package wasi:otel@0.2.0-draft; + +world imports { + import tracing; +} diff --git a/wit/world.wit b/wit/world.wit index b5d66b3b2f..5ec241aeeb 100644 --- a/wit/world.wit +++ b/wit/world.wit @@ -8,6 +8,7 @@ world http-trigger { /// The imports needed for a guest to run on a Spin host world platform { + include wasi:otel/imports@0.2.0-draft; include fermyon:spin/platform@2.0.0; include wasi:keyvalue/imports@0.2.0-draft2; import spin:postgres/postgres@3.0.0; From 651b1e2aa1abe50c542dd430f07c8e380dbf32a3 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Fri, 25 Jul 2025 12:53:22 -0500 Subject: [PATCH 02/10] fix: update opentelemetry version Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- Cargo.toml | 6 +- crates/factor-otel/Cargo.toml | 2 +- crates/factor-otel/src/lib.rs | 34 ++++---- crates/factor-outbound-mqtt/src/host.rs | 1 + crates/factor-outbound-mysql/src/lib.rs | 2 - crates/factor-outbound-redis/src/host.rs | 1 - crates/factor-sqlite/src/lib.rs | 1 - crates/telemetry/Cargo.toml | 6 +- crates/trigger-http/src/wasi.rs | 1 + crates/world/src/conversions.rs | 2 +- tests/test-components/components/Cargo.lock | 83 +++++++++++++++---- .../components/wasi-otel-tracing/Cargo.toml | 4 +- .../components/wasi-otel-tracing/src/lib.rs | 4 +- 13 files changed, 98 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 76bfb5fd6f..b030d88b01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ openssl = { version = "0.10" } anyhow = { workspace = true, features = ["backtrace"] } conformance = { path = "tests/conformance-tests" } conformance-tests = { workspace = true } -fake-opentelemetry-collector = "0.21.1" +fake-opentelemetry-collector = "0.26" hex = "0.4" http-body-util = { workspace = true } hyper = { workspace = true } @@ -143,6 +143,9 @@ hyper-util = { version = "0.1", features = ["tokio"] } indexmap = "2" itertools = "0.14" lazy_static = "1.5" +opentelemetry = "0.28" +opentelemetry-otlp = "0.28" +opentelemetry_sdk = "0.28" path-absolutize = "3" quote = "1" rand = "0.9" @@ -169,6 +172,7 @@ toml = "0.8" toml_edit = "0.22" tower-service = "0.3.3" tracing = { version = "0.1.41", features = ["log"] } +tracing-opentelemetry = "0.29" url = "2" walkdir = "2" wasm-encoder = "0.236.1" diff --git a/crates/factor-otel/Cargo.toml b/crates/factor-otel/Cargo.toml index 22df37e1a4..41f9498802 100644 --- a/crates/factor-otel/Cargo.toml +++ b/crates/factor-otel/Cargo.toml @@ -9,7 +9,7 @@ anyhow = { workspace = true } indexmap = "2.2.6" opentelemetry = { workspace = true } opentelemetry_sdk = { workspace = true } -opentelemetry-otlp = { version = "0.27", features = ["http-proto", "http", "reqwest-client"] } +opentelemetry-otlp = { workspace = true, features = ["http-proto", "http", "reqwest-client"] } spin-core = { path = "../core" } spin-factors = { path = "../factors" } spin-resource-table = { path = "../table" } diff --git a/crates/factor-otel/src/lib.rs b/crates/factor-otel/src/lib.rs index 4f36da6125..46bae13f25 100644 --- a/crates/factor-otel/src/lib.rs +++ b/crates/factor-otel/src/lib.rs @@ -2,7 +2,6 @@ mod host; use std::{ sync::{Arc, RwLock}, - time::Duration, }; use anyhow::bail; @@ -13,16 +12,15 @@ use opentelemetry::{ }; use opentelemetry_sdk::{ resource::{EnvResourceDetector, TelemetryResourceDetector}, - runtime::Tokio, trace::{BatchSpanProcessor, SpanProcessor}, Resource, }; -use spin_factors::{Factor, PrepareContext, RuntimeFactors, SelfInstanceBuilder}; +use spin_factors::{Factor, FactorData, PrepareContext, RuntimeFactors, SelfInstanceBuilder}; use spin_telemetry::{detector::SpinResourceDetector, env::OtlpProtocol}; use tracing_opentelemetry::OpenTelemetrySpanExt; pub struct OtelFactor { - processor: Arc>, + processor: Arc, } impl Factor for OtelFactor { @@ -30,11 +28,8 @@ impl Factor for OtelFactor { type AppState = (); type InstanceBuilder = InstanceState; - fn init( - &mut self, - mut ctx: spin_factors::InitContext, - ) -> anyhow::Result<()> { - ctx.link_bindings(spin_world::wasi::otel::tracing::add_to_linker)?; + fn init(&mut self, ctx: &mut impl spin_factors::InitContext) -> anyhow::Result<()> { + ctx.link_bindings(spin_world::wasi::otel::tracing::add_to_linker::<_, FactorData>)?; Ok(()) } @@ -71,16 +66,13 @@ impl OtelFactor { .build()?, OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"), }; - let mut processor = opentelemetry_sdk::trace::BatchSpanProcessor::builder( - exporter, - opentelemetry_sdk::runtime::Tokio, - ) - .build(); + + let mut processor = opentelemetry_sdk::trace::BatchSpanProcessor::builder(exporter).build(); + // This is a hack b/c we know the version of this crate will be the same as the version of Spin let spin_version = env!("CARGO_PKG_VERSION").to_string(); - processor.set_resource(&Resource::from_detectors( - Duration::from_secs(5), - vec![ + + let detectors: &[Box; 3] = &[ // Set service.name from env OTEL_SERVICE_NAME > env OTEL_RESOURCE_ATTRIBUTES > spin // Set service.version from Spin metadata Box::new(SpinResourceDetector::new(spin_version)), @@ -88,8 +80,10 @@ impl OtelFactor { Box::new(EnvResourceDetector::new()), // Sets telemetry.sdk{name, language, version} Box::new(TelemetryResourceDetector), - ], - )); + ]; + + processor.set_resource(&Resource::builder().with_detectors(detectors).build()); + Ok(Self { processor: Arc::new(processor), }) @@ -98,7 +92,7 @@ impl OtelFactor { pub struct InstanceState { pub(crate) state: Arc>, - pub(crate) processor: Arc>, + pub(crate) processor: Arc, } impl SelfInstanceBuilder for InstanceState {} diff --git a/crates/factor-outbound-mqtt/src/host.rs b/crates/factor-outbound-mqtt/src/host.rs index 6fb17182f2..53cb6a9830 100644 --- a/crates/factor-outbound-mqtt/src/host.rs +++ b/crates/factor-outbound-mqtt/src/host.rs @@ -4,6 +4,7 @@ use anyhow::Result; use spin_core::{async_trait, wasmtime::component::Resource}; use spin_factor_outbound_networking::config::allowed_hosts::OutboundAllowedHosts; use spin_world::v2::mqtt::{self as v2, Connection, Error, Qos}; +use spin_factor_otel::OtelContext; use tracing::{instrument, Level}; use crate::ClientCreator; diff --git a/crates/factor-outbound-mysql/src/lib.rs b/crates/factor-outbound-mysql/src/lib.rs index 0bf63805ef..e1bf9aabdb 100644 --- a/crates/factor-outbound-mysql/src/lib.rs +++ b/crates/factor-outbound-mysql/src/lib.rs @@ -7,9 +7,7 @@ use spin_factor_otel::OtelContext; use spin_factor_outbound_networking::{ config::allowed_hosts::OutboundAllowedHosts, OutboundNetworkingFactor, }; -use spin_factor_outbound_networking::{OutboundAllowedHosts, OutboundNetworkingFactor}; use spin_factors::{Factor, FactorData, InitContext, RuntimeFactors, SelfInstanceBuilder}; -use spin_factors::{Factor, InitContext, RuntimeFactors, SelfInstanceBuilder}; use spin_world::v1::mysql as v1; use spin_world::v2::mysql::{self as v2}; diff --git a/crates/factor-outbound-redis/src/host.rs b/crates/factor-outbound-redis/src/host.rs index c260b453d1..61a00eb5ae 100644 --- a/crates/factor-outbound-redis/src/host.rs +++ b/crates/factor-outbound-redis/src/host.rs @@ -3,7 +3,6 @@ use redis::{aio::MultiplexedConnection, AsyncCommands, FromRedisValue, Value}; use spin_core::wasmtime::component::Resource; use spin_factor_outbound_networking::config::allowed_hosts::OutboundAllowedHosts; use spin_factor_otel::OtelContext; -use spin_factor_outbound_networking::OutboundAllowedHosts; use spin_world::v1::{redis as v1, redis_types}; use spin_world::v2::redis::{ self as v2, Connection as RedisConnection, Error, RedisParameter, RedisResult, diff --git a/crates/factor-sqlite/src/lib.rs b/crates/factor-sqlite/src/lib.rs index 6298d6ae7a..ae3b4686e0 100644 --- a/crates/factor-sqlite/src/lib.rs +++ b/crates/factor-sqlite/src/lib.rs @@ -9,7 +9,6 @@ use host::InstanceState; use async_trait::async_trait; use spin_factors::{anyhow, Factor, FactorData}; use spin_factor_otel::OtelContext; -use spin_factors::{anyhow, Factor}; use spin_locked_app::MetadataKey; use spin_world::spin::sqlite::sqlite as v3; use spin_world::v1::sqlite as v1; diff --git a/crates/telemetry/Cargo.toml b/crates/telemetry/Cargo.toml index bf5079ac37..0ef7d9150f 100644 --- a/crates/telemetry/Cargo.toml +++ b/crates/telemetry/Cargo.toml @@ -10,11 +10,11 @@ http0 = { version = "0.2.9", package = "http" } http1 = { version = "1.0.0", package = "http" } opentelemetry = { version = "0.28", features = ["metrics", "trace", "logs"] } opentelemetry-appender-tracing = "0.28" -opentelemetry-otlp = { version = "0.28", features = ["grpc-tonic"] } -opentelemetry_sdk = { version = "0.28", features = ["rt-tokio", "spec_unstable_logs_enabled", "metrics"] } +opentelemetry-otlp = { workspace = true, features = ["grpc-tonic"] } +opentelemetry_sdk = { workspace = true, features = ["rt-tokio", "spec_unstable_logs_enabled", "metrics"] } terminal = { path = "../terminal" } tracing = { workspace = true } -tracing-opentelemetry = { version = "0.29", default-features = false, features = ["metrics"] } +tracing-opentelemetry = { workspace = true, default-features = false, features = ["metrics"] } tracing-subscriber = { version = "0.3", default-features = false, features = ["smallvec", "fmt", "ansi", "std", "env-filter", "json", "registry"] } [features] diff --git a/crates/trigger-http/src/wasi.rs b/crates/trigger-http/src/wasi.rs index 0afbbf3fb9..cb08557c5d 100644 --- a/crates/trigger-http/src/wasi.rs +++ b/crates/trigger-http/src/wasi.rs @@ -93,6 +93,7 @@ impl HttpExecutor for WasiHttpExecutor<'_> { HandlerType::Wagi(_) => unreachable!("should have used WagiExecutor instead"), }; + let span = tracing::debug_span!("execute_wasi"); let handle = task::spawn( async move { let result = match handler { diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index b9145f8d09..27b2d3705b 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -562,7 +562,7 @@ mod otel { use wasi::clocks0_2_0::wall_clock; use wasi::otel::tracing as wasi_otel; - impl From for opentelemetry_sdk::export::trace::SpanData { + impl From for opentelemetry_sdk::trace::SpanData { fn from(value: wasi_otel::SpanData) -> Self { let mut span_events = SpanEvents::default(); span_events.events = value.events.into_iter().map(Into::into).collect(); diff --git a/tests/test-components/components/Cargo.lock b/tests/test-components/components/Cargo.lock index 54ff180e7c..407be6e74a 100644 --- a/tests/test-components/components/Cargo.lock +++ b/tests/test-components/components/Cargo.lock @@ -45,9 +45,9 @@ checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -89,9 +89,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" @@ -627,7 +627,21 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror", + "thiserror 1.0.56", + "tracing", +] + +[[package]] +name = "opentelemetry" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236e667b670a5cdf90c258f5a55794ec5ac5027e960c224bff8367a59e1e6426" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror 2.0.12", "tracing", ] @@ -637,8 +651,8 @@ version = "0.27.0" source = "git+https://github.com/calebschoepp/opentelemetry-wasi?rev=bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed#bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed" dependencies = [ "anyhow", - "opentelemetry", - "opentelemetry_sdk", + "opentelemetry 0.27.1", + "opentelemetry_sdk 0.27.1", "wit-bindgen 0.30.0", ] @@ -653,11 +667,30 @@ dependencies = [ "futures-executor", "futures-util", "glob", - "opentelemetry", + "opentelemetry 0.27.1", "percent-encoding", "rand", "serde_json", - "thiserror", + "thiserror 1.0.56", + "tracing", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84dfad6042089c7fc1f6118b7040dc2eb4ab520abbf410b79dc481032af39570" +dependencies = [ + "async-trait", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "opentelemetry 0.28.0", + "percent-encoding", + "rand", + "serde_json", + "thiserror 2.0.12", "tracing", ] @@ -863,7 +896,7 @@ checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" dependencies = [ "percent-encoding", "serde", - "thiserror", + "thiserror 1.0.56", ] [[package]] @@ -990,7 +1023,7 @@ dependencies = [ "serde", "serde_json", "spin-macro 2.2.0", - "thiserror", + "thiserror 1.0.56", "wit-bindgen 0.13.1", ] @@ -1013,7 +1046,7 @@ dependencies = [ "serde_json", "spin-executor", "spin-macro 3.1.0", - "thiserror", + "thiserror 1.0.56", "wit-bindgen 0.16.0", ] @@ -1067,7 +1100,16 @@ version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.56", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -1081,6 +1123,17 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1238,9 +1291,9 @@ version = "0.1.0" dependencies = [ "anyhow", "http 0.2.11", - "opentelemetry", + "opentelemetry 0.28.0", "opentelemetry-wasi", - "opentelemetry_sdk", + "opentelemetry_sdk 0.28.0", "spin-sdk 3.1.0", "wit-bindgen 0.30.0", ] diff --git a/tests/test-components/components/wasi-otel-tracing/Cargo.toml b/tests/test-components/components/wasi-otel-tracing/Cargo.toml index e4356e29e1..83610c6ea2 100644 --- a/tests/test-components/components/wasi-otel-tracing/Cargo.toml +++ b/tests/test-components/components/wasi-otel-tracing/Cargo.toml @@ -9,8 +9,8 @@ crate-type = ["cdylib"] [dependencies] anyhow = "1" http = "0.2" -opentelemetry = "0.27.0" -opentelemetry_sdk = "0.27.0" +opentelemetry = "0.28.0" +opentelemetry_sdk = "0.28.0" opentelemetry-wasi = { git = "https://github.com/calebschoepp/opentelemetry-wasi", rev = "bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed" } spin-sdk = "3.1.0" wit-bindgen = "0.30.0" diff --git a/tests/test-components/components/wasi-otel-tracing/src/lib.rs b/tests/test-components/components/wasi-otel-tracing/src/lib.rs index 8fc55e4e43..c7d427b8bc 100644 --- a/tests/test-components/components/wasi-otel-tracing/src/lib.rs +++ b/tests/test-components/components/wasi-otel-tracing/src/lib.rs @@ -5,7 +5,7 @@ use opentelemetry::{ trace::{TraceContextExt, Tracer}, Array, Context, ContextGuard, KeyValue, Value, }; -use opentelemetry_sdk::trace::TracerProvider; +use opentelemetry_sdk::trace::SdkTracerProvider; use opentelemetry_wasi::WasiPropagator; use spin_sdk::{ http::{IntoResponse, Method, Params, Request, Response, Router}, @@ -27,7 +27,7 @@ fn handle(req: Request) -> anyhow::Result { fn setup_tracer(propagate_context: bool) -> (BoxedTracer, Option) { // Set up a tracer using the WASI processor let wasi_processor = opentelemetry_wasi::WasiProcessor::new(); - let tracer_provider = TracerProvider::builder() + let tracer_provider = SdkTracerProvider::builder() .with_span_processor(wasi_processor) .build(); global::set_tracer_provider(tracer_provider); From 002bc3afc44b5411a00db3188c7d85772fed3961 Mon Sep 17 00:00:00 2001 From: Caleb Schoepp Date: Fri, 29 Aug 2025 15:49:12 -0600 Subject: [PATCH 03/10] Fix out of date Cargo.lock from bad rebase Signed-off-by: Caleb Schoepp --- Cargo.lock | 112 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b4c8cb3d9..dfc16801e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1499,7 +1499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" dependencies = [ "serde", - "toml", + "toml 0.8.19", ] [[package]] @@ -1747,7 +1747,7 @@ dependencies = [ "rust-ini", "serde", "serde_json", - "toml", + "toml 0.8.19", "yaml-rust2", ] @@ -2821,6 +2821,25 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "fake-opentelemetry-collector" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce713bed1dfc379216421ebf0c4ee2268b5cb4d7894bed8a96d267834590916" +dependencies = [ + "futures", + "hex", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-proto", + "opentelemetry_sdk", + "serde", + "tokio", + "tokio-stream", + "tonic", + "tracing", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -5998,6 +6017,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84dfad6042089c7fc1f6118b7040dc2eb4ab520abbf410b79dc481032af39570" dependencies = [ + "async-std", "async-trait", "futures-channel", "futures-executor", @@ -8228,7 +8248,7 @@ dependencies = [ "spin-factors-test", "spin-locked-app", "tokio", - "toml", + "toml 0.8.19", ] [[package]] @@ -8243,7 +8263,7 @@ dependencies = [ "subprocess", "terminal", "tokio", - "toml", + "toml 0.8.19", ] [[package]] @@ -8262,6 +8282,7 @@ dependencies = [ "conformance-tests", "ctrlc", "dialoguer", + "fake-opentelemetry-collector", "futures", "hex", "http 1.1.0", @@ -8312,7 +8333,7 @@ dependencies = [ "test-environment", "testing-framework", "tokio", - "toml", + "toml 0.8.19", "tracing", "url", "uuid", @@ -8347,7 +8368,7 @@ dependencies = [ "serde_json", "tempfile", "tokio", - "toml", + "toml 0.8.19", "tracing", "wasm-encoder 0.236.1", "wasm-metadata 0.236.1", @@ -8409,7 +8430,7 @@ dependencies = [ "tempfile", "terminal", "tokio", - "toml", + "toml 0.8.19", "toml_edit", "tracing", "ui-testing", @@ -8438,7 +8459,7 @@ dependencies = [ "spin-manifest", "spin-serde", "tokio", - "toml", + "toml 0.8.19", "tracing", "wac-graph", "wac-types", @@ -8459,7 +8480,7 @@ dependencies = [ "spin-locked-app", "thiserror 2.0.12", "tokio", - "toml", + "toml 0.8.19", ] [[package]] @@ -8469,6 +8490,7 @@ dependencies = [ "anyhow", "serde", "spin-core", + "spin-factor-otel", "spin-factors", "spin-factors-test", "spin-key-value-redis", @@ -8480,7 +8502,7 @@ dependencies = [ "tempfile", "thiserror 2.0.12", "tokio", - "toml", + "toml 0.8.19", "tracing", ] @@ -8491,6 +8513,7 @@ dependencies = [ "anyhow", "async-trait", "serde", + "spin-factor-otel", "spin-factors", "spin-factors-test", "spin-llm-local", @@ -8499,11 +8522,30 @@ dependencies = [ "spin-telemetry", "spin-world", "tokio", - "toml", + "toml 0.8.19", "tracing", "url", ] +[[package]] +name = "spin-factor-otel" +version = "3.5.0-pre0" +dependencies = [ + "anyhow", + "indexmap 2.7.1", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry_sdk", + "spin-core", + "spin-factors", + "spin-resource-table", + "spin-telemetry", + "spin-world", + "toml 0.5.11", + "tracing", + "tracing-opentelemetry", +] + [[package]] name = "spin-factor-outbound-http" version = "3.5.0-pre0" @@ -8517,6 +8559,7 @@ dependencies = [ "reqwest 0.12.9", "rustls 0.23.18", "serde", + "spin-factor-otel", "spin-factor-outbound-networking", "spin-factor-variables", "spin-factors", @@ -8539,6 +8582,7 @@ dependencies = [ "anyhow", "rumqttc", "spin-core", + "spin-factor-otel", "spin-factor-outbound-networking", "spin-factor-variables", "spin-factors", @@ -8556,6 +8600,7 @@ dependencies = [ "anyhow", "mysql_async", "spin-core", + "spin-factor-otel", "spin-factor-outbound-networking", "spin-factor-variables", "spin-factors", @@ -8588,7 +8633,7 @@ dependencies = [ "spin-serde", "tempfile", "tokio", - "toml", + "toml 0.8.19", "tracing", "url", "wasmtime-wasi", @@ -8610,6 +8655,7 @@ dependencies = [ "rust_decimal", "serde_json", "spin-core", + "spin-factor-otel", "spin-factor-outbound-networking", "spin-factor-variables", "spin-factors", @@ -8629,6 +8675,7 @@ dependencies = [ "anyhow", "redis 0.25.4", "spin-core", + "spin-factor-otel", "spin-factor-outbound-networking", "spin-factor-variables", "spin-factors", @@ -8644,6 +8691,7 @@ name = "spin-factor-sqlite" version = "3.5.0-pre0" dependencies = [ "async-trait", + "spin-factor-otel", "spin-factors", "spin-factors-test", "spin-locked-app", @@ -8658,6 +8706,7 @@ name = "spin-factor-variables" version = "3.5.0-pre0" dependencies = [ "spin-expressions", + "spin-factor-otel", "spin-factors", "spin-factors-test", "spin-telemetry", @@ -8689,7 +8738,7 @@ dependencies = [ "spin-app", "spin-factors-derive", "thiserror 2.0.12", - "toml", + "toml 0.8.19", "wasmtime", ] @@ -8725,7 +8774,7 @@ dependencies = [ "spin-loader", "spin-telemetry", "tempfile", - "toml", + "toml 0.8.19", ] [[package]] @@ -8743,7 +8792,7 @@ dependencies = [ "spin-app", "spin-factor-outbound-http", "spin-http-routes", - "toml", + "toml 0.8.19", "tracing", "wasmtime", "wasmtime-wasi", @@ -8873,7 +8922,7 @@ dependencies = [ "tempfile", "terminal", "tokio", - "toml", + "toml 0.8.19", "tracing", "ui-testing", "wasm-pkg-client", @@ -8906,7 +8955,7 @@ dependencies = [ "spin-serde", "terminal", "thiserror 2.0.12", - "toml", + "toml 0.8.19", "ui-testing", "url", "wasm-pkg-common", @@ -8999,6 +9048,7 @@ dependencies = [ "spin-expressions", "spin-factor-key-value", "spin-factor-llm", + "spin-factor-otel", "spin-factor-outbound-http", "spin-factor-outbound-mqtt", "spin-factor-outbound-mysql", @@ -9023,7 +9073,7 @@ dependencies = [ "spin-world", "tempfile", "tokio", - "toml", + "toml 0.8.19", ] [[package]] @@ -9035,6 +9085,7 @@ dependencies = [ "spin-common", "spin-factor-key-value", "spin-factor-llm", + "spin-factor-otel", "spin-factor-outbound-http", "spin-factor-outbound-mqtt", "spin-factor-outbound-mysql", @@ -9074,7 +9125,7 @@ dependencies = [ "spin-factors", "spin-sqlite-inproc", "spin-sqlite-libsql", - "toml", + "toml 0.8.19", ] [[package]] @@ -9146,7 +9197,7 @@ dependencies = [ "tempfile", "terminal", "tokio", - "toml", + "toml 0.8.19", "toml_edit", "url", "walkdir", @@ -9196,6 +9247,7 @@ dependencies = [ "serde_json", "spin-app", "spin-core", + "spin-factor-otel", "spin-factor-outbound-http", "spin-factor-outbound-networking", "spin-factor-wasi", @@ -9266,7 +9318,7 @@ dependencies = [ "spin-expressions", "spin-factors", "tempfile", - "toml", + "toml 0.8.19", ] [[package]] @@ -9284,7 +9336,10 @@ dependencies = [ name = "spin-world" version = "3.5.0-pre0" dependencies = [ + "anyhow", "async-trait", + "opentelemetry", + "opentelemetry_sdk", "wasmtime", ] @@ -9992,6 +10047,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.19" @@ -10942,7 +11006,7 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tokio-util", - "toml", + "toml 0.8.19", "tracing", "tracing-subscriber", "url", @@ -10971,7 +11035,7 @@ dependencies = [ "sha2", "thiserror 1.0.69", "tokio", - "toml", + "toml 0.8.19", ] [[package]] @@ -11163,7 +11227,7 @@ dependencies = [ "serde", "serde_derive", "sha2", - "toml", + "toml 0.8.19", "windows-sys 0.60.2", "zstd", ] From b22f90f017c37b8cc5aa2339486257a37210f89a Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:18:39 -0500 Subject: [PATCH 04/10] feat(factor-otel): adding metrics Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- Cargo.lock | 2919 +++++++++-------- Cargo.toml | 5 +- crates/factor-otel/Cargo.toml | 4 +- crates/factor-otel/src/host.rs | 27 +- crates/factor-otel/src/lib.rs | 66 +- crates/telemetry/src/metrics.rs | 5 +- crates/telemetry/src/traces.rs | 7 +- crates/world/src/conversions.rs | 628 +++- tests/test-components/components/Cargo.lock | 220 +- .../components/wasi-otel-tracing/Cargo.toml | 6 +- wit/deps/otel/metrics.wit | 272 ++ wit/deps/otel/tracing.wit | 48 +- wit/deps/otel/types.wit | 48 + wit/deps/otel/world.wit | 4 + 14 files changed, 2709 insertions(+), 1550 deletions(-) create mode 100644 wit/deps/otel/metrics.wit create mode 100644 wit/deps/otel/types.wit diff --git a/Cargo.lock b/Cargo.lock index dfc16801e6..5bef408169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,14 +17,14 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9acbfca36652500c911ddb767ed433e3ed99b032b5d935be73c6923662db1d43" dependencies = [ - "gimli 0.32.0", + "gimli 0.32.2", ] [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adler32" @@ -49,19 +49,21 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.3", "once_cell", + "serde", "version_check", "zerocopy", ] @@ -77,9 +79,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "ambient-authority" @@ -104,9 +106,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -119,43 +121,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" dependencies = [ "backtrace", ] @@ -168,9 +171,9 @@ checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] @@ -199,7 +202,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.1", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -218,9 +221,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ "concurrent-queue", "event-listener-strategy", @@ -230,10 +233,12 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.17" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb8f1d480b0ea3783ab015936d2a55c87e219676f0c0b7dec61494043f21857" +checksum = "5bee399cc3a623ec5a2db2c5b90ee0190a2260241fbe0c023ac8f7bab426aaf8" dependencies = [ + "compression-codecs", + "compression-core", "flate2", "futures-core", "memchr", @@ -243,26 +248,27 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.2.0", - "futures-lite 2.5.0", + "fastrand 2.3.0", + "futures-lite 2.6.1", + "pin-project-lite", "slab", ] [[package]] name = "async-fs" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +checksum = "09f7e37c0ed80b2a977691c47dae8625cfb21e205827106c64f7c588766b2e50" dependencies = [ "async-lock", "blocking", - "futures-lite 2.5.0", + "futures-lite 2.6.1", ] [[package]] @@ -271,41 +277,40 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.3.1", + "async-channel 2.5.0", "async-executor", "async-io", "async-lock", "blocking", - "futures-lite 2.5.0", + "futures-lite 2.6.1", "once_cell", ] [[package]] name = "async-io" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" dependencies = [ "async-lock", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.5.0", + "futures-lite 2.6.1", "parking", "polling", - "rustix 0.38.40", + "rustix 1.0.8", "slab", - "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.1", "event-listener-strategy", "pin-project-lite", ] @@ -327,21 +332,20 @@ dependencies = [ [[package]] name = "async-process" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00" dependencies = [ - "async-channel 2.3.1", + "async-channel 2.5.0", "async-io", "async-lock", "async-signal", "async-task", "blocking", "cfg-if", - "event-listener 5.3.1", - "futures-lite 2.5.0", - "rustix 0.38.40", - "tracing", + "event-listener 5.4.1", + "futures-lite 2.6.1", + "rustix 1.0.8", ] [[package]] @@ -352,14 +356,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "async-signal" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1" dependencies = [ "async-io", "async-lock", @@ -367,17 +371,17 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.40", + "rustix 1.0.8", "signal-hook-registry", "slab", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "async-std" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" dependencies = [ "async-channel 1.9.0", "async-global-executor", @@ -388,7 +392,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "futures-lite 2.5.0", + "futures-lite 2.6.1", "gloo-timers", "kv-log-macro", "log", @@ -419,7 +423,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -444,13 +448,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -490,15 +494,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.5.10" +version = "1.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b49afaa341e8dd8577e1a2200468f98956d6eda50bcf4a53246cc00174ba924" +checksum = "8bc1b40fb26027769f16960d2f4a6bc20c4bb755d403e552c8c1a73af433c246" dependencies = [ "aws-credential-types", "aws-runtime", @@ -513,9 +517,9 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes", - "fastrand 2.2.0", + "fastrand 2.3.0", "hex", - "http 0.2.12", + "http 1.3.1", "ring", "time", "tokio", @@ -526,9 +530,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.1" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60e8f6b615cb5fc60a98132268508ad104310f0cfb25a1c22eee76efdf9154da" +checksum = "d025db5d9f52cbc413b167136afb3d8aeea708c0d8884783cf6253be5e22f6f2" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -538,9 +542,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.4.3" +version = "1.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a10d5c055aa540164d9561a0e2e74ad30f0dcf7393c3a92f6733ddf9c5762468" +checksum = "c034a1bc1d70e16e7f4e4caf7e9f7693e4c9c24cd91cf17c2a0b21abaebc7c8b" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -551,10 +555,9 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes", - "fastrand 2.2.0", + "fastrand 2.3.0", "http 0.2.12", "http-body 0.4.6", - "once_cell", "percent-encoding", "pin-project-lite", "tracing", @@ -563,9 +566,9 @@ dependencies = [ [[package]] name = "aws-sdk-dynamodb" -version = "1.53.0" +version = "1.92.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6355a9536b92daf4c4b7d4d4f60dd08ea780259ed80bac0312f2e1df4398176" +checksum = "0c1d9a7084cc5b14acae411d19f33a693fdb06ac55044705deb88844c8b58aa9" dependencies = [ "aws-credential-types", "aws-runtime", @@ -577,18 +580,17 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes", - "fastrand 2.2.0", + "fastrand 2.3.0", "http 0.2.12", - "once_cell", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-sso" -version = "1.49.0" +version = "1.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09677244a9da92172c8dc60109b4a9658597d4d298b188dd0018b6a66b410ca4" +checksum = "643cd43af212d2a1c4dedff6f044d7e1961e5d9e7cfe773d70f31d9842413886" dependencies = [ "aws-credential-types", "aws-runtime", @@ -600,17 +602,17 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes", + "fastrand 2.3.0", "http 0.2.12", - "once_cell", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-ssooidc" -version = "1.50.0" +version = "1.84.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fea2f3a8bb3bd10932ae7ad59cc59f65f270fc9183a7e91f501dc5efbef7ee" +checksum = "20ec4a95bd48e0db7a424356a161f8d87bd6a4f0af37204775f0da03d9e39fc3" dependencies = [ "aws-credential-types", "aws-runtime", @@ -622,17 +624,17 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes", + "fastrand 2.3.0", "http 0.2.12", - "once_cell", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-sts" -version = "1.49.0" +version = "1.85.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53dcf5e7d9bd1517b8b998e170e650047cea8a2b85fe1835abe3210713e541b7" +checksum = "410309ad0df4606bc721aff0d89c3407682845453247213a0ccc5ff8801ee107" dependencies = [ "aws-credential-types", "aws-runtime", @@ -645,17 +647,17 @@ dependencies = [ "aws-smithy-types", "aws-smithy-xml", "aws-types", + "fastrand 2.3.0", "http 0.2.12", - "once_cell", "regex-lite", "tracing", ] [[package]] name = "aws-sigv4" -version = "1.2.5" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5619742a0d8f253be760bfbb8e8e8368c69e3587e4637af5754e488a611499b1" +checksum = "084c34162187d39e3740cb635acd73c4e3a551a36146ad6fe8883c929c9f876c" dependencies = [ "aws-credential-types", "aws-smithy-http", @@ -666,8 +668,7 @@ dependencies = [ "hex", "hmac", "http 0.2.12", - "http 1.1.0", - "once_cell", + "http 1.3.1", "percent-encoding", "sha2", "time", @@ -676,9 +677,9 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "1.2.1" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" +checksum = "1e190749ea56f8c42bf15dd76c65e14f8f765233e6df9b0506d9d934ebef867c" dependencies = [ "futures-util", "pin-project-lite", @@ -687,9 +688,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.60.11" +version = "0.62.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8bc3e8fdc6b8d07d976e301c02fe553f72a39b7a9fea820e023268467d7ab6" +checksum = "7c4dacf2d38996cf729f55e7a762b30918229917eca115de45dfa8dfb97796c9" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", @@ -697,23 +698,53 @@ dependencies = [ "bytes-utils", "futures-core", "http 0.2.12", + "http 1.3.1", "http-body 0.4.6", - "once_cell", "percent-encoding", "pin-project-lite", "pin-utils", "tracing", ] +[[package]] +name = "aws-smithy-http-client" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147e8eea63a40315d704b97bf9bc9b8c1402ae94f89d5ad6f7550d963309da1b" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.12", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-rustls 0.24.2", + "pin-project-lite", + "rustls 0.21.12", + "tokio", + "tracing", +] + [[package]] name = "aws-smithy-json" -version = "0.60.7" +version = "0.61.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" +checksum = "eaa31b350998e703e9826b2104dd6f63be0508666e1aba88137af060e8944047" dependencies = [ "aws-smithy-types", ] +[[package]] +name = "aws-smithy-observability" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9364d5989ac4dd918e5cc4c4bdcc61c9be17dcd2586ea7f69e348fc7c6cab393" +dependencies = [ + "aws-smithy-runtime-api", +] + [[package]] name = "aws-smithy-query" version = "0.60.7" @@ -726,42 +757,39 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.7.3" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be28bd063fa91fd871d131fc8b68d7cd4c5fa0869bea68daca50dcb1cbd76be2" +checksum = "d3946acbe1ead1301ba6862e712c7903ca9bb230bdf1fbd1b5ac54158ef2ab1f" dependencies = [ "aws-smithy-async", "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", "aws-smithy-runtime-api", "aws-smithy-types", "bytes", - "fastrand 2.2.0", - "h2 0.3.26", + "fastrand 2.3.0", "http 0.2.12", + "http 1.3.1", "http-body 0.4.6", "http-body 1.0.1", - "httparse", - "hyper 0.14.31", - "hyper-rustls 0.24.2", - "once_cell", "pin-project-lite", "pin-utils", - "rustls 0.21.12", "tokio", "tracing", ] [[package]] name = "aws-smithy-runtime-api" -version = "1.7.3" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92165296a47a812b267b4f41032ff8069ab7ff783696d217f0994a0d7ab585cd" +checksum = "07f5e0fc8a6b3f2303f331b94504bbf754d85488f402d6f1dd7a6080f99afe56" dependencies = [ "aws-smithy-async", "aws-smithy-types", "bytes", "http 0.2.12", - "http 1.1.0", + "http 1.3.1", "pin-project-lite", "tokio", "tracing", @@ -770,16 +798,16 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.2.9" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd94a32b3a7d55d3806fe27d98d3ad393050439dd05eb53ece36ec5e3d3510" +checksum = "d498595448e43de7f4296b7b7a18a8a02c61ec9349128c80a368f7c3b4ab11a8" dependencies = [ "base64-simd", "bytes", "bytes-utils", "futures-core", "http 0.2.12", - "http 1.1.0", + "http 1.3.1", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -796,18 +824,18 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.60.9" +version = "0.60.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab0b0166827aa700d3dc519f72f8b3a91c35d0b8d042dc5d643a91e6f80648fc" +checksum = "3db87b96cb1b16c024980f133968d52882ca0daaee3a086c6decc500f6c99728" dependencies = [ "xmlparser", ] [[package]] name = "aws-types" -version = "1.3.3" +version = "1.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" +checksum = "b069d19bf01e46298eaedd7c6f283fe565a59263e53eebec945f3e6398f42390" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -827,7 +855,7 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "itoa", @@ -838,7 +866,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower 0.5.2", "tower-layer", "tower-service", @@ -853,13 +881,13 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", ] @@ -874,13 +902,13 @@ dependencies = [ "bytes", "dyn-clone", "futures", - "getrandom 0.2.15", + "getrandom 0.2.16", "http-types", "once_cell", "paste", "pin-project", "rand 0.8.5", - "reqwest 0.12.9", + "reqwest 0.12.23", "rustc_version", "serde", "serde_json", @@ -901,14 +929,14 @@ dependencies = [ "bytes", "dyn-clone", "futures", - "getrandom 0.2.15", + "getrandom 0.2.16", "hmac", "http-types", "once_cell", "paste", "pin-project", "rand 0.8.5", - "reqwest 0.12.9", + "reqwest 0.12.23", "rustc_version", "serde", "serde_json", @@ -994,24 +1022,24 @@ dependencies = [ [[package]] name = "backon" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd0b50b1b78dbadd44ab18b3c794e496f3a139abb9fbc27d9c94c4eebbb96496" +checksum = "592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d" dependencies = [ - "fastrand 2.2.0", + "fastrand 2.3.0", ] [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line 0.24.2", "cfg-if", "libc", "miniz_oxide", - "object 0.36.5", + "object 0.36.7", "rustc-demangle", "windows-targets 0.52.6", ] @@ -1052,9 +1080,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "beef" @@ -1096,9 +1124,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" dependencies = [ "serde", ] @@ -1159,14 +1187,14 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "async-channel 2.3.1", + "async-channel 2.5.0", "async-task", "futures-io", - "futures-lite 2.5.0", + "futures-lite 2.6.1", "piper", ] @@ -1190,17 +1218,17 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "bstr" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", - "regex-automata 0.4.9", + "regex-automata", "serde", ] @@ -1215,9 +1243,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" dependencies = [ "allocator-api2", ] @@ -1246,22 +1274,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -1272,9 +1300,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" dependencies = [ "serde", ] @@ -1291,9 +1319,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.9" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" dependencies = [ "serde", ] @@ -1310,11 +1338,11 @@ dependencies = [ "cudarc", "gemm 0.17.1", "half", - "memmap2 0.9.5", + "memmap2 0.9.8", "metal 0.27.0", "num-traits", "num_cpus", - "rand 0.9.1", + "rand 0.9.2", "rand_distr", "rayon", "safetensors 0.4.5", @@ -1322,7 +1350,7 @@ dependencies = [ "ug", "ug-cuda", "ug-metal", - "yoke", + "yoke 0.7.5", "zip", ] @@ -1375,7 +1403,7 @@ dependencies = [ "candle-nn", "fancy-regex", "num-traits", - "rand 0.9.1", + "rand 0.9.2", "rayon", "serde", "serde_json", @@ -1403,7 +1431,7 @@ checksum = "9f83833816c66c986e913b22ac887cec216ea09301802054316fc5301809702c" dependencies = [ "cap-primitives", "cap-std", - "rustix 1.0.5", + "rustix 1.0.8", "smallvec", ] @@ -1419,7 +1447,7 @@ dependencies = [ "io-lifetimes", "ipnet", "maybe-owned", - "rustix 1.0.5", + "rustix 1.0.8", "rustix-linux-procfs", "windows-sys 0.59.0", "winx", @@ -1444,7 +1472,7 @@ dependencies = [ "cap-primitives", "io-extras", "io-lifetimes", - "rustix 1.0.5", + "rustix 1.0.8", ] [[package]] @@ -1457,15 +1485,15 @@ dependencies = [ "cap-primitives", "iana-time-zone", "once_cell", - "rustix 1.0.5", + "rustix 1.0.8", "winx", ] [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -1499,7 +1527,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" dependencies = [ "serde", - "toml 0.8.19", + "toml 0.8.23", +] + +[[package]] +name = "castaway" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", ] [[package]] @@ -1513,9 +1550,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.0" +version = "1.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" dependencies = [ "jobserver", "libc", @@ -1524,9 +1561,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cfg_aliases" @@ -1536,9 +1573,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1546,7 +1583,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -1578,23 +1615,23 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" dependencies = [ "clap_builder", - "clap_derive 4.5.18", + "clap_derive 4.5.45", ] [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.2", + "clap_lex 0.7.5", "strsim 0.11.1", ] @@ -1613,14 +1650,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -1634,9 +1671,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clearscreen" @@ -1653,37 +1690,40 @@ dependencies = [ [[package]] name = "clearscreen" -version = "4.0.1" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c41dc435a7b98e4608224bbf65282309f5403719df9113621b30f8b6f74e2f4" +checksum = "85a8ab73a1c02b0c15597b22e09c7dc36e63b2f601f9d1e83ac0c3decd38b1ae" dependencies = [ "nix 0.29.0", "terminfo 0.9.0", - "thiserror 2.0.12", - "which 7.0.3", + "thiserror 2.0.16", + "which 8.0.0", "windows-sys 0.59.0", ] [[package]] name = "cmake" -version = "0.1.51" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] [[package]] name = "cobs" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.16", +] [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -1701,14 +1741,13 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.1" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" +checksum = "3f8e18d0dca9578507f13f9803add0df13362b02c501c1c17734f0dbb52eaf0b" dependencies = [ "crossterm", - "strum 0.26.3", - "strum_macros 0.26.4", - "unicode-width 0.1.14", + "unicode-segmentation", + "unicode-width 0.2.1", ] [[package]] @@ -1723,6 +1762,40 @@ dependencies = [ "winapi", ] +[[package]] +name = "compact_str" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "serde", + "static_assertions", +] + +[[package]] +name = "compression-codecs" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7eea68f0e02c2b0aa8856e9a9478444206d4b6828728e7b0697c0f8cca265cb" +dependencies = [ + "compression-core", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", +] + +[[package]] +name = "compression-core" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1747,7 +1820,7 @@ dependencies = [ "rust-ini", "serde", "serde_json", - "toml 0.8.19", + "toml 0.8.23", "yaml-rust2", ] @@ -1770,7 +1843,7 @@ dependencies = [ "flate2", "json5", "libtest-mimic", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "tar", "test-environment", @@ -1778,15 +1851,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.8" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", - "lazy_static 1.5.0", "libc", - "unicode-width 0.1.14", - "windows-sys 0.52.0", + "once_cell", + "unicode-width 0.2.1", + "windows-sys 0.59.0", ] [[package]] @@ -1810,16 +1883,16 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "once_cell", "tiny-keccak", ] [[package]] name = "const_fn" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373e9fafaa20882876db20562275ff58d50e0caa2590077fe7ce7bef90211d0d" +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" [[package]] name = "convert_case" @@ -1842,9 +1915,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -1878,9 +1951,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -1937,8 +2010,8 @@ dependencies = [ "cranelift-control", "cranelift-entity", "cranelift-isle", - "gimli 0.32.0", - "hashbrown 0.15.2", + "gimli 0.32.2", + "hashbrown 0.15.5", "log", "pulley-interpreter", "regalloc2", @@ -2025,9 +2098,9 @@ checksum = "673bd6d1c83cb41d60afb140a1474ef6caf1a3e02f3820fc522aefbc93ac67d6" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -2047,18 +2120,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -2075,29 +2148,30 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" -version = "0.27.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "crossterm_winapi", - "libc", + "document-features", "parking_lot", + "rustix 1.0.8", "winapi", ] @@ -2112,9 +2186,9 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" @@ -2140,11 +2214,11 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.5" +version = "3.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73" dependencies = [ - "nix 0.29.0", + "nix 0.30.1", "windows-sys 0.59.0", ] @@ -2170,12 +2244,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core 0.20.10", - "darling_macro 0.20.10", + "darling_core 0.20.11", + "darling_macro 0.20.11", ] [[package]] @@ -2194,16 +2268,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2219,42 +2293,51 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core 0.20.10", + "darling_core 0.20.11", "quote", - "syn 2.0.87", + "syn 2.0.106", +] + +[[package]] +name = "dary_heap" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d2cd9c18b9f454ed67da600630b021a8a80bf33f8c95896ab33aaf1c26b728" +dependencies = [ + "serde", ] [[package]] name = "dbus" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +checksum = "6e8d0767bcb66eb101d5ab87b9f38542691185af14fa8a7026c2490e62b45cfc" dependencies = [ "libc", "libdbus-sys", - "winapi", + "windows-sys 0.59.0", ] [[package]] name = "dbus-secret-service" -version = "4.0.3" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42a16374481d92aed73ae45b1f120207d8e71d24fb89f357fadbd8f946fd84b" +checksum = "708b509edf7889e53d7efb0ffadd994cc6c2345ccb62f55cfd6b0682165e4fa6" dependencies = [ "aes", "block-padding", "cbc", "dbus", - "futures-util", + "fastrand 2.3.0", "hkdf", "num", "once_cell", - "rand 0.8.5", "sha2", + "zeroize", ] [[package]] @@ -2276,7 +2359,7 @@ checksum = "3d697d376cbfa018c23eb4caab1fd1883dd9c906a8c034e8d9a3cb06a7e0bef9" dependencies = [ "async-trait", "deadpool", - "getrandom 0.2.15", + "getrandom 0.2.16", "tokio", "tokio-postgres", "tracing", @@ -2302,9 +2385,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -2313,9 +2396,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", "serde", @@ -2323,13 +2406,13 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2368,10 +2451,10 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.10", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2391,7 +2474,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core 0.20.2", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2502,7 +2585,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.0", + "redox_users 0.5.2", "windows-sys 0.60.2", ] @@ -2525,7 +2608,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2564,23 +2647,26 @@ dependencies = [ "const-random", ] -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "docker_credential" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31951f49556e34d90ed28342e1df7e1cb7a229c4cab0aecc627b5d91edd41d07" +checksum = "1d89dfcba45b4afad7450a99b39e751590463e45c04728cf555d36bb66940de8" dependencies = [ "base64 0.21.7", "serde", "serde_json", ] +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + [[package]] name = "dotenvy" version = "0.15.7" @@ -2589,9 +2675,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "dyn-stack" @@ -2628,9 +2714,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" @@ -2666,9 +2752,9 @@ checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" @@ -2694,14 +2780,14 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ "enumflags2_derive", "serde", @@ -2709,13 +2795,13 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2739,18 +2825,18 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2787,9 +2873,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -2798,11 +2884,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.1", "pin-project-lite", ] @@ -2818,7 +2904,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -2865,8 +2951,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" dependencies = [ "bit-set", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] @@ -2880,26 +2966,26 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fd-lock" -version = "4.0.2" +version = "4.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", - "rustix 0.38.40", - "windows-sys 0.52.0", + "rustix 1.0.8", + "windows-sys 0.59.0", ] [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "rand_core 0.6.4", "subtle", @@ -2917,14 +3003,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2935,9 +3021,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -2962,9 +3048,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -2993,7 +3079,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -3010,9 +3096,9 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -3028,13 +3114,13 @@ dependencies = [ [[package]] name = "fs-set-times" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" +checksum = "94e7099f6313ecacbe1256e8ff9d617b75d1bcb16a6fddef94866d225a01a14a" dependencies = [ "io-lifetimes", - "rustix 0.38.40", - "windows-sys 0.52.0", + "rustix 1.0.8", + "windows-sys 0.59.0", ] [[package]] @@ -3133,11 +3219,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.2.0", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -3152,7 +3238,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -3200,7 +3286,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "debugid", "fxhash", "serde", @@ -3341,7 +3427,7 @@ dependencies = [ "num-traits", "once_cell", "paste", - "pulp 0.21.4", + "pulp 0.21.5", "raw-cpuid 11.5.0", "rayon", "seq-macro", @@ -3446,9 +3532,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" dependencies = [ "cc", "cfg-if", @@ -3482,39 +3568,41 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.3+wasi-0.2.4", + "wasm-bindgen", ] [[package]] name = "getset" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" +checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -3525,12 +3613,12 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gimli" -version = "0.32.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" +checksum = "cc6298e594375a7fead9efd5568f0a46e6a154fb6a9bdcbe3c06946ffd81a5f6" dependencies = [ "fallible-iterator 0.3.0", - "indexmap 2.7.1", + "indexmap 2.11.0", "stable_deref_trait", ] @@ -3742,11 +3830,11 @@ dependencies = [ [[package]] name = "gix-utils" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba427e3e9599508ed98a6ddf8ed05493db114564e338e41f6a996d2e4790335f" +checksum = "ff08f24e03ac8916c478c8419d7d3c33393da9bb41fa4c24455d5406aeefd35f" dependencies = [ - "fastrand 2.2.0", + "fastrand 2.3.0", "unicode-normalization", ] @@ -3762,21 +3850,21 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] @@ -3804,9 +3892,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -3814,7 +3902,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.7.1", + "indexmap 2.11.0", "slab", "tokio", "tokio-util", @@ -3823,17 +3911,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.1.0", - "indexmap 2.7.1", + "http 1.3.1", + "indexmap 2.11.0", "slab", "tokio", "tokio-util", @@ -3850,7 +3938,7 @@ dependencies = [ "cfg-if", "crunchy", "num-traits", - "rand 0.9.1", + "rand 0.9.2", "rand_distr", ] @@ -3869,15 +3957,15 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "allocator-api2", ] [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", @@ -3900,7 +3988,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -3935,15 +4023,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -3971,11 +4053,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3991,9 +4073,9 @@ dependencies = [ [[package]] name = "http" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -4027,18 +4109,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.3.1", ] [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", - "http 1.1.0", + "futures-core", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] @@ -4065,9 +4147,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -4077,28 +4159,28 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "hyper" -version = "0.14.31" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -4107,20 +4189,22 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", - "h2 0.4.6", - "http 1.1.0", + "futures-core", + "h2 0.4.12", + "http 1.3.1", "http-body 1.0.1", "httparse", "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -4134,7 +4218,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", @@ -4150,32 +4234,31 @@ checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "log", "rustls 0.22.4", "rustls-native-certs 0.7.3", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] name = "hyper-rustls" -version = "0.27.3" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "futures-util", - "http 1.1.0", - "hyper 1.5.0", + "http 1.3.1", + "hyper 1.7.0", "hyper-util", - "rustls 0.23.18", + "rustls 0.23.31", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.2", "tower-service", - "webpki-roots", + "webpki-roots 1.0.2", ] [[package]] @@ -4184,7 +4267,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.5.0", + "hyper 1.7.0", "hyper-util", "pin-project-lite", "tokio", @@ -4198,7 +4281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.31", + "hyper 0.14.32", "native-tls", "tokio", "tokio-native-tls", @@ -4212,7 +4295,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.5.0", + "hyper 1.7.0", "hyper-util", "native-tls", "tokio", @@ -4222,35 +4305,43 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-body 1.0.1", - "hyper 1.5.0", + "hyper 1.7.0", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.0", + "system-configuration 0.6.1", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -4264,21 +4355,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", - "yoke", + "potential_utf", + "yoke 0.8.0", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -4287,31 +4379,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -4319,67 +4391,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", - "yoke", + "yoke 0.8.0", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "id-arena" version = "2.2.1" @@ -4394,9 +4453,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -4405,9 +4464,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -4423,7 +4482,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.9", + "regex-automata", "same-file", "walkdir", "winapi-util", @@ -4471,25 +4530,25 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.5", "serde", ] [[package]] name = "indicatif" -version = "0.17.9" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ "console", "number_prefix", "portable-atomic", - "unicode-width 0.2.0", + "unicode-width 0.2.1", "web-time", ] @@ -4521,9 +4580,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ "block-padding", "generic-array", @@ -4540,19 +4599,30 @@ dependencies = [ [[package]] name = "io-extras" -version = "0.18.3" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d45fd7584f9b67ac37bc041212d06bfac0700b36456b05890d36a3b626260eb" +checksum = "2285ddfe3054097ef4b2fe909ef8c3bcd1ea52a8f0d274416caebeef39f04a65" dependencies = [ "io-lifetimes", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "io-lifetimes" -version = "2.0.3" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06432fb54d3be7964ecd3649233cddf80db2832f47fec34c01f65b3d9d774983" + +[[package]] +name = "io-uring" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags 2.9.3", + "cfg-if", + "libc", +] [[package]] name = "ip_network" @@ -4578,19 +4648,29 @@ checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" [[package]] name = "ipnet" -version = "2.10.1" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.4.0", + "hermit-abi 0.5.2", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4617,15 +4697,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -4637,9 +4708,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "ittapi" @@ -4663,19 +4734,21 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -4725,14 +4798,14 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d" dependencies = [ - "indexmap 2.7.1", + "indexmap 2.11.0", ] [[package]] name = "keyring" -version = "3.6.2" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1961983669d57bdfe6c0f3ef8e4c229b5ef751afcc7d87e4271d2f71f6ccfa8b" +checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c" dependencies = [ "byteorder", "dbus-secret-service", @@ -4740,16 +4813,17 @@ dependencies = [ "log", "secret-service", "security-framework 2.11.1", - "security-framework 3.2.0", - "windows-sys 0.59.0", + "security-framework 3.3.0", + "windows-sys 0.60.2", "zbus", + "zeroize", ] [[package]] name = "kqueue" -version = "1.0.8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", @@ -4816,15 +4890,15 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libdbus-sys" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +checksum = "5cbe856efeb50e4681f010e9aaa2bf0a644e10139e54cde10fc83a307c23bd9f" dependencies = [ "pkg-config", ] @@ -4851,29 +4925,29 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.3", ] [[package]] name = "libm" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.17", ] [[package]] @@ -4885,12 +4959,12 @@ dependencies = [ "async-stream", "async-trait", "base64 0.21.7", - "bitflags 2.6.0", + "bitflags 2.9.3", "bytes", "fallible-iterator 0.3.0", "futures", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "hyper-rustls 0.25.0", "libsql-hrana", "libsql-sqlite3-parser", @@ -4921,10 +4995,10 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15a90128c708356af8f7d767c9ac2946692c9112b4f74f07b99a01a60680e413" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "cc", "fallible-iterator 0.3.0", - "indexmap 2.7.1", + "indexmap 2.11.0", "log", "memchr", "phf", @@ -4950,7 +5024,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc0bda45ed5b3a2904262c1bb91e526127aa70e7ef3758aba2ef93cf896b9b58" dependencies = [ - "clap 4.5.20", + "clap 4.5.46", "escape8259", "termcolor", "threadpool", @@ -4962,15 +5036,15 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "libc", ] [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" @@ -4980,11 +5054,10 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "liquid" -version = "0.26.9" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdcc72b82748f47c2933c172313f5a9aea5b2c4eb3fa4c66b4ea55bb60bb4b1" +checksum = "2a494c3f9dad3cb7ed16f1c51812cbe4b29493d6c2e5cd1e2b87477263d9534d" dependencies = [ - "doc-comment", "liquid-core", "liquid-derive", "liquid-lib", @@ -4993,15 +5066,14 @@ dependencies = [ [[package]] name = "liquid-core" -version = "0.26.9" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2752e978ffc53670f3f2e8b3ef09f348d6f7b5474a3be3f8a5befe5382e4effb" +checksum = "fc623edee8a618b4543e8e8505584f4847a4e51b805db1af6d9af0a3395d0d57" dependencies = [ "anymap2", - "itertools 0.13.0", + "itertools 0.14.0", "kstring", "liquid-derive", - "num-traits", "pest", "pest_derive", "regex", @@ -5011,24 +5083,23 @@ dependencies = [ [[package]] name = "liquid-derive" -version = "0.26.8" +version = "0.26.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b51f1d220e3fa869e24cfd75915efe3164bd09bb11b3165db3f37f57bf673e3" +checksum = "de66c928222984aea59fcaed8ba627f388aaac3c1f57dcb05cc25495ef8faefe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "liquid-lib" -version = "0.26.9" +version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b1a298d3d2287ee5b1e43840d885b8fdfc37d3f4e90d82aacfd04d021618da" +checksum = "9befeedd61f5995bc128c571db65300aeb50d62e4f0542c88282dbcb5f72372a" dependencies = [ - "itertools 0.13.0", + "itertools 0.14.0", "liquid-core", - "once_cell", "percent-encoding", "regex", "time", @@ -5037,15 +5108,21 @@ dependencies = [ [[package]] name = "litemap" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -5062,33 +5139,33 @@ dependencies = [ [[package]] name = "logos" -version = "0.14.2" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" +checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.14.2" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" +checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f" dependencies = [ "beef", "fnv", "lazy_static 1.5.0", "proc-macro2", "quote", - "regex-syntax 0.8.5", - "syn 2.0.87", + "regex-syntax", + "syn 2.0.106", ] [[package]] name = "logos-derive" -version = "0.14.2" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" +checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d" dependencies = [ "logos-codegen", ] @@ -5112,23 +5189,29 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] [[package]] name = "macro_rules_attribute" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" +checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" dependencies = [ "macro_rules_attribute-proc_macro", "paste", @@ -5136,9 +5219,9 @@ dependencies = [ [[package]] name = "macro_rules_attribute-proc_macro" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" +checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" [[package]] name = "malloc_buf" @@ -5151,11 +5234,11 @@ dependencies = [ [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -5182,9 +5265,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memfd" @@ -5192,7 +5275,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.40", + "rustix 0.38.44", ] [[package]] @@ -5206,9 +5289,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" dependencies = [ "libc", "stable_deref_trait", @@ -5238,7 +5321,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "block", "core-graphics-types", "foreign-types 0.5.0", @@ -5253,7 +5336,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "block", "core-graphics-types", "foreign-types 0.5.0", @@ -5276,13 +5359,12 @@ dependencies = [ [[package]] name = "miette" -version = "7.2.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" dependencies = [ "cfg-if", - "miette-derive 7.2.0", - "thiserror 1.0.69", + "miette-derive 7.6.0", "unicode-width 0.1.14", ] @@ -5294,18 +5376,18 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "miette-derive" -version = "7.2.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -5322,9 +5404,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -5337,7 +5419,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -5348,7 +5430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -5373,9 +5455,9 @@ dependencies = [ [[package]] name = "monostate" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d208407d7552cd041d8cdb69a1bc3303e029c598738177a3d87082004dc0e1e" +checksum = "aafe1be9d0c75642e3e50fedc7ecadf1ef1cbce6eb66462153fc44245343fbee" dependencies = [ "monostate-impl", "serde", @@ -5383,20 +5465,20 @@ dependencies = [ [[package]] name = "monostate-impl" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ce64b975ed4f123575d11afd9491f2e37bbd5813fbfbc0f09ae1fbddea74e0" +checksum = "c402a4092d5e204f32c9e155431046831fa712637043c58cb73bc6bc6c9663b5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "multimap" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" [[package]] name = "mysql_async" @@ -5420,8 +5502,8 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "socket2", - "thiserror 2.0.12", + "socket2 0.5.10", + "thiserror 2.0.16", "tokio", "tokio-native-tls", "tokio-util", @@ -5436,7 +5518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34a9141e735d5bb02414a7ac03add09522466d4db65bdd827069f76ae0850e58" dependencies = [ "base64 0.22.1", - "bitflags 2.6.0", + "bitflags 2.9.3", "btoi", "byteorder", "bytes", @@ -5462,9 +5544,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -5496,13 +5578,25 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "cfg-if", "cfg_aliases", "libc", "memoffset 0.9.1", ] +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.3", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -5554,12 +5648,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -5645,33 +5738,34 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi 0.5.2", "libc", ] [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -5697,7 +5791,7 @@ checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" dependencies = [ "base64 0.13.1", "chrono", - "getrandom 0.2.15", + "getrandom 0.2.16", "http 0.2.12", "rand 0.8.5", "serde", @@ -5729,9 +5823,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] @@ -5743,8 +5837,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "crc32fast", - "hashbrown 0.15.2", - "indexmap 2.7.1", + "hashbrown 0.15.5", + "indexmap 2.11.0", "memchr", ] @@ -5757,14 +5851,14 @@ dependencies = [ "bytes", "chrono", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-auth", "jwt 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.5.0", "oci-spec", "olpc-cjson", "regex", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "serde_json", "sha2", @@ -5782,13 +5876,13 @@ dependencies = [ "bytes", "chrono", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-auth", "jwt 0.16.0 (git+https://github.com/vdice/rust-jwt?rev=c5b596d28a39dd428350b445d5c5829ba6352f02)", "lazy_static 1.5.0", "olpc-cjson", "regex", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "serde_json", "sha2", @@ -5806,13 +5900,13 @@ dependencies = [ "bytes", "chrono", "futures-util", - "http 1.1.0", + "http 1.3.1", "http-auth", "jwt 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.5.0", "olpc-cjson", "regex", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "serde_json", "sha2", @@ -5835,7 +5929,7 @@ dependencies = [ "serde_json", "strum 0.26.3", "strum_macros 0.26.4", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -5868,9 +5962,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "onig" @@ -5878,7 +5978,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "libc", "once_cell", "onig_sys", @@ -5896,11 +5996,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "cfg-if", "foreign-types 0.3.2", "libc", @@ -5917,20 +6017,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -5948,7 +6048,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] @@ -5972,9 +6072,9 @@ checksum = "a8863faf2910030d139fb48715ad5ff2f35029fc5f244f6d5f689ddcf4d26253" dependencies = [ "async-trait", "bytes", - "http 1.1.0", + "http 1.3.1", "opentelemetry", - "reqwest 0.12.9", + "reqwest 0.12.23", "tracing", ] @@ -5986,17 +6086,16 @@ checksum = "5bef114c6d41bea83d6dc60eb41720eedd0261a67af57b66dd2b84ac46c01d91" dependencies = [ "async-trait", "futures-core", - "http 1.1.0", + "http 1.3.1", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", - "prost 0.13.3", - "reqwest 0.12.9", - "thiserror 2.0.12", + "prost 0.13.5", + "reqwest 0.12.23", + "thiserror 2.0.16", "tokio", "tonic", - "tracing", ] [[package]] @@ -6007,7 +6106,7 @@ checksum = "56f8870d3024727e99212eb3bb1762ec16e255e3e6f58eeb3dc8db1aa226746d" dependencies = [ "opentelemetry", "opentelemetry_sdk", - "prost 0.13.3", + "prost 0.13.5", "tonic", ] @@ -6027,7 +6126,7 @@ dependencies = [ "percent-encoding", "rand 0.8.5", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", @@ -6076,15 +6175,9 @@ checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "outref" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" - -[[package]] -name = "overload" -version = "0.1.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" [[package]] name = "p256" @@ -6106,9 +6199,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -6116,13 +6209,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.17", "smallvec", "windows-targets 0.52.6", ] @@ -6153,9 +6246,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pbjson" @@ -6196,9 +6289,9 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" dependencies = [ "base64 0.22.1", "serde", @@ -6215,26 +6308,26 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.7.14" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.16", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" dependencies = [ "pest", "pest_generator", @@ -6242,24 +6335,23 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" dependencies = [ - "once_cell", "pest", "sha2", ] @@ -6271,23 +6363,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.7.1", + "indexmap 2.11.0", ] [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_shared", ] [[package]] name = "phf_codegen" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" dependencies = [ "phf_generator", "phf_shared", @@ -6295,9 +6387,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand 0.8.5", @@ -6305,9 +6397,9 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", "uncased", @@ -6315,29 +6407,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -6352,7 +6444,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.2.0", + "fastrand 2.3.0", "futures-io", ] @@ -6368,36 +6460,35 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "polling" -version = "3.7.4" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.4.0", + "hermit-abi 0.5.2", "pin-project-lite", - "rustix 0.38.40", - "tracing", - "windows-sys 0.59.0", + "rustix 1.0.8", + "windows-sys 0.60.2", ] [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "postcard" -version = "1.0.10" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" dependencies = [ "cobs", "embedded-io 0.4.0", @@ -6407,11 +6498,10 @@ dependencies = [ [[package]] name = "postgres-native-tls" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d442770e2b1e244bb5eb03b31c79b65bb2568f413b899eaba850fa945a65954" +checksum = "a1f39498473c92f7b6820ae970382c1d83178a3454c618161cb772e8598d9f6f" dependencies = [ - "futures", "native-tls", "tokio", "tokio-native-tls", @@ -6420,9 +6510,9 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acda0ebdebc28befa84bee35e651e4c5f09073d668c7aed4cf7e23c3cda84b23" +checksum = "76ff0abab4a9b844b93ef7b81f1efc0a366062aaef2cd702c76256b5dc075c54" dependencies = [ "base64 0.22.1", "byteorder", @@ -6431,16 +6521,16 @@ dependencies = [ "hmac", "md-5", "memchr", - "rand 0.8.5", + "rand 0.9.2", "sha2", "stringprep", ] [[package]] name = "postgres-types" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66ea23a2d0e5734297357705193335e0a957696f34bed2f2faefacb2fec336f" +checksum = "613283563cd90e1dfc3518d548caee47e0e725455ed619881f5cf21f36de4b48" dependencies = [ "bytes", "chrono", @@ -6461,6 +6551,15 @@ dependencies = [ "postgres-types", ] +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -6469,9 +6568,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] @@ -6488,12 +6587,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -6507,9 +6606,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit", ] @@ -6557,14 +6656,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -6591,12 +6690,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ "bytes", - "prost-derive 0.13.3", + "prost-derive 0.13.5", ] [[package]] @@ -6616,7 +6715,7 @@ dependencies = [ "prost 0.12.6", "prost-types", "regex", - "syn 2.0.87", + "syn 2.0.106", "tempfile", ] @@ -6630,20 +6729,20 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "prost-derive" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -6653,7 +6752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f5eec97d5d34bdd17ad2db2219aabf46b054c6c41bd5529767c9ce55be5898f" dependencies = [ "logos", - "miette 7.2.0", + "miette 7.6.0", "once_cell", "prost 0.12.6", "prost-types", @@ -6675,7 +6774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac532509cee918d40f38c3e12f8ef9230f215f017d54de7dd975015538a42ce7" dependencies = [ "bytes", - "miette 7.2.0", + "miette 7.6.0", "prost 0.12.6", "prost-reflect", "prost-types", @@ -6690,7 +6789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6c33f43516fe397e2f930779d720ca12cd057f7da4cd6326a0ef78d69dee96" dependencies = [ "logos", - "miette 7.2.0", + "miette 7.6.0", "prost-types", "thiserror 1.0.69", ] @@ -6750,7 +6849,7 @@ checksum = "efb9fdafaca625f9ea8cfa793364ea1bdd32d306cff18f166b00ddaa61ecbb27" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -6767,9 +6866,9 @@ dependencies = [ [[package]] name = "pulp" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fb7a99b37aaef4c7dd2fd15a819eb8010bfc7a2c2155230d51f497316cad6d" +checksum = "96b86df24f0a7ddd5e4b95c94fc9ed8a98f1ca94d3b01bdce2824097e7835907" dependencies = [ "bytemuck", "cfg-if", @@ -6781,67 +6880,73 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.5" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.18", - "socket2", - "thiserror 1.0.69", + "rustls 0.23.31", + "socket2 0.6.0", + "thiserror 2.0.16", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.8" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "rand 0.8.5", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", "ring", "rustc-hash", - "rustls 0.23.18", + "rustls 0.23.31", + "rustls-pki-types", "slab", - "thiserror 1.0.69", + "thiserror 2.0.16", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.7" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2", + "socket2 0.6.0", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "radium" @@ -6875,9 +6980,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -6928,7 +7033,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -6937,7 +7042,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", ] [[package]] @@ -6947,7 +7052,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ "num-traits", - "rand 0.9.1", + "rand 0.9.2", ] [[package]] @@ -6983,14 +7088,14 @@ version = "11.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", ] [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -6998,20 +7103,20 @@ dependencies = [ [[package]] name = "rayon-cond" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "059f538b55efd2309c9794130bc149c6a553db90e9d99c2030785c82f0bd7df9" +checksum = "2964d0cf57a3e7a06e8183d14a8b527195c706b7983549cd5462d5aa3747438f" dependencies = [ "either", - "itertools 0.11.0", + "itertools 0.14.0", "rayon", ] [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -7039,7 +7144,7 @@ dependencies = [ "pin-project-lite", "ryu", "sha1_smol", - "socket2", + "socket2 0.5.10", "tokio", "tokio-native-tls", "tokio-util", @@ -7065,7 +7170,7 @@ dependencies = [ "pin-project-lite", "ryu", "sha1_smol", - "socket2", + "socket2 0.5.10", "tokio", "tokio-native-tls", "tokio-util", @@ -7083,11 +7188,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", ] [[package]] @@ -7096,20 +7201,40 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", "thiserror 1.0.69", ] [[package]] name = "redox_users" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", - "thiserror 2.0.12", + "thiserror 2.0.16", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] @@ -7120,7 +7245,7 @@ checksum = "5216b1837de2149f8bc8e6d5f88a9326b63b8c836ed58ce4a0a29ec736a59734" dependencies = [ "allocator-api2", "bumpalo", - "hashbrown 0.15.2", + "hashbrown 0.15.5", "log", "rustc-hash", "smallvec", @@ -7128,53 +7253,38 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-lite" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" - -[[package]] -name = "regex-syntax" -version = "0.6.29" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "rend" @@ -7196,10 +7306,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.31", + "hyper 0.14.32", "hyper-tls 0.5.0", "ipnet", "js-sys", @@ -7229,9 +7339,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.9" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "async-compression", "base64 0.22.1", @@ -7240,44 +7350,40 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.6", - "http 1.1.0", + "h2 0.4.12", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", - "hyper-rustls 0.27.3", + "hyper 1.7.0", + "hyper-rustls 0.27.7", "hyper-tls 0.6.0", "hyper-util", - "ipnet", "js-sys", "log", "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.18", - "rustls-pemfile 2.2.0", + "rustls 0.23.31", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", - "system-configuration 0.6.1", + "sync_wrapper 1.0.2", "tokio", "tokio-native-tls", - "tokio-rustls 0.26.0", - "tokio-socks", + "tokio-rustls 0.26.2", "tokio-util", + "tower 0.5.2", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", - "windows-registry", + "webpki-roots 1.0.2", ] [[package]] @@ -7292,15 +7398,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -7347,7 +7452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.6.0", + "bitflags 2.9.3", "serde", "serde_derive", ] @@ -7364,23 +7469,23 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.3.1" +version = "7.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" +checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39" dependencies = [ "libc", "rtoolbox", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "rtoolbox" -version = "0.0.2" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" +checksum = "a7cc970b249fbe527d6e02e0a227762c9108b2f49d81094fe357ffc6d14d7f6f" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -7420,7 +7525,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "fallible-iterator 0.3.0", "fallible-streaming-iterator", "hashlink 0.10.0", @@ -7457,15 +7562,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -7478,15 +7583,15 @@ dependencies = [ [[package]] name = "rustify" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d375f36613139ffb8d55ead633a4904c74ffa1279cbdd2b96a037184cb56d932" +checksum = "759a090a17ce545d1adcffcc48207d5136c8984d8153bd8247b1ad4a71e49f5f" dependencies = [ "anyhow", "async-trait", "bytes", - "http 1.1.0", - "reqwest 0.12.9", + "http 1.3.1", + "reqwest 0.12.23", "rustify_derive", "serde", "serde_json", @@ -7498,9 +7603,9 @@ dependencies = [ [[package]] name = "rustify_derive" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7345f32672da54338227b727bd578c897859ddfaad8952e0b0d787fb4e58f07d" +checksum = "f07d43b2dbdbd99aaed648192098f0f413b762f0f352667153934ef3955f1793" dependencies = [ "proc-macro2", "quote", @@ -7512,28 +7617,28 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "errno", "libc", - "linux-raw-sys 0.4.14", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -7543,7 +7648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fc84bf7e9aa16c4f2c758f27412dc9841341e16aa682d9c7ac308fe3ee12056" dependencies = [ "once_cell", - "rustix 1.0.5", + "rustix 1.0.8", ] [[package]] @@ -7574,15 +7679,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.8", + "rustls-webpki 0.103.4", "subtle", "zeroize", ] @@ -7636,6 +7741,7 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ + "web-time", "zeroize", ] @@ -7660,17 +7766,28 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "safetensors" @@ -7719,23 +7836,47 @@ checksum = "ece8e78b2f38ec51c51f5d475df0a7187ba5111b2a28bdc761ee05b075d40a71" [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 2.11.0", + "schemars_derive", + "semver", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" dependencies = [ - "windows-sys 0.59.0", + "dyn-clone", + "ref-cast", + "serde", + "serde_json", ] [[package]] name = "schemars" -version = "0.8.22" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" dependencies = [ "dyn-clone", - "indexmap 2.7.1", - "schemars_derive", - "semver", + "ref-cast", "serde", "serde_json", ] @@ -7749,7 +7890,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -7829,7 +7970,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -7838,12 +7979,12 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" dependencies = [ - "bitflags 2.6.0", - "core-foundation 0.10.0", + "bitflags 2.9.3", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -7861,24 +8002,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] [[package]] name = "seq-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] @@ -7895,13 +8036,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -7912,23 +8053,23 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "serde_ignored" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf" +checksum = "b516445dac1e3535b6d658a7b528d771153dfb272ed4180ca4617a20550365ff" dependencies = [ "serde", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ "itoa", "memchr", @@ -7938,9 +8079,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" dependencies = [ "itoa", "serde", @@ -7968,20 +8109,20 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -8000,15 +8141,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.11.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.7.1", + "indexmap 2.11.0", + "schemars 0.9.0", + "schemars 1.0.4", "serde", "serde_derive", "serde_json", @@ -8018,14 +8161,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.11.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" dependencies = [ - "darling 0.20.10", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -8034,7 +8177,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.7.1", + "indexmap 2.11.0", "itoa", "ryu", "serde", @@ -8060,9 +8203,9 @@ checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -8071,9 +8214,9 @@ dependencies = [ [[package]] name = "sha256" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +checksum = "f880fc8562bdeb709793f00eb42a2ad0e672c4f883bbe59122b926eca935c8f6" dependencies = [ "async-trait", "bytes", @@ -8105,9 +8248,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -8130,15 +8273,15 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "similar" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "sized-chunks" @@ -8152,18 +8295,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" dependencies = [ "serde", ] @@ -8212,19 +8352,29 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "spdx" -version = "0.10.6" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" +checksum = "c3e17e880bafaeb362a7b751ec46bdc5b61445a188f80e0606e68167cd540fa3" dependencies = [ "smallvec", ] @@ -8248,7 +8398,7 @@ dependencies = [ "spin-factors-test", "spin-locked-app", "tokio", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -8263,7 +8413,7 @@ dependencies = [ "subprocess", "terminal", "tokio", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -8275,7 +8425,7 @@ dependencies = [ "bytes", "cargo-target-dep", "clap 3.2.25", - "clearscreen 4.0.1", + "clearscreen 4.0.2", "comfy-table", "command-group", "conformance", @@ -8285,9 +8435,9 @@ dependencies = [ "fake-opentelemetry-collector", "futures", "hex", - "http 1.1.0", + "http 1.3.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.7.0", "hyper-util", "indicatif", "itertools 0.14.0", @@ -8299,10 +8449,10 @@ dependencies = [ "pretty_assertions", "redis 0.29.5", "regex", - "reqwest 0.12.9", + "reqwest 0.12.23", "rpassword", "runtime-tests", - "schemars", + "schemars 0.8.22", "semver", "serde", "serde_json", @@ -8333,7 +8483,7 @@ dependencies = [ "test-environment", "testing-framework", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", "url", "uuid", @@ -8361,14 +8511,14 @@ dependencies = [ "anyhow", "async-trait", "cap-std", - "rand 0.9.1", + "rand 0.9.2", "rand_chacha 0.3.1", "rand_core 0.6.4", "serde", "serde_json", "tempfile", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", "wasm-encoder 0.236.1", "wasm-metadata 0.236.1", @@ -8386,13 +8536,13 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "async-trait", - "indexmap 2.7.1", + "indexmap 2.11.0", "semver", "spin-app", "spin-common", "spin-componentize", "spin-serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "wac-graph", ] @@ -8422,7 +8572,7 @@ dependencies = [ "anyhow", "async-trait", "glob", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "similar", "spin-common", @@ -8430,7 +8580,7 @@ dependencies = [ "tempfile", "terminal", "tokio", - "toml 0.8.19", + "toml 0.8.23", "toml_edit", "tracing", "ui-testing", @@ -8447,7 +8597,7 @@ dependencies = [ "futures", "futures-util", "id-arena", - "indexmap 2.7.1", + "indexmap 2.11.0", "oci-distribution 0.11.0 (git+https://github.com/fermyon/oci-distribution?rev=7e4ce9be9bcd22e78a28f06204931f10c44402ba)", "semver", "serde", @@ -8459,7 +8609,7 @@ dependencies = [ "spin-manifest", "spin-serde", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", "wac-graph", "wac-types", @@ -8478,9 +8628,9 @@ dependencies = [ "async-trait", "futures", "spin-locked-app", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -8500,9 +8650,9 @@ dependencies = [ "spin-telemetry", "spin-world", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", ] @@ -8522,7 +8672,7 @@ dependencies = [ "spin-telemetry", "spin-world", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", "url", ] @@ -8532,7 +8682,7 @@ name = "spin-factor-otel" version = "3.5.0-pre0" dependencies = [ "anyhow", - "indexmap 2.7.1", + "indexmap 2.11.0", "opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", @@ -8552,12 +8702,12 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "bytes", - "http 1.1.0", + "http 1.3.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.7.0", "hyper-util", - "reqwest 0.12.9", - "rustls 0.23.18", + "reqwest 0.12.23", + "rustls 0.23.31", "serde", "spin-factor-otel", "spin-factor-outbound-networking", @@ -8567,7 +8717,7 @@ dependencies = [ "spin-telemetry", "spin-world", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.2", "tower-service", "tracing", "wasmtime", @@ -8618,9 +8768,9 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "futures-util", - "http 1.1.0", + "http 1.3.1", "ip_network", - "rustls 0.23.18", + "rustls 0.23.31", "rustls-pki-types", "serde", "spin-factor-variables", @@ -8633,11 +8783,11 @@ dependencies = [ "spin-serde", "tempfile", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", "url", "wasmtime-wasi", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] @@ -8737,8 +8887,8 @@ dependencies = [ "serde", "spin-app", "spin-factors-derive", - "thiserror 2.0.12", - "toml 0.8.19", + "thiserror 2.0.16", + "toml 0.8.23", "wasmtime", ] @@ -8749,7 +8899,7 @@ dependencies = [ "expander", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -8774,7 +8924,7 @@ dependencies = [ "spin-loader", "spin-telemetry", "tempfile", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -8782,17 +8932,17 @@ name = "spin-http" version = "3.5.0-pre0" dependencies = [ "anyhow", - "http 1.1.0", + "http 1.3.1", "http-body-util", - "hyper 1.5.0", - "indexmap 2.7.1", + "hyper 1.7.0", + "indexmap 2.11.0", "percent-encoding", "routefinder", "serde", "spin-app", "spin-factor-outbound-http", "spin-http-routes", - "toml 0.8.19", + "toml 0.8.23", "tracing", "wasmtime", "wasmtime-wasi", @@ -8804,7 +8954,7 @@ name = "spin-http-routes" version = "3.5.0-pre0" dependencies = [ "anyhow", - "indexmap 2.7.1", + "indexmap 2.11.0", "percent-encoding", "routefinder", "serde", @@ -8835,7 +8985,7 @@ dependencies = [ "azure_data_cosmos", "azure_identity 0.21.0", "futures", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "spin-factor-key-value", ] @@ -8874,7 +9024,7 @@ dependencies = [ "candle-core", "candle-nn", "candle-transformers", - "rand 0.9.1", + "rand 0.9.2", "safetensors 0.5.3", "serde", "serde_json", @@ -8891,7 +9041,7 @@ name = "spin-llm-remote-http" version = "3.5.0-pre0" dependencies = [ "anyhow", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "serde_json", "spin-telemetry", @@ -8908,7 +9058,7 @@ dependencies = [ "futures", "glob", "path-absolutize", - "reqwest 0.12.9", + "reqwest 0.12.23", "semver", "serde", "serde_json", @@ -8922,7 +9072,7 @@ dependencies = [ "tempfile", "terminal", "tokio", - "toml 0.8.19", + "toml 0.8.23", "tracing", "ui-testing", "wasm-pkg-client", @@ -8938,7 +9088,7 @@ dependencies = [ "serde", "serde_json", "spin-serde", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -8947,15 +9097,15 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "glob", - "indexmap 2.7.1", - "schemars", + "indexmap 2.11.0", + "schemars 0.8.22", "semver", "serde", "serde_json", "spin-serde", "terminal", - "thiserror 2.0.12", - "toml 0.8.19", + "thiserror 2.0.16", + "toml 0.8.23", "ui-testing", "url", "wasm-pkg-common", @@ -8976,7 +9126,7 @@ dependencies = [ "futures-util", "itertools 0.14.0", "oci-distribution 0.11.0 (git+https://github.com/fermyon/oci-distribution?rev=7b291a39f74d1a3c9499d934a56cae6580fc8e37)", - "reqwest 0.12.9", + "reqwest 0.12.23", "serde", "serde_json", "spin-common", @@ -9001,7 +9151,7 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "futures-util", - "http 1.1.0", + "http 1.3.1", "ip_network", "ip_network_table", "spin-expressions", @@ -9020,7 +9170,7 @@ dependencies = [ "fd-lock", "flate2", "path-absolutize", - "reqwest 0.12.9", + "reqwest 0.12.23", "semver", "serde", "serde_json", @@ -9028,7 +9178,7 @@ dependencies = [ "tar", "tempfile", "terminal", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", "url", @@ -9073,7 +9223,7 @@ dependencies = [ "spin-world", "tempfile", "tokio", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -9110,7 +9260,7 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "base64 0.22.1", - "schemars", + "schemars 0.8.22", "semver", "serde", "wasm-pkg-common", @@ -9125,7 +9275,7 @@ dependencies = [ "spin-factors", "spin-sqlite-inproc", "spin-sqlite-libsql", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -9158,7 +9308,7 @@ version = "3.5.0-pre0" dependencies = [ "anyhow", "http 0.2.12", - "http 1.1.0", + "http 1.3.1", "opentelemetry", "opentelemetry-appender-tracing", "opentelemetry-otlp", @@ -9179,7 +9329,7 @@ dependencies = [ "flate2", "fs_extra", "heck 0.5.0", - "indexmap 2.7.1", + "indexmap 2.11.0", "itertools 0.14.0", "lazy_static 1.5.0", "liquid", @@ -9188,7 +9338,7 @@ dependencies = [ "path-absolutize", "pathdiff", "regex", - "reqwest 0.12.9", + "reqwest 0.12.23", "semver", "serde", "spin-common", @@ -9197,7 +9347,7 @@ dependencies = [ "tempfile", "terminal", "tokio", - "toml 0.8.19", + "toml 0.8.23", "toml_edit", "url", "walkdir", @@ -9237,11 +9387,11 @@ dependencies = [ "anyhow", "clap 3.2.25", "futures", - "http 1.1.0", + "http 1.3.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.7.0", "hyper-util", - "rustls 0.23.18", + "rustls 0.23.31", "rustls-pki-types", "serde", "serde_json", @@ -9258,7 +9408,7 @@ dependencies = [ "spin-world", "terminal", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.2", "tracing", "wasmtime-wasi", "wasmtime-wasi-http", @@ -9318,7 +9468,7 @@ dependencies = [ "spin-expressions", "spin-factors", "tempfile", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -9435,7 +9585,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -9467,9 +9617,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -9484,9 +9634,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -9505,13 +9655,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -9520,7 +9670,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "byteorder", "enum-as-inner", "libc", @@ -9534,7 +9684,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "byteorder", "enum-as-inner", "libc", @@ -9559,7 +9709,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -9586,17 +9736,17 @@ dependencies = [ [[package]] name = "system-interface" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b858526d22750088a9b3cf2e3c2aacebd5377f13adeec02860c30d09113010a6" +checksum = "cc4592f674ce18521c2a81483873a49596655b179f71c5e05d10c1fe66c78745" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.3", "cap-fs-ext", "cap-std", "fd-lock", "io-lifetimes", - "rustix 0.38.40", - "windows-sys 0.52.0", + "rustix 0.38.44", + "windows-sys 0.59.0", "winx", ] @@ -9614,38 +9764,38 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", - "xattr 1.3.1", + "xattr 1.5.1", ] [[package]] name = "target-lexicon" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc12939a1c9b9d391e0b7135f72fd30508b73450753e28341fed159317582a77" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "temp-dir" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc1ee6eef34f12f765cb94725905c6312b6610ab2b0940889cfe58dae7bc3c72" +checksum = "83176759e9416cf81ee66cb6508dbfe9c96f20b8b56265a39917551c23c70964" [[package]] name = "tempfile" -version = "3.14.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" dependencies = [ - "cfg-if", - "fastrand 2.2.0", + "fastrand 2.3.0", + "getrandom 0.3.3", "once_cell", - "rustix 0.38.40", - "windows-sys 0.59.0", + "rustix 1.0.8", + "windows-sys 0.60.2", ] [[package]] @@ -9695,7 +9845,7 @@ version = "0.0.0" dependencies = [ "heck 0.5.0", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -9714,7 +9864,7 @@ dependencies = [ "anyhow", "fslock", "regex", - "reqwest 0.12.9", + "reqwest 0.12.23", "temp-dir", "tokio", ] @@ -9724,11 +9874,11 @@ name = "testing-framework" version = "0.1.0" dependencies = [ "anyhow", - "http 1.1.0", + "http 1.3.1", "http-body-util", "log", "nix 0.29.0", - "reqwest 0.12.9", + "reqwest 0.12.23", "spin-app", "spin-http", "spin-loader", @@ -9741,9 +9891,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" [[package]] name = "thiserror" @@ -9756,11 +9906,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.16", ] [[package]] @@ -9771,28 +9921,27 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -9806,9 +9955,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -9824,15 +9973,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -9858,9 +10007,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -9868,9 +10017,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -9883,31 +10032,33 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokenizers" -version = "0.21.1" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3169b3195f925496c895caee7978a335d49218488ef22375267fba5a46a40bd7" +checksum = "a620b996116a59e184c2fa2dfd8251ea34a36d0a514758c6f966386bd2e03476" dependencies = [ + "ahash 0.8.12", "aho-corasick", + "compact_str", + "dary_heap", "derive_builder 0.20.2", "esaxx-rs", - "getrandom 0.2.15", + "getrandom 0.3.3", "indicatif", - "itertools 0.13.0", - "lazy_static 1.5.0", + "itertools 0.14.0", "log", "macro_rules_attribute", "monostate", "onig", "paste", - "rand 0.8.5", + "rand 0.9.2", "rayon", "rayon-cond", "regex", - "regex-syntax 0.8.5", + "regex-syntax", "serde", "serde_json", "spm_precompiled", - "thiserror 2.0.12", + "thiserror 2.0.16", "unicode-normalization-alignments", "unicode-segmentation", "unicode_categories", @@ -9915,20 +10066,22 @@ dependencies = [ [[package]] name = "tokio" -version = "1.45.1" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio 1.0.4", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "slab", + "socket2 0.6.0", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -9939,7 +10092,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -9954,9 +10107,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b5d3742945bc7d7f210693b0c58ae542c6fd47b17adbbda0885f3dcb34a6bdb" +checksum = "6c95d533c83082bb6490e0189acaa0bbeef9084e60471b696ca6988cd0541fb0" dependencies = [ "async-trait", "byteorder", @@ -9971,8 +10124,8 @@ dependencies = [ "pin-project-lite", "postgres-protocol", "postgres-types", - "rand 0.8.5", - "socket2", + "rand 0.9.2", + "socket2 0.5.10", "tokio", "tokio-util", "whoami", @@ -10001,32 +10154,19 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls 0.23.18", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-socks" -version = "0.5.2" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "either", - "futures-util", - "thiserror 1.0.69", + "rustls 0.23.31", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -10035,9 +10175,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -10058,11 +10198,11 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ - "indexmap 2.7.1", + "indexmap 2.11.0", "serde", "serde_spanned", "toml_datetime", @@ -10071,26 +10211,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.7.1", + "indexmap 2.11.0", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tonic" version = "0.12.3" @@ -10102,17 +10249,17 @@ dependencies = [ "axum", "base64 0.22.1", "bytes", - "h2 0.4.6", - "http 1.1.0", + "h2 0.4.12", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.7.0", "hyper-timeout", "hyper-util", "percent-encoding", "pin-project", - "prost 0.13.3", - "socket2", + "prost 0.13.5", + "socket2 0.5.10", "tokio", "tokio-stream", "tower 0.4.13", @@ -10156,7 +10303,26 @@ dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.9.3", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower 0.5.2", "tower-layer", "tower-service", ] @@ -10187,20 +10353,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -10237,9 +10403,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -10247,14 +10413,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "serde", "serde_json", "sharded-slab", @@ -10274,15 +10440,15 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twox-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7b17f197b3050ba473acf9181f7b1d3b66d1cf7356c6cc57886662276e65908" +checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56" [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "tz-rs" @@ -10319,7 +10485,7 @@ dependencies = [ "gemm 0.18.2", "half", "libloading", - "memmap2 0.9.5", + "memmap2 0.9.8", "num", "num-traits", "num_cpus", @@ -10328,7 +10494,7 @@ dependencies = [ "serde", "thiserror 1.0.69", "tracing", - "yoke", + "yoke 0.7.5", ] [[package]] @@ -10380,15 +10546,15 @@ dependencies = [ [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-bidi" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-bom" @@ -10398,9 +10564,9 @@ checksum = "63ec69f541d875b783ca40184d655f2927c95f0bffd486faa83cd3ac3529ec32" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" @@ -10440,9 +10606,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode-xid" @@ -10470,9 +10636,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.3" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", @@ -10486,12 +10652,6 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -10506,36 +10666,38 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.3.3", + "js-sys", + "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" [[package]] name = "vaultrs" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a769a71e45deef489beed23167f79ee75d41f482b5e3d96ddab833f24fd07e51" +checksum = "f81eb4d9221ca29bad43d4b6871b6d2e7656e1af2cfca624a87e5d17880d831d" dependencies = [ "async-trait", "bytes", "derive_builder 0.12.0", - "http 1.1.0", - "reqwest 0.12.9", + "http 1.3.1", + "reqwest 0.12.23", "rustify", "rustify_derive", "serde", @@ -10585,7 +10747,7 @@ checksum = "0d94f428d894714ffba71621dd5fde3b5a52feb6a0ec96aded6207f85057dffc" dependencies = [ "anyhow", "id-arena", - "indexmap 2.7.1", + "indexmap 2.11.0", "log", "petgraph", "semver", @@ -10604,7 +10766,7 @@ checksum = "6690e903d48e7258ea5e623c3269452c81ce1c9bfa8ffcb9c8909d77861fff6a" dependencies = [ "anyhow", "id-arena", - "indexmap 2.7.1", + "indexmap 2.11.0", "semver", "wasm-encoder 0.235.0", "wasmparser 0.235.0", @@ -10641,7 +10803,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98505d42b5289563c6d659f625b6789a97980166508bd00862c4328bf41c261" dependencies = [ - "indexmap 2.7.1", + "indexmap 2.11.0", "itertools 0.12.1", "serde", "serde_with", @@ -10660,11 +10822,11 @@ dependencies = [ "async-recursion", "async-trait", "bytes", - "clap 4.5.20", + "clap 4.5.46", "dialoguer", "dirs 5.0.1", "futures-util", - "indexmap 2.7.1", + "indexmap 2.11.0", "itertools 0.12.1", "keyring", "libc", @@ -10672,7 +10834,7 @@ dependencies = [ "once_cell", "pathdiff", "ptree", - "reqwest 0.12.9", + "reqwest 0.12.23", "secrecy", "semver", "serde", @@ -10745,7 +10907,7 @@ dependencies = [ "anyhow", "base64 0.21.7", "hex", - "indexmap 2.7.1", + "indexmap 2.11.0", "pbjson-types", "prost 0.12.6", "prost-types", @@ -10766,7 +10928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b8d8110b6800c43422676201a6a62167769b015ca29a8fcab67d789ac8b9c63" dependencies = [ "anyhow", - "indexmap 2.7.1", + "indexmap 2.11.0", "prost 0.12.6", "thiserror 1.0.69", "warg-crypto", @@ -10781,17 +10943,17 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.3+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] @@ -10802,47 +10964,48 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10850,22 +11013,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-compose" @@ -10876,7 +11042,7 @@ dependencies = [ "anyhow", "heck 0.4.1", "im-rc", - "indexmap 2.7.1", + "indexmap 2.11.0", "log", "petgraph", "serde", @@ -10928,6 +11094,16 @@ dependencies = [ "wasmparser 0.236.1", ] +[[package]] +name = "wasm-encoder" +version = "0.238.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50143b010bdc3adbd16275710f9085cc80d9c12cb869309a51a98ce2ff96558e" +dependencies = [ + "leb128fmt", + "wasmparser 0.238.0", +] + [[package]] name = "wasm-metadata" version = "0.224.1" @@ -10935,7 +11111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c93c9e49fa2749be3c5ab28ad4be03167294915cd3b2ded3f04f760cef5cfb86" dependencies = [ "anyhow", - "indexmap 2.7.1", + "indexmap 2.11.0", "serde", "serde_derive", "serde_json", @@ -10954,7 +11130,7 @@ dependencies = [ "anyhow", "auditable-serde", "flate2", - "indexmap 2.7.1", + "indexmap 2.11.0", "serde", "serde_derive", "serde_json", @@ -10973,7 +11149,7 @@ dependencies = [ "anyhow", "auditable-serde", "flate2", - "indexmap 2.7.1", + "indexmap 2.11.0", "serde", "serde_derive", "serde_json", @@ -10998,7 +11174,7 @@ dependencies = [ "futures-util", "oci-client", "oci-wasm", - "reqwest 0.12.9", + "reqwest 0.12.23", "secrecy", "serde", "serde_json", @@ -11006,7 +11182,7 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tokio-util", - "toml 0.8.19", + "toml 0.8.23", "tracing", "tracing-subscriber", "url", @@ -11028,14 +11204,14 @@ dependencies = [ "bytes", "etcetera", "futures-util", - "http 1.1.0", + "http 1.3.1", "semver", "serde", "serde_json", "sha2", "thiserror 1.0.69", "tokio", - "toml 0.8.19", + "toml 0.8.23", ] [[package]] @@ -11057,8 +11233,8 @@ version = "0.121.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe55c8f9d0dbd25d9447a5a889ff90c0cc3feaa7395310d3d826b2c703eaab" dependencies = [ - "bitflags 2.6.0", - "indexmap 2.7.1", + "bitflags 2.9.3", + "indexmap 2.11.0", "semver", ] @@ -11068,9 +11244,9 @@ version = "0.224.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" dependencies = [ - "bitflags 2.6.0", - "hashbrown 0.15.2", - "indexmap 2.7.1", + "bitflags 2.9.3", + "hashbrown 0.15.5", + "indexmap 2.11.0", "semver", ] @@ -11080,9 +11256,9 @@ version = "0.235.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "161296c618fa2d63f6ed5fffd1112937e803cb9ec71b32b01a76321555660917" dependencies = [ - "bitflags 2.6.0", - "hashbrown 0.15.2", - "indexmap 2.7.1", + "bitflags 2.9.3", + "hashbrown 0.15.5", + "indexmap 2.11.0", "semver", "serde", ] @@ -11093,13 +11269,24 @@ version = "0.236.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" dependencies = [ - "bitflags 2.6.0", - "hashbrown 0.15.2", - "indexmap 2.7.1", + "bitflags 2.9.3", + "hashbrown 0.15.5", + "indexmap 2.11.0", "semver", "serde", ] +[[package]] +name = "wasmparser" +version = "0.238.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ad4ca2ecb86b79ea410cd970985665de1d05774b7107b214bc5852b1bcbad7" +dependencies = [ + "bitflags 2.9.3", + "indexmap 2.11.0", + "semver", +] + [[package]] name = "wasmprinter" version = "0.2.80" @@ -11130,15 +11317,15 @@ dependencies = [ "addr2line 0.25.0", "anyhow", "async-trait", - "bitflags 2.6.0", + "bitflags 2.9.3", "bumpalo", "cc", "cfg-if", "encoding_rs", "fxprof-processed-profile", - "gimli 0.32.0", - "hashbrown 0.15.2", - "indexmap 2.7.1", + "gimli 0.32.2", + "hashbrown 0.15.5", + "indexmap 2.11.0", "ittapi", "libc", "log", @@ -11149,7 +11336,7 @@ dependencies = [ "postcard", "pulley-interpreter", "rayon", - "rustix 1.0.5", + "rustix 1.0.8", "semver", "serde", "serde_derive", @@ -11186,8 +11373,8 @@ dependencies = [ "cpp_demangle", "cranelift-bitset", "cranelift-entity", - "gimli 0.32.0", - "indexmap 2.7.1", + "gimli 0.32.2", + "indexmap 2.11.0", "log", "object 0.37.3", "postcard", @@ -11223,11 +11410,11 @@ dependencies = [ "directories-next", "log", "postcard", - "rustix 1.0.5", + "rustix 1.0.8", "serde", "serde_derive", "sha2", - "toml 0.8.19", + "toml 0.8.23", "windows-sys 0.60.2", "zstd", ] @@ -11241,7 +11428,7 @@ dependencies = [ "anyhow", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "wasmtime-internal-component-util", "wasmtime-internal-wit-bindgen", "wit-parser 0.236.1", @@ -11266,14 +11453,14 @@ dependencies = [ "cranelift-entity", "cranelift-frontend", "cranelift-native", - "gimli 0.32.0", + "gimli 0.32.2", "itertools 0.14.0", "log", "object 0.37.3", "pulley-interpreter", "smallvec", "target-lexicon", - "thiserror 2.0.12", + "thiserror 2.0.16", "wasmparser 0.236.1", "wasmtime-environ", "wasmtime-internal-math", @@ -11290,7 +11477,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "rustix 1.0.5", + "rustix 1.0.8", "wasmtime-internal-asm-macros", "wasmtime-internal-versioned-export-macros", "windows-sys 0.60.2", @@ -11304,7 +11491,7 @@ checksum = "e03f0b11f8fe4d456feac11e7e9dc6f02ddb34d4f6a1912775dbc63c5bdd5670" dependencies = [ "cc", "object 0.37.3", - "rustix 1.0.5", + "rustix 1.0.8", "wasmtime-internal-versioned-export-macros", ] @@ -11356,7 +11543,7 @@ checksum = "c61c7f75326434944cc5f3b75409a063fa37e537f6247f00f0f733679f0be406" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -11367,7 +11554,7 @@ checksum = "6cfbaa87e1ac4972bb096c9cb1800fedc113e36332cc4bc2c96a2ef1d7c5e750" dependencies = [ "anyhow", "cranelift-codegen", - "gimli 0.32.0", + "gimli 0.32.2", "object 0.37.3", "target-lexicon", "wasmparser 0.236.1", @@ -11383,9 +11570,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "169042d58002f16da149ab7d608b71164411abd1fc5140f48f4c200b44bb5565" dependencies = [ "anyhow", - "bitflags 2.6.0", + "bitflags 2.9.3", "heck 0.5.0", - "indexmap 2.7.1", + "indexmap 2.11.0", "wit-parser 0.236.1", ] @@ -11397,7 +11584,7 @@ checksum = "b9049a5fedcd24fa0f665ba7c17c4445c1a547536a9560d960e15bee2d8428d0" dependencies = [ "anyhow", "async-trait", - "bitflags 2.6.0", + "bitflags 2.9.3", "bytes", "cap-fs-ext", "cap-net-ext", @@ -11408,9 +11595,9 @@ dependencies = [ "futures", "io-extras", "io-lifetimes", - "rustix 1.0.5", + "rustix 1.0.8", "system-interface", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", "url", @@ -11430,10 +11617,10 @@ dependencies = [ "async-trait", "bytes", "futures", - "http 1.1.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.7.0", "rustls 0.22.4", "tokio", "tokio-rustls 0.25.0", @@ -11441,7 +11628,7 @@ dependencies = [ "wasmtime", "wasmtime-wasi", "wasmtime-wasi-io", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] @@ -11468,24 +11655,24 @@ dependencies = [ [[package]] name = "wast" -version = "236.0.1" +version = "238.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3bec4b4db9c6808d394632fd4b0cd4654c32c540bd3237f55ee6a40fff6e51f" +checksum = "8c671ea796336ebaa49b963adb14cf13cb98de4e64d69ed4a16ace8c7b4db87b" dependencies = [ "bumpalo", "leb128fmt", "memchr", - "unicode-width 0.2.0", - "wasm-encoder 0.236.1", + "unicode-width 0.2.1", + "wasm-encoder 0.238.0", ] [[package]] name = "wat" -version = "1.236.1" +version = "1.238.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64475e2f77d6071ce90624098fc236285ddafa8c3ea1fb386f2c4154b6c2bbdb" +checksum = "8de04a6a9c93aaae4de7bec6323bf11f810457b479f9f877e80d212fd77ffdbc" dependencies = [ - "wast 236.0.1", + "wast 238.0.0", ] [[package]] @@ -11559,9 +11746,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -11579,9 +11766,18 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.2", +] + +[[package]] +name = "webpki-roots" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] @@ -11595,28 +11791,27 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.40", + "rustix 0.38.44", ] [[package]] name = "which" -version = "7.0.3" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762" +checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ - "either", "env_home", - "rustix 1.0.5", + "rustix 1.0.8", "winsafe", ] [[package]] name = "whoami" -version = "1.5.2" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ - "redox_syscall 0.5.7", + "libredox", "wasite", "web-sys", ] @@ -11629,8 +11824,8 @@ checksum = "e233166bc0ef02371ebe2c630aba51dd3f015bcaf616d32b4171efab84d09137" dependencies = [ "anyhow", "async-trait", - "bitflags 2.6.0", - "thiserror 2.0.12", + "bitflags 2.9.3", + "thiserror 2.0.16", "tracing", "wasmtime", "wiggle-macro", @@ -11646,7 +11841,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "witx", ] @@ -11658,7 +11853,7 @@ checksum = "fd7e511edbcaa045079dea564486c4ff7946ae491002227c41d74ea62a59d329" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "wiggle-generate", ] @@ -11680,11 +11875,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -11702,11 +11897,11 @@ dependencies = [ "anyhow", "cranelift-assembler-x64", "cranelift-codegen", - "gimli 0.32.0", + "gimli 0.32.2", "regalloc2", "smallvec", "target-lexicon", - "thiserror 2.0.12", + "thiserror 2.0.16", "wasmparser 0.236.1", "wasmtime-environ", "wasmtime-internal-cranelift", @@ -11735,7 +11930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core", "windows-future", "windows-link", "windows-numerics", @@ -11747,16 +11942,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", + "windows-core", ] [[package]] @@ -11768,8 +11954,8 @@ dependencies = [ "windows-implement", "windows-interface", "windows-link", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-result", + "windows-strings", ] [[package]] @@ -11778,7 +11964,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core 0.61.2", + "windows-core", "windows-link", "windows-threading", ] @@ -11791,7 +11977,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -11802,7 +11988,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -11817,28 +12003,19 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core 0.61.2", + "windows-core", "windows-link", ] [[package]] name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-targets 0.52.6", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] @@ -11850,16 +12027,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -12168,9 +12335,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -12193,22 +12360,19 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "winx" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" +checksum = "3f3fd376f71958b862e7afb20cfe5a22830e1963462f3a17f49d82a6c1d1f42d" dependencies = [ - "bitflags 2.6.0", - "windows-sys 0.52.0", + "bitflags 2.9.3", + "windows-sys 0.59.0", ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.6.0", -] +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" [[package]] name = "wit-component" @@ -12217,8 +12381,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "923637fe647372efbbb654757f8c884ba280924477e1d265eca7e35d4cdcea8b" dependencies = [ "anyhow", - "bitflags 2.6.0", - "indexmap 2.7.1", + "bitflags 2.9.3", + "indexmap 2.11.0", "log", "serde", "serde_derive", @@ -12236,8 +12400,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a57a11109cc553396f89f3a38a158a97d0b1adaec113bd73e0f64d30fb601f" dependencies = [ "anyhow", - "bitflags 2.6.0", - "indexmap 2.7.1", + "bitflags 2.9.3", + "indexmap 2.11.0", "log", "serde", "serde_derive", @@ -12255,8 +12419,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3622959ed7ed6341c38e5aa35af243632534b0a36226852faa802939ce11e00f" dependencies = [ "anyhow", - "bitflags 2.6.0", - "indexmap 2.7.1", + "bitflags 2.9.3", + "indexmap 2.11.0", "log", "serde", "serde_derive", @@ -12289,7 +12453,7 @@ checksum = "e3477d8d0acb530d76beaa8becbdb1e3face08929db275f39934963eb4f716f8" dependencies = [ "anyhow", "id-arena", - "indexmap 2.7.1", + "indexmap 2.11.0", "log", "semver", "serde", @@ -12307,7 +12471,7 @@ checksum = "0a1f95a87d03a33e259af286b857a95911eb46236a0f726cbaec1227b3dfc67a" dependencies = [ "anyhow", "id-arena", - "indexmap 2.7.1", + "indexmap 2.11.0", "log", "semver", "serde", @@ -12325,7 +12489,7 @@ checksum = "16e4833a20cd6e85d6abfea0e63a399472d6f88c6262957c17f546879a80ba15" dependencies = [ "anyhow", "id-arena", - "indexmap 2.7.1", + "indexmap 2.11.0", "log", "semver", "serde", @@ -12347,17 +12511,11 @@ dependencies = [ "wast 35.0.2", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "wyz" @@ -12379,13 +12537,12 @@ dependencies = [ [[package]] name = "xattr" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" dependencies = [ "libc", - "linux-raw-sys 0.4.14", - "rustix 0.38.40", + "rustix 1.0.8", ] [[package]] @@ -12423,26 +12580,50 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", - "yoke-derive", + "yoke-derive 0.7.5", + "zerofrom", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive 0.8.0", "zerofrom", ] [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "synstructure 0.13.2", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", - "synstructure 0.13.1", + "syn 2.0.106", + "synstructure 0.13.2", ] [[package]] @@ -12462,7 +12643,7 @@ dependencies = [ "async-trait", "blocking", "enumflags2", - "event-listener 5.3.1", + "event-listener 5.4.1", "futures-core", "futures-sink", "futures-util", @@ -12492,7 +12673,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "zvariant_utils", ] @@ -12509,44 +12690,43 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", - "synstructure 0.13.1", + "syn 2.0.106", + "synstructure 0.13.2", ] [[package]] @@ -12554,27 +12734,52 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke 0.8.0", + "zerofrom", +] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ - "yoke", + "yoke 0.8.0", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] [[package]] @@ -12587,34 +12792,34 @@ dependencies = [ "crc32fast", "crossbeam-utils", "displaydoc", - "indexmap 2.7.1", + "indexmap 2.11.0", "num_enum", "thiserror 1.0.69", ] [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.1" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", @@ -12642,7 +12847,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", "zvariant_utils", ] @@ -12654,5 +12859,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.106", ] diff --git a/Cargo.toml b/Cargo.toml index b030d88b01..c2f3742839 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -144,8 +144,9 @@ indexmap = "2" itertools = "0.14" lazy_static = "1.5" opentelemetry = "0.28" -opentelemetry-otlp = "0.28" -opentelemetry_sdk = "0.28" +# The default `reqwest-blocking-client` causes a runtime panic +opentelemetry-otlp = { version = "0.28", default-features = false, features = ["http-proto", "reqwest-client", "logs"]} +opentelemetry_sdk = {version = "0.28", features = ["experimental_metrics_periodicreader_with_async_runtime", "experimental_trace_batch_span_processor_with_async_runtime"]} path-absolutize = "3" quote = "1" rand = "0.9" diff --git a/crates/factor-otel/Cargo.toml b/crates/factor-otel/Cargo.toml index 41f9498802..66bb28e40c 100644 --- a/crates/factor-otel/Cargo.toml +++ b/crates/factor-otel/Cargo.toml @@ -9,7 +9,7 @@ anyhow = { workspace = true } indexmap = "2.2.6" opentelemetry = { workspace = true } opentelemetry_sdk = { workspace = true } -opentelemetry-otlp = { workspace = true, features = ["http-proto", "http", "reqwest-client"] } +opentelemetry-otlp = { workspace = true } spin-core = { path = "../core" } spin-factors = { path = "../factors" } spin-resource-table = { path = "../table" } @@ -22,4 +22,4 @@ tracing-opentelemetry = { workspace = true } toml = "0.5" [lints] -workspace = true +workspace = true \ No newline at end of file diff --git a/crates/factor-otel/src/host.rs b/crates/factor-otel/src/host.rs index 12513ab9e2..36f322375a 100644 --- a/crates/factor-otel/src/host.rs +++ b/crates/factor-otel/src/host.rs @@ -1,15 +1,15 @@ use anyhow::anyhow; use anyhow::Result; use opentelemetry::trace::TraceContextExt; +use opentelemetry_sdk::metrics::exporter::PushMetricExporter; use opentelemetry_sdk::trace::SpanProcessor; -use spin_world::wasi::otel::tracing as wasi_otel; - +use spin_world::wasi; use tracing_opentelemetry::OpenTelemetrySpanExt; use crate::InstanceState; -impl wasi_otel::Host for InstanceState { - async fn on_start(&mut self, context: wasi_otel::SpanContext) -> Result<()> { +impl wasi::otel::tracing::Host for InstanceState { + async fn on_start(&mut self, context: wasi::otel::tracing::SpanContext) -> Result<()> { let mut state = self.state.write().unwrap(); // Before we do anything make sure we track the original host span ID for reparenting @@ -32,7 +32,7 @@ impl wasi_otel::Host for InstanceState { Ok(()) } - async fn on_end(&mut self, span_data: wasi_otel::SpanData) -> Result<()> { + async fn on_end(&mut self, span_data: wasi::otel::tracing::SpanData) -> Result<()> { let mut state = self.state.write().unwrap(); let span_context: opentelemetry::trace::SpanContext = span_data.span_context.clone().into(); @@ -42,12 +42,12 @@ impl wasi_otel::Host for InstanceState { Err(anyhow!("Trying to end a span that was not started"))?; } - self.processor.on_end(span_data.into()); + self.span_processor.on_end(span_data.into()); Ok(()) } - async fn outer_span_context(&mut self) -> Result { + async fn outer_span_context(&mut self) -> Result { Ok(tracing::Span::current() .context() .span() @@ -56,3 +56,16 @@ impl wasi_otel::Host for InstanceState { .into()) } } + +impl wasi::otel::metrics::Host for InstanceState { + async fn collect( + &mut self, + metrics: wasi::otel::metrics::ResourceMetrics, + ) -> spin_core::wasmtime::Result> { + let mut rm: opentelemetry_sdk::metrics::data::ResourceMetrics = metrics.into(); + match self.metric_exporter.export(&mut rm).await { + Ok(_) => Ok(Ok(())), + Err(e) => Ok(Err(e.into())), + } + } +} diff --git a/crates/factor-otel/src/lib.rs b/crates/factor-otel/src/lib.rs index 46bae13f25..c224ce3730 100644 --- a/crates/factor-otel/src/lib.rs +++ b/crates/factor-otel/src/lib.rs @@ -1,26 +1,26 @@ mod host; -use std::{ - sync::{Arc, RwLock}, -}; - use anyhow::bail; use indexmap::IndexMap; use opentelemetry::{ trace::{SpanContext, SpanId, TraceContextExt}, Context, }; +use opentelemetry_otlp::MetricExporter; use opentelemetry_sdk::{ - resource::{EnvResourceDetector, TelemetryResourceDetector}, - trace::{BatchSpanProcessor, SpanProcessor}, + resource::{EnvResourceDetector, ResourceDetector, TelemetryResourceDetector}, + runtime::Tokio, + trace::{span_processor_with_async_runtime::BatchSpanProcessor, SpanProcessor}, Resource, }; use spin_factors::{Factor, FactorData, PrepareContext, RuntimeFactors, SelfInstanceBuilder}; use spin_telemetry::{detector::SpinResourceDetector, env::OtlpProtocol}; +use std::sync::{Arc, RwLock}; use tracing_opentelemetry::OpenTelemetrySpanExt; pub struct OtelFactor { - processor: Arc, + span_processor: Arc>, + metric_exporter: Arc, } impl Factor for OtelFactor { @@ -30,6 +30,7 @@ impl Factor for OtelFactor { fn init(&mut self, ctx: &mut impl spin_factors::InitContext) -> anyhow::Result<()> { ctx.link_bindings(spin_world::wasi::otel::tracing::add_to_linker::<_, FactorData>)?; + ctx.link_bindings(spin_world::wasi::otel::metrics::add_to_linker::<_, FactorData>)?; Ok(()) } @@ -49,15 +50,31 @@ impl Factor for OtelFactor { guest_span_contexts: Default::default(), original_host_span_id: None, })), - processor: self.processor.clone(), + span_processor: self.span_processor.clone(), + metric_exporter: self.metric_exporter.clone(), }) } } impl OtelFactor { pub fn new() -> anyhow::Result { + // This is a hack b/c we know the version of this crate will be the same as the version of Spin + let spin_version = env!("CARGO_PKG_VERSION").to_string(); + + let resource = Resource::builder() + .with_detectors(&[ + // Set service.name from env OTEL_SERVICE_NAME > env OTEL_RESOURCE_ATTRIBUTES > spin + // Set service.version from Spin metadata + Box::new(SpinResourceDetector::new(spin_version)) as Box, + // Sets fields from env OTEL_RESOURCE_ATTRIBUTES + Box::new(EnvResourceDetector::new()), + // Sets telemetry.sdk{name, language, version} + Box::new(TelemetryResourceDetector), + ]) + .build(); + // This will configure the exporter based on the OTEL_EXPORTER_* environment variables. - let exporter = match OtlpProtocol::traces_protocol_from_env() { + let span_exporter = match OtlpProtocol::traces_protocol_from_env() { OtlpProtocol::Grpc => opentelemetry_otlp::SpanExporter::builder() .with_tonic() .build()?, @@ -67,32 +84,31 @@ impl OtelFactor { OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"), }; - let mut processor = opentelemetry_sdk::trace::BatchSpanProcessor::builder(exporter).build(); + let mut span_processor = BatchSpanProcessor::builder(span_exporter, Tokio).build(); - // This is a hack b/c we know the version of this crate will be the same as the version of Spin - let spin_version = env!("CARGO_PKG_VERSION").to_string(); + span_processor.set_resource(&resource); - let detectors: &[Box; 3] = &[ - // Set service.name from env OTEL_SERVICE_NAME > env OTEL_RESOURCE_ATTRIBUTES > spin - // Set service.version from Spin metadata - Box::new(SpinResourceDetector::new(spin_version)), - // Sets fields from env OTEL_RESOURCE_ATTRIBUTES - Box::new(EnvResourceDetector::new()), - // Sets telemetry.sdk{name, language, version} - Box::new(TelemetryResourceDetector), - ]; - - processor.set_resource(&Resource::builder().with_detectors(detectors).build()); + let metric_exporter = match OtlpProtocol::metrics_protocol_from_env() { + OtlpProtocol::Grpc => opentelemetry_otlp::MetricExporter::builder() + .with_tonic() + .build()?, + OtlpProtocol::HttpProtobuf => opentelemetry_otlp::MetricExporter::builder() + .with_http() + .build()?, + OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"), + }; Ok(Self { - processor: Arc::new(processor), + span_processor: Arc::new(span_processor), + metric_exporter: Arc::new(metric_exporter), }) } } pub struct InstanceState { pub(crate) state: Arc>, - pub(crate) processor: Arc, + pub(crate) span_processor: Arc>, + pub(crate) metric_exporter: Arc, } impl SelfInstanceBuilder for InstanceState {} diff --git a/crates/telemetry/src/metrics.rs b/crates/telemetry/src/metrics.rs index 2dc2ed811c..9c76090d62 100644 --- a/crates/telemetry/src/metrics.rs +++ b/crates/telemetry/src/metrics.rs @@ -1,8 +1,9 @@ use anyhow::{bail, Result}; use opentelemetry::global; use opentelemetry_sdk::{ - metrics::{PeriodicReader, SdkMeterProvider}, + metrics::{periodic_reader_with_async_runtime::PeriodicReader, SdkMeterProvider}, resource::{EnvResourceDetector, ResourceDetector, TelemetryResourceDetector}, + runtime::Tokio, Resource, }; use tracing::Subscriber; @@ -45,7 +46,7 @@ pub(crate) fn otel_metrics_layer LookupSpan<'span>>( OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"), }; - let reader = PeriodicReader::builder(exporter).build(); + let reader = PeriodicReader::builder(exporter, Tokio).build(); let meter_provider = SdkMeterProvider::builder() .with_reader(reader) .with_resource(resource) diff --git a/crates/telemetry/src/traces.rs b/crates/telemetry/src/traces.rs index fdccd4b44a..0b9f92f020 100644 --- a/crates/telemetry/src/traces.rs +++ b/crates/telemetry/src/traces.rs @@ -2,6 +2,7 @@ use anyhow::bail; use opentelemetry::{global, trace::TracerProvider}; use opentelemetry_sdk::{ resource::{EnvResourceDetector, ResourceDetector, TelemetryResourceDetector}, + runtime::Tokio, Resource, }; use tracing::Subscriber; @@ -42,7 +43,11 @@ pub(crate) fn otel_tracing_layer LookupSpan<'span>>( OtlpProtocol::HttpJson => bail!("http/json OTLP protocol is not supported"), }; - let span_processor = opentelemetry_sdk::trace::BatchSpanProcessor::builder(exporter).build(); + let span_processor = + opentelemetry_sdk::trace::span_processor_with_async_runtime::BatchSpanProcessor::builder( + exporter, Tokio, + ) + .build(); let tracer_provider = opentelemetry_sdk::trace::SdkTracerProvider::builder() .with_resource(resource) diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index 27b2d3705b..563333d284 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -557,13 +557,559 @@ mod llm { mod otel { use super::*; use opentelemetry::StringValue; + use opentelemetry_sdk::error::OTelSdkError; use opentelemetry_sdk::trace::{SpanEvents, SpanLinks}; + use std::borrow::Cow; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use wasi::clocks0_2_0::wall_clock; - use wasi::otel::tracing as wasi_otel; + use wasi::otel::metrics as wasi_metrics; + use wasi::otel::tracing as wasi_tracing; + use wasi::otel::types as wasi_types; - impl From for opentelemetry_sdk::trace::SpanData { - fn from(value: wasi_otel::SpanData) -> Self { + impl From for wasi::otel::metrics::OtelError { + fn from(value: OTelSdkError) -> Self { + match value { + OTelSdkError::AlreadyShutdown => wasi::otel::metrics::OtelError::AlreadyShutdown, + OTelSdkError::InternalFailure(v) => { + wasi::otel::metrics::OtelError::InternalFailure(v) + } + OTelSdkError::Timeout(d) => wasi::otel::metrics::OtelError::Timeout(d.as_secs()), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::ResourceMetrics { + fn from(value: wasi_metrics::ResourceMetrics) -> Self { + Self { + resource: value.resource.into(), + scope_metrics: value.scope_metrics.into_iter().map(Into::into).collect(), + } + } + } + + impl From for opentelemetry_sdk::Resource { + fn from(value: wasi_metrics::Resource) -> Self { + let attributes: Vec = + value.inner.attributes.into_iter().map(Into::into).collect(); + let schema_url: Option = value.inner.schema_url.into(); + + match schema_url { + Some(url) => opentelemetry_sdk::resource::Resource::builder() + .with_schema_url(attributes, url) // TODO: Does this also need `with_attributes`? + .build(), + None => opentelemetry_sdk::resource::Resource::builder() + .with_attributes(attributes) + .build(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::ScopeMetrics { + fn from(value: wasi_metrics::ScopeMetrics) -> Self { + Self { + scope: value.scope.into(), + metrics: value.metrics.into_iter().map(Into::into).collect(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Metric { + fn from(value: wasi_metrics::Metric) -> Self { + Self { + name: Cow::Owned(value.name), + description: Cow::Owned(value.description), + unit: Cow::Owned(value.unit), + data: value.data.into(), + } + } + } + + impl From + for Box + { + fn from(value: wasi_metrics::AggregatedMetrics) -> Self { + use opentelemetry_sdk::metrics::data as O; + use wasi_metrics::AggregatedMetrics; + + fn convert_metric_data( + md: wasi_metrics::MetricData, + ) -> Box + where + T: Clone + std::fmt::Debug + Send + Sync + 'static, + O::Gauge: From, + O::Sum: From, + O::Histogram: From, + O::ExponentialHistogram: From, + { + match md { + wasi_metrics::MetricData::Gauge(gauge) => { + let gauge: O::Gauge = gauge.into(); + Box::new(gauge) + } + wasi_metrics::MetricData::Sum(sum) => { + let sum: O::Sum = sum.into(); + Box::new(sum) + } + wasi_metrics::MetricData::Histogram(hist) => { + let hist: O::Histogram = hist.into(); + Box::new(hist) + } + wasi_metrics::MetricData::ExponentialHistogram(hist) => { + let hist: O::ExponentialHistogram = hist.into(); + Box::new(hist) + } + } + } + match value { + AggregatedMetrics::S64(md) => convert_metric_data::(md), + AggregatedMetrics::U64(md) => convert_metric_data::(md), + AggregatedMetrics::F64(md) => convert_metric_data::(md), + } + } + } + + // TODO: we need to make these generic + impl From for opentelemetry_sdk::metrics::data::Gauge { + fn from(value: wasi_metrics::Gauge) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.into_f64(), + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }) + .collect(), + start_time: value.start_time.map(Into::into), + time: value.time.into(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Gauge { + fn from(value: wasi_metrics::Gauge) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.into_i64(), + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }) + .collect(), + start_time: value.start_time.map(Into::into), + time: value.time.into(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Gauge { + fn from(value: wasi_metrics::Gauge) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.into_u64(), + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }) + .collect(), + start_time: value.start_time.map(Into::into), + time: value.time.into(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Sum { + fn from(value: wasi_metrics::Sum) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.into_f64(), + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + is_monotonic: value.is_monotonic, + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Sum { + fn from(value: wasi_metrics::Sum) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.into_i64(), + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + is_monotonic: value.is_monotonic, + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Sum { + fn from(value: wasi_metrics::Sum) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.into_u64(), + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + is_monotonic: value.is_monotonic, + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Histogram { + fn from(value: wasi_metrics::Histogram) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count, + bounds: dp.bounds, + bucket_counts: dp.bucket_counts, + min: match dp.min { + Some(v) => Some(v.into_f64()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.into_f64()), + None => None, + }, + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + sum: dp.sum.into_f64(), + }) + .collect(), + temporality: value.temporality.into(), + start_time: value.start_time.into(), + time: value.time.into(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Histogram { + fn from(value: wasi_metrics::Histogram) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count, + bounds: dp.bounds, + bucket_counts: dp.bucket_counts, + min: match dp.min { + Some(v) => Some(v.into_i64()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.into_i64()), + None => None, + }, + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + sum: dp.sum.into_i64(), + }) + .collect(), + temporality: value.temporality.into(), + start_time: value.start_time.into(), + time: value.time.into(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Histogram { + fn from(value: wasi_metrics::Histogram) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count, + bounds: dp.bounds, + bucket_counts: dp.bucket_counts, + min: match dp.min { + Some(v) => Some(v.into_u64()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.into_u64()), + None => None, + }, + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + sum: dp.sum.into_u64(), + }) + .collect(), + temporality: value.temporality.into(), + start_time: value.start_time.into(), + time: value.time.into(), + } + } + } + + impl From + for opentelemetry_sdk::metrics::data::ExponentialHistogram + { + fn from(value: wasi_metrics::ExponentialHistogram) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map( + |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count as usize, + min: match dp.min { + Some(v) => Some(v.into_f64()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.into_f64()), + None => None, + }, + sum: dp.sum.into_f64(), + scale: dp.scale, + zero_count: dp.zero_count, + positive_bucket: dp.positive_bucket.into(), + negative_bucket: dp.negative_bucket.into(), + zero_threshold: dp.zero_threshold, + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }, + ) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + } + } + } + + impl From + for opentelemetry_sdk::metrics::data::ExponentialHistogram + { + fn from(value: wasi_metrics::ExponentialHistogram) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map( + |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count as usize, + min: match dp.min { + Some(v) => Some(v.into_i64()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.into_i64()), + None => None, + }, + sum: dp.sum.into_i64(), + scale: dp.scale, + zero_count: dp.zero_count, + positive_bucket: dp.positive_bucket.into(), + negative_bucket: dp.negative_bucket.into(), + zero_threshold: dp.zero_threshold, + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }, + ) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + } + } + } + + impl From + for opentelemetry_sdk::metrics::data::ExponentialHistogram + { + fn from(value: wasi_metrics::ExponentialHistogram) -> Self { + Self { + data_points: value + .data_points + .into_iter() + .map( + |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count as usize, + min: match dp.min { + Some(v) => Some(v.into_u64()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.into_u64()), + None => None, + }, + sum: dp.sum.into_u64(), + scale: dp.scale, + zero_count: dp.zero_count, + positive_bucket: dp.positive_bucket.into(), + negative_bucket: dp.negative_bucket.into(), + zero_threshold: dp.zero_threshold, + exemplars: dp.exemplars.into_iter().map(Into::into).collect(), + }, + ) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::ExponentialBucket { + fn from(value: wasi_metrics::ExponentialBucket) -> Self { + Self { + offset: value.offset, + counts: value.counts, + } + } + } + + impl wasi_metrics::MetricNumber { + pub fn into_f64(self) -> f64 { + match self { + wasi_metrics::MetricNumber::F64(v) => v, + // TODO: validate that this is desirable over just converting i64 and u64 types to f64. + // In my mind, the panic will help reduce bugs (i.e. a float being converted to int) + _ => panic!("value is not f64"), + } + } + + pub fn into_i64(self) -> i64 { + match self { + wasi_metrics::MetricNumber::S64(v) => v, + _ => panic!("value is not i64"), + } + } + + pub fn into_u64(self) -> u64 { + match self { + wasi_metrics::MetricNumber::U64(v) => v, + _ => panic!("value is not u64"), + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Exemplar { + fn from(value: wasi_metrics::Exemplar) -> Self { + let span_id: [u8; 8] = value + .span_id + .as_bytes() + .try_into() + .expect("Span ID is longer than 8 bytes"); + let trace_id: [u8; 16] = value + .trace_id + .as_bytes() + .try_into() + .expect("Trace ID is longer than 16 bytes"); + Self { + filtered_attributes: value + .filtered_attributes + .into_iter() + .map(Into::into) + .collect(), + time: value.time.into(), + value: value.value.into_f64(), + span_id, + trace_id, + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Exemplar { + fn from(value: wasi_metrics::Exemplar) -> Self { + let span_id: [u8; 8] = value + .span_id + .as_bytes() + .try_into() + .expect("Span ID is longer than 8 bytes"); + let trace_id: [u8; 16] = value + .trace_id + .as_bytes() + .try_into() + .expect("Trace ID is longer than 16 bytes"); + Self { + filtered_attributes: value + .filtered_attributes + .into_iter() + .map(Into::into) + .collect(), + time: value.time.into(), + value: value.value.into_i64(), + span_id, + trace_id, + } + } + } + + impl From for opentelemetry_sdk::metrics::data::Exemplar { + fn from(value: wasi_metrics::Exemplar) -> Self { + let span_id: [u8; 8] = value + .span_id + .as_bytes() + .try_into() + .expect("Span ID is longer than 8 bytes"); + let trace_id: [u8; 16] = value + .trace_id + .as_bytes() + .try_into() + .expect("Trace ID is longer than 16 bytes"); + Self { + filtered_attributes: value + .filtered_attributes + .into_iter() + .map(Into::into) + .collect(), + time: value.time.into(), + value: value.value.into_u64(), + span_id, + trace_id, + } + } + } + + impl From for opentelemetry_sdk::metrics::Temporality { + fn from(value: wasi_metrics::Temporality) -> Self { + use opentelemetry_sdk::metrics::Temporality as OT; + use wasi_metrics::Temporality as T; + match value { + T::Delta => OT::Delta, + T::LowMemory => OT::LowMemory, + _ => OT::Cumulative, + } + } + } + + impl From for opentelemetry_sdk::trace::SpanData { + fn from(value: wasi_tracing::SpanData) -> Self { let mut span_events = SpanEvents::default(); span_events.events = value.events.into_iter().map(Into::into).collect(); span_events.dropped_count = value.dropped_events; @@ -588,8 +1134,8 @@ mod otel { } } - impl From for opentelemetry::trace::SpanContext { - fn from(sc: wasi_otel::SpanContext) -> Self { + impl From for opentelemetry::trace::SpanContext { + fn from(sc: wasi_tracing::SpanContext) -> Self { let trace_id = opentelemetry::trace::TraceId::from_hex(&sc.trace_id) .unwrap_or(opentelemetry::trace::TraceId::INVALID); let span_id = opentelemetry::trace::SpanId::from_hex(&sc.span_id) @@ -606,7 +1152,7 @@ mod otel { } } - impl From for wasi_otel::SpanContext { + impl From for wasi_tracing::SpanContext { fn from(sc: opentelemetry::trace::SpanContext) -> Self { Self { trace_id: format!("{:x}", sc.trace_id()), @@ -629,62 +1175,62 @@ mod otel { } } - impl From for opentelemetry::trace::TraceFlags { - fn from(flags: wasi_otel::TraceFlags) -> Self { + impl From for opentelemetry::trace::TraceFlags { + fn from(flags: wasi_tracing::TraceFlags) -> Self { Self::new(flags.as_array()[0] as u8) } } - impl From for wasi_otel::TraceFlags { + impl From for wasi_tracing::TraceFlags { fn from(flags: opentelemetry::trace::TraceFlags) -> Self { if flags.is_sampled() { - wasi_otel::TraceFlags::SAMPLED + wasi_tracing::TraceFlags::SAMPLED } else { - wasi_otel::TraceFlags::empty() + wasi_tracing::TraceFlags::empty() } } } - impl From for opentelemetry::trace::SpanKind { - fn from(kind: wasi_otel::SpanKind) -> Self { + impl From for opentelemetry::trace::SpanKind { + fn from(kind: wasi_tracing::SpanKind) -> Self { match kind { - wasi_otel::SpanKind::Client => opentelemetry::trace::SpanKind::Client, - wasi_otel::SpanKind::Server => opentelemetry::trace::SpanKind::Server, - wasi_otel::SpanKind::Producer => opentelemetry::trace::SpanKind::Producer, - wasi_otel::SpanKind::Consumer => opentelemetry::trace::SpanKind::Consumer, - wasi_otel::SpanKind::Internal => opentelemetry::trace::SpanKind::Internal, + wasi_tracing::SpanKind::Client => opentelemetry::trace::SpanKind::Client, + wasi_tracing::SpanKind::Server => opentelemetry::trace::SpanKind::Server, + wasi_tracing::SpanKind::Producer => opentelemetry::trace::SpanKind::Producer, + wasi_tracing::SpanKind::Consumer => opentelemetry::trace::SpanKind::Consumer, + wasi_tracing::SpanKind::Internal => opentelemetry::trace::SpanKind::Internal, } } } - impl From for opentelemetry::KeyValue { - fn from(kv: wasi_otel::KeyValue) -> Self { + impl From for opentelemetry::KeyValue { + fn from(kv: wasi_tracing::KeyValue) -> Self { opentelemetry::KeyValue::new(kv.key, kv.value) } } - impl From for opentelemetry::Value { - fn from(value: wasi_otel::Value) -> Self { + impl From for opentelemetry::Value { + fn from(value: wasi_types::Value) -> Self { match value { - wasi_otel::Value::String(v) => v.into(), - wasi_otel::Value::Bool(v) => v.into(), - wasi_otel::Value::F64(v) => v.into(), - wasi_otel::Value::S64(v) => v.into(), - wasi_otel::Value::StringArray(v) => opentelemetry::Value::Array( + wasi_types::Value::String(v) => v.into(), + wasi_types::Value::Bool(v) => v.into(), + wasi_types::Value::F64(v) => v.into(), + wasi_types::Value::S64(v) => v.into(), + wasi_types::Value::StringArray(v) => opentelemetry::Value::Array( v.into_iter() .map(StringValue::from) .collect::>() .into(), ), - wasi_otel::Value::BoolArray(v) => opentelemetry::Value::Array(v.into()), - wasi_otel::Value::F64Array(v) => opentelemetry::Value::Array(v.into()), - wasi_otel::Value::S64Array(v) => opentelemetry::Value::Array(v.into()), + wasi_types::Value::BoolArray(v) => opentelemetry::Value::Array(v.into()), + wasi_types::Value::F64Array(v) => opentelemetry::Value::Array(v.into()), + wasi_types::Value::S64Array(v) => opentelemetry::Value::Array(v.into()), } } } - impl From for opentelemetry::trace::Event { - fn from(event: wasi_otel::Event) -> Self { + impl From for opentelemetry::trace::Event { + fn from(event: wasi_tracing::Event) -> Self { Self::new( event.name, event.time.into(), @@ -694,8 +1240,8 @@ mod otel { } } - impl From for opentelemetry::trace::Link { - fn from(link: wasi_otel::Link) -> Self { + impl From for opentelemetry::trace::Link { + fn from(link: wasi_tracing::Link) -> Self { Self::new( link.span_context.into(), link.attributes.into_iter().map(Into::into).collect(), @@ -704,20 +1250,20 @@ mod otel { } } - impl From for opentelemetry::trace::Status { - fn from(status: wasi_otel::Status) -> Self { + impl From for opentelemetry::trace::Status { + fn from(status: wasi_tracing::Status) -> Self { match status { - wasi_otel::Status::Unset => Self::Unset, - wasi_otel::Status::Ok => Self::Ok, - wasi_otel::Status::Error(s) => Self::Error { + wasi_tracing::Status::Unset => Self::Unset, + wasi_tracing::Status::Ok => Self::Ok, + wasi_tracing::Status::Error(s) => Self::Error { description: s.into(), }, } } } - impl From for opentelemetry::InstrumentationScope { - fn from(value: wasi_otel::InstrumentationScope) -> Self { + impl From for opentelemetry::InstrumentationScope { + fn from(value: wasi_tracing::InstrumentationScope) -> Self { let builder = Self::builder(value.name) .with_attributes(value.attributes.into_iter().map(Into::into)); match (value.version, value.schema_url) { diff --git a/tests/test-components/components/Cargo.lock b/tests/test-components/components/Cargo.lock index 407be6e74a..87132267dc 100644 --- a/tests/test-components/components/Cargo.lock +++ b/tests/test-components/components/Cargo.lock @@ -279,21 +279,16 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", + "r-efi", "wasi", ] -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - [[package]] name = "hashbrown" version = "0.14.3" @@ -556,6 +551,12 @@ dependencies = [ "spin-sdk 2.2.0", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "leb128" version = "0.2.5" @@ -602,6 +603,15 @@ dependencies = [ "ryu", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -619,23 +629,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opentelemetry" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab70038c28ed37b97d8ed414b6429d343a8bbf44c9f79ec854f3a643029ba6d7" -dependencies = [ - "futures-core", - "futures-sink", - "js-sys", - "pin-project-lite", - "thiserror 1.0.56", - "tracing", -] - -[[package]] -name = "opentelemetry" -version = "0.28.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "236e667b670a5cdf90c258f5a55794ec5ac5027e960c224bff8367a59e1e6426" +checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6" dependencies = [ "futures-core", "futures-sink", @@ -648,50 +644,32 @@ dependencies = [ [[package]] name = "opentelemetry-wasi" version = "0.27.0" -source = "git+https://github.com/calebschoepp/opentelemetry-wasi?rev=bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed#bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed" +source = "git+https://github.com/calebschoepp/opentelemetry-wasi?rev=60df119fbc03ed83d0e2cc1300f6a8eb055d23f7#60df119fbc03ed83d0e2cc1300f6a8eb055d23f7" dependencies = [ "anyhow", - "opentelemetry 0.27.1", - "opentelemetry_sdk 0.27.1", - "wit-bindgen 0.30.0", -] - -[[package]] -name = "opentelemetry_sdk" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" -dependencies = [ - "async-trait", - "futures-channel", - "futures-executor", - "futures-util", - "glob", - "opentelemetry 0.27.1", - "percent-encoding", - "rand", - "serde_json", - "thiserror 1.0.56", + "opentelemetry", + "opentelemetry_sdk", + "spin-sdk 3.1.0", "tracing", + "tracing-opentelemetry", + "tracing-subscriber", + "wit-bindgen 0.30.0", ] [[package]] name = "opentelemetry_sdk" -version = "0.28.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84dfad6042089c7fc1f6118b7040dc2eb4ab520abbf410b79dc481032af39570" +checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b" dependencies = [ - "async-trait", "futures-channel", "futures-executor", "futures-util", - "glob", - "opentelemetry 0.28.0", + "opentelemetry", "percent-encoding", "rand", "serde_json", "thiserror 2.0.12", - "tracing", ] [[package]] @@ -799,22 +777,27 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" -version = "0.8.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" -version = "0.3.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", @@ -822,9 +805,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", ] @@ -910,6 +893,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1134,6 +1126,15 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1156,14 +1157,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "tracing-core" version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] [[package]] name = "typenum" @@ -1215,6 +1275,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "variables" version = "0.1.0" @@ -1240,9 +1306,12 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.14.3+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" +dependencies = [ + "wit-bindgen 0.45.0", +] [[package]] name = "wasi-config" @@ -1291,9 +1360,9 @@ version = "0.1.0" dependencies = [ "anyhow", "http 0.2.11", - "opentelemetry 0.28.0", + "opentelemetry", "opentelemetry-wasi", - "opentelemetry_sdk 0.28.0", + "opentelemetry_sdk", "spin-sdk 3.1.0", "wit-bindgen 0.30.0", ] @@ -1508,6 +1577,16 @@ dependencies = [ "semver", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -1523,6 +1602,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1627,6 +1715,12 @@ dependencies = [ "wit-bindgen-rust-macro 0.34.0", ] +[[package]] +name = "wit-bindgen" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" + [[package]] name = "wit-bindgen-core" version = "0.13.1" diff --git a/tests/test-components/components/wasi-otel-tracing/Cargo.toml b/tests/test-components/components/wasi-otel-tracing/Cargo.toml index 83610c6ea2..4a434653e1 100644 --- a/tests/test-components/components/wasi-otel-tracing/Cargo.toml +++ b/tests/test-components/components/wasi-otel-tracing/Cargo.toml @@ -9,8 +9,8 @@ crate-type = ["cdylib"] [dependencies] anyhow = "1" http = "0.2" -opentelemetry = "0.28.0" -opentelemetry_sdk = "0.28.0" -opentelemetry-wasi = { git = "https://github.com/calebschoepp/opentelemetry-wasi", rev = "bd0fad4dd41c07a64e02fb048b2ec56dc08d19ed" } +opentelemetry = "0.30.0" +opentelemetry_sdk = "0.30.0" +opentelemetry-wasi = { git = "https://github.com/calebschoepp/opentelemetry-wasi", rev = "60df119fbc03ed83d0e2cc1300f6a8eb055d23f7" } spin-sdk = "3.1.0" wit-bindgen = "0.30.0" diff --git a/wit/deps/otel/metrics.wit b/wit/deps/otel/metrics.wit new file mode 100644 index 0000000000..fc32122272 --- /dev/null +++ b/wit/deps/otel/metrics.wit @@ -0,0 +1,272 @@ +interface metrics { + use wasi:clocks/wall-clock@0.2.0.{datetime}; + use wasi:clocks/monotonic-clock@0.2.0.{duration}; + use types.{key-value, instrumentation-scope}; + use tracing.{span-id, trace-id}; + + /// `collect` gathers all metric data related to a Reader from the SDK + collect: func(metrics: resource-metrics) -> result<_, otel-error>; + + /// `resource-metrics` is a collection of `scope-metrics` and the associated `resource` + /// that created them. + /// + /// See https://github.com/open-telemetry/opentelemetry-rust/blob/c811cde1ae21c624870c1b952190e687b16f76b8/opentelemetry-sdk/src/metrics/data/mod.rs#L13 + record resource-metrics { + /// The entity that collected the metrics. + %resource: %resource, + /// The collection of metrics with unique `instrumentation-scope`s. + scope-metrics: list, + } + + /// An immutable representation of the entity producing telemetry as attributes. + record %resource { + inner: resource-inner, + } + + /// Inner structure of `resource` holding the actual data. + record resource-inner { + attributes: list, + schema-url: option, + } + + /// `scope-metrics` is a collection of `metric`s produced by a meter. + record scope-metrics { + /// The `instrumentation-scope` that the meter was created with. + scope: instrumentation-scope, + /// The list of aggregations created by the meter. + metrics: list, + } + + /// `metric` is a collection of one or more aggregated time series from an instrument + record metric { + /// The name of the instrument that created this data. + name: string, + /// The description of the instrument, which can be used in documentation. + description: string, + /// The unit in which the instrument reports. + unit: string, + /// The aggregated data from an instrument. + data: aggregated-metrics, + } + + /// Aggregated metrics data from an instrument. + variant aggregated-metrics { + /// All metric data with `f64` value type. + %f64(metric-data), + /// All metric data with `u64` value type. + %u64(metric-data), + /// All metric data with `s64` value type. + %s64(metric-data), + } + + /// Metric data for all types. + variant metric-data { + /// Metric data for `gauge`. + gauge(gauge), + /// Metric data for `sum`. + sum(sum), + /// Metric data for `histogram`. + histogram(histogram), + /// Metric data for `exponential-histogram`. + exponential-histogram(exponential-histogram), + } + + /// A measurement of the current value of an instrument. + record gauge { + /// Represents individual aggregated measurements with unique attributes. + data-points: list, + /// The time when the time series was started. + start-time: option, + /// The time when the time series was recorded. + time: datetime, + } + + /// `gauge-data-point` is a single data point in a time series. + record gauge-data-point { + /// `attributes` is the set of key value pairs that uniquely identify the + /// time series. + attributes: list, + /// The value of this data point. + value: metric-number, + /// The sampled `exemplar`s collected during the time series. + exemplars: list, + } + + /// Represents the sum of all measurements of values from an instrument. + record sum { + /// Represents individual aggregated measurements with unique attributes. + data-points: list, + /// The time when the time series was started. + start-time: datetime, + /// The time when the time series was recorded. + time: datetime, + /// Describes if the aggregation is reported as the change from the last report + /// time, or the cumulative changes since a fixed start time. + temporality: temporality, + /// Whether this aggregation only increases or decreases. + is-monotonic: bool, + } + + /// `sum-data-point` is a single data point in a time series. + record sum-data-point { + /// `attributes` is the set of key value pairs that uniquely identify the + /// time series. + attributes: list, + /// The value of this data point. + value: metric-number, + /// The sampled `exemplar`s collected during the time series. + exemplars: list, + } + + /// Represents the histogram of all measurements of values from an instrument. + record histogram { + /// Individual aggregated measurements with unique attributes. + data-points: list, + /// The time when the time series was started. + start-time: datetime, + /// The time when the time series was recorded. + time: datetime, + /// Describes if the aggregation is reported as the change from the last report + /// time, or the cumulative changes since a fixed start time. + temporality: temporality, + } + + /// A single histogram data point in a time series. + record histogram-data-point { + /// The set of key value pairs that uniquely identify the time series. + attributes: list, + /// The number of updates this histogram has been calculated with. + count: u64, + /// The upper bounds of the buckets of the histogram. + bounds: list, + /// The count of each of the buckets. + bucket-counts: list, + /// The minimum value recorded. + min: option, + /// The maximum value recorded. + max: option, + /// The sum of the values recorded + sum: metric-number, + /// The sampled `exemplar`s collected during the time series. + exemplars: list, + } + + /// The histogram of all measurements of values from an instrument. + record exponential-histogram { + /// The individual aggregated measurements with unique attributes. + data-points: list, + /// When the time series was started. + start-time: datetime, + /// The time when the time series was recorded. + time: datetime, + /// Describes if the aggregation is reported as the change from the last report + /// time, or the cumulative changes since a fixed start time. + temporality: temporality, + } + + /// A single exponential histogram data point in a time series. + record exponential-histogram-data-point { + /// The set of key value pairs that uniquely identify the time series. + attributes: list, + /// The number of updates this histogram has been calculated with. + count: u64, // TODO: check that u64 is an acceptable replacement for usize + /// The minimum value recorded. + min: option, + /// The maximum value recorded. + max: option, + /// The maximum value recorded. + sum: metric-number, + /// Describes the resolution of the histogram. + /// + /// Boundaries are located at powers of the base, where: + /// + /// base = 2 ^ (2 ^ -scale) + scale: s8, + /// The number of values whose absolute value is less than or equal to + /// `zero_threshold`. + /// + /// When `zero_threshold` is `0`, this is the number of values that cannot be + /// expressed using the standard exponential formula as well as values that have + /// been rounded to zero. + zero-count: u64, + /// The range of positive value bucket counts. + positive-bucket: exponential-bucket, + /// The range of negative value bucket counts. + negative-bucket: exponential-bucket, + /// The width of the zero region. + /// + /// Where the zero region is defined as the closed interval + /// [-zero_threshold, zero_threshold]. + zero-threshold: f64, + /// The sampled exemplars collected during the time series. + exemplars: list, + } + + /// A set of bucket counts, encoded in a contiguous array of counts. + record exponential-bucket { + /// The bucket index of the first entry in the `counts` list. + offset: s32, + /// A list where `counts[i]` carries the count of the bucket at index `offset + i`. + /// + /// `counts[i]` is the count of values greater than base^(offset+i) and less than + /// or equal to base^(offset+i+1). + counts: list, + } + + /// A measurement sampled from a time series providing a typical example. + record exemplar { + /// The attributes recorded with the measurement but filtered out of the + /// time series' aggregated data. + filtered-attributes: list, + /// The time when the measurement was recorded. + time: datetime, + /// The measured value. + value: metric-number, + /// The ID of the span that was active during the measurement. + /// + /// If no span was active or the span was not sampled this will be empty. + span-id: span-id, + /// The ID of the trace the active span belonged to during the measurement. + /// + /// If no span was active or the span was not sampled this will be empty. + trace-id: trace-id, + } + + /// Defines the window that an aggregation was calculated over. + enum temporality { + /// A measurement interval that continues to expand forward in time from a + /// starting point. + /// + /// New measurements are added to all previous measurements since a start time. + /// + /// This is the default temporality + cumulative, + /// A measurement interval that resets each cycle. + /// + /// Measurements from one cycle are recorded independently, measurements from + /// other cycles do not affect them. + delta, + /// Configures Synchronous Counter and Histogram instruments to use + /// Delta aggregation temporality, which allows them to shed memory + /// following a cardinality explosion, thus use less memory. + low-memory, + } + + /// The number types available for use with the OpenTelemetry SDKs. + /// + /// This makes it easier to use generics when converting to and from WASI data types. + variant metric-number { + %f64(f64), + %s64(s64), + %u64(u64), + } + + /// The WASI representation of the `OTelSdkError`. + /// + /// See https://github.com/open-telemetry/opentelemetry-rust/blob/353bbb0d80fc35a26a00b4f4fed0dcaed23e5523/opentelemetry-sdk/src/error.rs#L15 + variant otel-error { + already-shutdown, + timeout(duration), + internal-failure(string), + } +} diff --git a/wit/deps/otel/tracing.wit b/wit/deps/otel/tracing.wit index 8ac7385652..1143e9bcd4 100644 --- a/wit/deps/otel/tracing.wit +++ b/wit/deps/otel/tracing.wit @@ -1,5 +1,6 @@ interface tracing { use wasi:clocks/wall-clock@0.2.0.{datetime}; + use types.{key-value, instrumentation-scope}; /// Called when a span is started. on-start: func(context: span-context); @@ -91,37 +92,6 @@ interface tracing { internal } - /// A key-value pair describing an attribute. - record key-value { - /// The attribute name. - key: key, - /// The attribute value. - value: value, - } - - /// The key part of attribute `key-value` pairs. - type key = string; - - /// The value part of attribute `key-value` pairs. - variant value { - /// A string value. - %string(string), - /// A boolean value. - %bool(bool), - /// A double precision floating point value. - %f64(f64), - /// A signed 64 bit integer value. - %s64(s64), - /// A homogeneous array of string values. - string-array(list), - /// A homogeneous array of boolean values. - bool-array(list), - /// A homogeneous array of double precision floating point values. - f64-array(list), - /// A homogeneous array of 64 bit integer values. - s64-array(list), - } - /// An event describing a specific moment in time on a span and associated attributes. record event { /// Event name. @@ -149,20 +119,4 @@ interface tracing { /// The operation contains an error with a description. error(string), } - - /// Describes the instrumentation scope that produced a span. - record instrumentation-scope { - /// Name of the instrumentation scope. - name: string, - - /// The library version. - version: option, - - /// Schema URL used by this library. - /// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/schemas/overview.md#schema-url - schema-url: option, - - /// Specifies the instrumentation scope attributes to associate with emitted telemetry. - attributes: list, - } } diff --git a/wit/deps/otel/types.wit b/wit/deps/otel/types.wit new file mode 100644 index 0000000000..f9c30c9869 --- /dev/null +++ b/wit/deps/otel/types.wit @@ -0,0 +1,48 @@ +interface types { + /// A key-value pair describing an attribute. + record key-value { + /// The attribute name. + key: key, + /// The attribute value. + value: value, + } + + /// The key part of attribute `key-value` pairs. + type key = string; + + /// The value part of attribute `key-value` pairs. + variant value { + /// A string value. + %string(string), + /// A boolean value. + %bool(bool), + /// A double precision floating point value. + %f64(f64), + /// A signed 64 bit integer value. + %s64(s64), + /// A homogeneous array of string values. + string-array(list), + /// A homogeneous array of boolean values. + bool-array(list), + /// A homogeneous array of double precision floating point values. + f64-array(list), + /// A homogeneous array of 64 bit integer values. + s64-array(list), + } + + /// Describes the instrumentation scope that produced telemetry. + record instrumentation-scope { + /// Name of the instrumentation scope. + name: string, + + /// The library version. + version: option, + + /// Schema URL used by this library. + /// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/schemas/overview.md#schema-url + schema-url: option, + + /// Specifies the instrumentation scope attributes to associate with emitted telemetry. + attributes: list, + } +} diff --git a/wit/deps/otel/world.wit b/wit/deps/otel/world.wit index d1d9701abf..8bfe740215 100644 --- a/wit/deps/otel/world.wit +++ b/wit/deps/otel/world.wit @@ -1,5 +1,9 @@ package wasi:otel@0.2.0-draft; world imports { + import types; import tracing; + import metrics; } + +// TODO: Switch to using wkg From 37f02247e8b9788017bc558c06e99728d5b7d7b6 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:40:55 -0500 Subject: [PATCH 05/10] feat(factor-otel): refactoring otel conversions Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- crates/world/src/conversions.rs | 584 +++++++++----------------------- 1 file changed, 169 insertions(+), 415 deletions(-) diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index 563333d284..e88edfad44 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -628,7 +628,6 @@ mod otel { for Box { fn from(value: wasi_metrics::AggregatedMetrics) -> Self { - use opentelemetry_sdk::metrics::data as O; use wasi_metrics::AggregatedMetrics; fn convert_metric_data( @@ -636,27 +635,14 @@ mod otel { ) -> Box where T: Clone + std::fmt::Debug + Send + Sync + 'static, - O::Gauge: From, - O::Sum: From, - O::Histogram: From, - O::ExponentialHistogram: From, + wasi_metrics::MetricNumber: ExtractWasiMetricNumber, { match md { - wasi_metrics::MetricData::Gauge(gauge) => { - let gauge: O::Gauge = gauge.into(); - Box::new(gauge) - } - wasi_metrics::MetricData::Sum(sum) => { - let sum: O::Sum = sum.into(); - Box::new(sum) - } - wasi_metrics::MetricData::Histogram(hist) => { - let hist: O::Histogram = hist.into(); - Box::new(hist) - } + wasi_metrics::MetricData::Gauge(gauge) => Box::new(convert_gauge(gauge)), + wasi_metrics::MetricData::Sum(sum) => Box::new(convert_sum(sum)), + wasi_metrics::MetricData::Histogram(hist) => Box::new(convert_histogram(hist)), wasi_metrics::MetricData::ExponentialHistogram(hist) => { - let hist: O::ExponentialHistogram = hist.into(); - Box::new(hist) + Box::new(convert_exponential_histogram(hist)) } } } @@ -668,349 +654,207 @@ mod otel { } } - // TODO: we need to make these generic - impl From for opentelemetry_sdk::metrics::data::Gauge { - fn from(value: wasi_metrics::Gauge) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.into_f64(), - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }) - .collect(), - start_time: value.start_time.map(Into::into), - time: value.time.into(), - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Gauge { - fn from(value: wasi_metrics::Gauge) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.into_i64(), - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }) - .collect(), - start_time: value.start_time.map(Into::into), - time: value.time.into(), - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Gauge { - fn from(value: wasi_metrics::Gauge) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.into_u64(), - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }) - .collect(), - start_time: value.start_time.map(Into::into), - time: value.time.into(), - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Sum { - fn from(value: wasi_metrics::Sum) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.into_f64(), - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), - is_monotonic: value.is_monotonic, - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Sum { - fn from(value: wasi_metrics::Sum) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.into_i64(), - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), - is_monotonic: value.is_monotonic, - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Sum { - fn from(value: wasi_metrics::Sum) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.into_u64(), - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), - is_monotonic: value.is_monotonic, - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Histogram { - fn from(value: wasi_metrics::Histogram) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count, - bounds: dp.bounds, - bucket_counts: dp.bucket_counts, - min: match dp.min { - Some(v) => Some(v.into_f64()), - None => None, - }, - max: match dp.max { - Some(v) => Some(v.into_f64()), - None => None, - }, - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - sum: dp.sum.into_f64(), - }) - .collect(), - temporality: value.temporality.into(), - start_time: value.start_time.into(), - time: value.time.into(), - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Histogram { - fn from(value: wasi_metrics::Histogram) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count, - bounds: dp.bounds, - bucket_counts: dp.bucket_counts, - min: match dp.min { - Some(v) => Some(v.into_i64()), - None => None, - }, - max: match dp.max { - Some(v) => Some(v.into_i64()), - None => None, - }, - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - sum: dp.sum.into_i64(), - }) - .collect(), - temporality: value.temporality.into(), - start_time: value.start_time.into(), - time: value.time.into(), - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Histogram { - fn from(value: wasi_metrics::Histogram) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { + fn convert_gauge(value: wasi_metrics::Gauge) -> opentelemetry_sdk::metrics::data::Gauge + where + wasi_metrics::MetricNumber: ExtractWasiMetricNumber, + { + opentelemetry_sdk::metrics::data::Gauge { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.extract_number(), + exemplars: dp + .exemplars + .into_iter() + .map(|e| convert_exemplar(e)) + .collect(), + }) + .collect(), + start_time: value.start_time.map(Into::into), + time: value.time.into(), + } + } + + fn convert_sum(value: wasi_metrics::Sum) -> opentelemetry_sdk::metrics::data::Sum + where + wasi_metrics::MetricNumber: ExtractWasiMetricNumber, + { + opentelemetry_sdk::metrics::data::Sum { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + value: dp.value.extract_number(), + exemplars: dp + .exemplars + .into_iter() + .map(|e| convert_exemplar(e)) + .collect(), + }) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), + is_monotonic: value.is_monotonic, + } + } + + fn convert_histogram( + value: wasi_metrics::Histogram, + ) -> opentelemetry_sdk::metrics::data::Histogram + where + wasi_metrics::MetricNumber: ExtractWasiMetricNumber, + { + opentelemetry_sdk::metrics::data::Histogram { + data_points: value + .data_points + .into_iter() + .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { + attributes: dp.attributes.into_iter().map(Into::into).collect(), + count: dp.count, + bounds: dp.bounds, + bucket_counts: dp.bucket_counts, + min: match dp.min { + Some(v) => Some(v.extract_number()), + None => None, + }, + max: match dp.max { + Some(v) => Some(v.extract_number()), + None => None, + }, + exemplars: dp + .exemplars + .into_iter() + .map(|e| convert_exemplar(e)) + .collect(), + sum: dp.sum.extract_number(), + }) + .collect(), + temporality: value.temporality.into(), + start_time: value.start_time.into(), + time: value.time.into(), + } + } + + fn convert_exponential_histogram( + value: wasi_metrics::ExponentialHistogram, + ) -> opentelemetry_sdk::metrics::data::ExponentialHistogram + where + wasi_metrics::MetricNumber: ExtractWasiMetricNumber, + { + opentelemetry_sdk::metrics::data::ExponentialHistogram { + data_points: value + .data_points + .into_iter() + .map( + |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count, - bounds: dp.bounds, - bucket_counts: dp.bucket_counts, + count: dp.count as usize, min: match dp.min { - Some(v) => Some(v.into_u64()), + Some(v) => Some(v.extract_number()), None => None, }, max: match dp.max { - Some(v) => Some(v.into_u64()), + Some(v) => Some(v.extract_number()), None => None, }, - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - sum: dp.sum.into_u64(), - }) - .collect(), - temporality: value.temporality.into(), - start_time: value.start_time.into(), - time: value.time.into(), - } + sum: dp.sum.extract_number(), + scale: dp.scale, + zero_count: dp.zero_count, + positive_bucket: dp.positive_bucket.into(), + negative_bucket: dp.negative_bucket.into(), + zero_threshold: dp.zero_threshold, + exemplars: dp + .exemplars + .into_iter() + .map(|e| convert_exemplar(e)) + .collect(), + }, + ) + .collect(), + start_time: value.start_time.into(), + time: value.time.into(), + temporality: value.temporality.into(), } } - impl From - for opentelemetry_sdk::metrics::data::ExponentialHistogram - { - fn from(value: wasi_metrics::ExponentialHistogram) -> Self { + impl From for opentelemetry_sdk::metrics::data::ExponentialBucket { + fn from(value: wasi_metrics::ExponentialBucket) -> Self { Self { - data_points: value - .data_points - .into_iter() - .map( - |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count as usize, - min: match dp.min { - Some(v) => Some(v.into_f64()), - None => None, - }, - max: match dp.max { - Some(v) => Some(v.into_f64()), - None => None, - }, - sum: dp.sum.into_f64(), - scale: dp.scale, - zero_count: dp.zero_count, - positive_bucket: dp.positive_bucket.into(), - negative_bucket: dp.negative_bucket.into(), - zero_threshold: dp.zero_threshold, - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }, - ) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), + offset: value.offset, + counts: value.counts, } } } - impl From - for opentelemetry_sdk::metrics::data::ExponentialHistogram + fn convert_exemplar( + value: wasi_metrics::Exemplar, + ) -> opentelemetry_sdk::metrics::data::Exemplar + where + wasi_metrics::MetricNumber: ExtractWasiMetricNumber, { - fn from(value: wasi_metrics::ExponentialHistogram) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map( - |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count as usize, - min: match dp.min { - Some(v) => Some(v.into_i64()), - None => None, - }, - max: match dp.max { - Some(v) => Some(v.into_i64()), - None => None, - }, - sum: dp.sum.into_i64(), - scale: dp.scale, - zero_count: dp.zero_count, - positive_bucket: dp.positive_bucket.into(), - negative_bucket: dp.negative_bucket.into(), - zero_threshold: dp.zero_threshold, - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }, - ) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), - } + let span_id: [u8; 8] = value + .span_id + .as_bytes() + .try_into() + .expect("Span ID is longer than 8 bytes"); + let trace_id: [u8; 16] = value + .trace_id + .as_bytes() + .try_into() + .expect("Trace ID is longer than 16 bytes"); + opentelemetry_sdk::metrics::data::Exemplar { + filtered_attributes: value + .filtered_attributes + .into_iter() + .map(Into::into) + .collect(), + time: value.time.into(), + value: value.value.extract_number(), + span_id, + trace_id, } } - impl From - for opentelemetry_sdk::metrics::data::ExponentialHistogram - { - fn from(value: wasi_metrics::ExponentialHistogram) -> Self { - Self { - data_points: value - .data_points - .into_iter() - .map( - |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count as usize, - min: match dp.min { - Some(v) => Some(v.into_u64()), - None => None, - }, - max: match dp.max { - Some(v) => Some(v.into_u64()), - None => None, - }, - sum: dp.sum.into_u64(), - scale: dp.scale, - zero_count: dp.zero_count, - positive_bucket: dp.positive_bucket.into(), - negative_bucket: dp.negative_bucket.into(), - zero_threshold: dp.zero_threshold, - exemplars: dp.exemplars.into_iter().map(Into::into).collect(), - }, - ) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), + impl From for opentelemetry_sdk::metrics::Temporality { + fn from(value: wasi_metrics::Temporality) -> Self { + use opentelemetry_sdk::metrics::Temporality as OT; + use wasi_metrics::Temporality as T; + match value { + T::Delta => OT::Delta, + T::LowMemory => OT::LowMemory, + _ => OT::Cumulative, } } } - impl From for opentelemetry_sdk::metrics::data::ExponentialBucket { - fn from(value: wasi_metrics::ExponentialBucket) -> Self { - Self { - offset: value.offset, - counts: value.counts, - } - } + trait ExtractWasiMetricNumber { + fn extract_number(self) -> T; } - impl wasi_metrics::MetricNumber { - pub fn into_f64(self) -> f64 { + impl ExtractWasiMetricNumber for wasi_metrics::MetricNumber { + fn extract_number(self) -> f64 { match self { wasi_metrics::MetricNumber::F64(v) => v, - // TODO: validate that this is desirable over just converting i64 and u64 types to f64. - // In my mind, the panic will help reduce bugs (i.e. a float being converted to int) _ => panic!("value is not f64"), } } + } - pub fn into_i64(self) -> i64 { + impl ExtractWasiMetricNumber for wasi_metrics::MetricNumber { + fn extract_number(self) -> i64 { match self { wasi_metrics::MetricNumber::S64(v) => v, _ => panic!("value is not i64"), } } + } - pub fn into_u64(self) -> u64 { + impl ExtractWasiMetricNumber for wasi_metrics::MetricNumber { + fn extract_number(self) -> u64 { match self { wasi_metrics::MetricNumber::U64(v) => v, _ => panic!("value is not u64"), @@ -1018,96 +862,6 @@ mod otel { } } - impl From for opentelemetry_sdk::metrics::data::Exemplar { - fn from(value: wasi_metrics::Exemplar) -> Self { - let span_id: [u8; 8] = value - .span_id - .as_bytes() - .try_into() - .expect("Span ID is longer than 8 bytes"); - let trace_id: [u8; 16] = value - .trace_id - .as_bytes() - .try_into() - .expect("Trace ID is longer than 16 bytes"); - Self { - filtered_attributes: value - .filtered_attributes - .into_iter() - .map(Into::into) - .collect(), - time: value.time.into(), - value: value.value.into_f64(), - span_id, - trace_id, - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Exemplar { - fn from(value: wasi_metrics::Exemplar) -> Self { - let span_id: [u8; 8] = value - .span_id - .as_bytes() - .try_into() - .expect("Span ID is longer than 8 bytes"); - let trace_id: [u8; 16] = value - .trace_id - .as_bytes() - .try_into() - .expect("Trace ID is longer than 16 bytes"); - Self { - filtered_attributes: value - .filtered_attributes - .into_iter() - .map(Into::into) - .collect(), - time: value.time.into(), - value: value.value.into_i64(), - span_id, - trace_id, - } - } - } - - impl From for opentelemetry_sdk::metrics::data::Exemplar { - fn from(value: wasi_metrics::Exemplar) -> Self { - let span_id: [u8; 8] = value - .span_id - .as_bytes() - .try_into() - .expect("Span ID is longer than 8 bytes"); - let trace_id: [u8; 16] = value - .trace_id - .as_bytes() - .try_into() - .expect("Trace ID is longer than 16 bytes"); - Self { - filtered_attributes: value - .filtered_attributes - .into_iter() - .map(Into::into) - .collect(), - time: value.time.into(), - value: value.value.into_u64(), - span_id, - trace_id, - } - } - } - - impl From for opentelemetry_sdk::metrics::Temporality { - fn from(value: wasi_metrics::Temporality) -> Self { - use opentelemetry_sdk::metrics::Temporality as OT; - use wasi_metrics::Temporality as T; - match value { - T::Delta => OT::Delta, - T::LowMemory => OT::LowMemory, - _ => OT::Cumulative, - } - } - } - impl From for opentelemetry_sdk::trace::SpanData { fn from(value: wasi_tracing::SpanData) -> Self { let mut span_events = SpanEvents::default(); From 85f93aada17c970224a65ada1b39e9cd4d68eba7 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Fri, 3 Oct 2025 00:45:39 +0000 Subject: [PATCH 06/10] fix(telemetry): update BatchLogProcessor to be async Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- Cargo.toml | 2 +- crates/telemetry/src/logs.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c2f3742839..29fe3177e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,7 +146,7 @@ lazy_static = "1.5" opentelemetry = "0.28" # The default `reqwest-blocking-client` causes a runtime panic opentelemetry-otlp = { version = "0.28", default-features = false, features = ["http-proto", "reqwest-client", "logs"]} -opentelemetry_sdk = {version = "0.28", features = ["experimental_metrics_periodicreader_with_async_runtime", "experimental_trace_batch_span_processor_with_async_runtime"]} +opentelemetry_sdk = {version = "0.28", features = ["experimental_metrics_periodicreader_with_async_runtime", "experimental_trace_batch_span_processor_with_async_runtime", "experimental_logs_batch_log_processor_with_async_runtime"]} path-absolutize = "3" quote = "1" rand = "0.9" diff --git a/crates/telemetry/src/logs.rs b/crates/telemetry/src/logs.rs index f87857bb70..deb0166389 100644 --- a/crates/telemetry/src/logs.rs +++ b/crates/telemetry/src/logs.rs @@ -3,8 +3,9 @@ use std::{ascii::escape_default, sync::OnceLock}; use anyhow::bail; use opentelemetry::logs::{LogRecord, Logger, LoggerProvider}; use opentelemetry_sdk::{ - logs::{BatchConfigBuilder, BatchLogProcessor, SdkLogger}, + logs::{log_processor_with_async_runtime::BatchLogProcessor, BatchConfigBuilder, SdkLogger}, resource::{EnvResourceDetector, ResourceDetector, TelemetryResourceDetector}, + runtime::Tokio, Resource, }; @@ -97,7 +98,7 @@ pub(crate) fn init_otel_logging_backend(spin_version: String) -> anyhow::Result< let provider = opentelemetry_sdk::logs::SdkLoggerProvider::builder() .with_resource(resource) .with_log_processor( - BatchLogProcessor::builder(exporter) + BatchLogProcessor::builder(exporter, Tokio) .with_batch_config(BatchConfigBuilder::default().build()) .build(), ) From 146c7e3f7e37afe4070fd3893c21569d266593c1 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Wed, 15 Oct 2025 21:13:47 -0500 Subject: [PATCH 07/10] feat(factor-otel): refactoring WIT and updating conversions Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- crates/world/src/conversions.rs | 4 ++-- wit/deps/otel/metrics.wit | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index e88edfad44..dfd3d8fe5c 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -590,8 +590,8 @@ mod otel { impl From for opentelemetry_sdk::Resource { fn from(value: wasi_metrics::Resource) -> Self { let attributes: Vec = - value.inner.attributes.into_iter().map(Into::into).collect(); - let schema_url: Option = value.inner.schema_url.into(); + value.attributes.into_iter().map(Into::into).collect(); + let schema_url: Option = value.schema_url.into(); match schema_url { Some(url) => opentelemetry_sdk::resource::Resource::builder() diff --git a/wit/deps/otel/metrics.wit b/wit/deps/otel/metrics.wit index fc32122272..6a6843f64c 100644 --- a/wit/deps/otel/metrics.wit +++ b/wit/deps/otel/metrics.wit @@ -20,11 +20,6 @@ interface metrics { /// An immutable representation of the entity producing telemetry as attributes. record %resource { - inner: resource-inner, - } - - /// Inner structure of `resource` holding the actual data. - record resource-inner { attributes: list, schema-url: option, } @@ -215,7 +210,7 @@ interface metrics { /// A measurement sampled from a time series providing a typical example. record exemplar { - /// The attributes recorded with the measurement but filtered out of the + /// The attributes recorded with the measurement but filtered out of the /// time series' aggregated data. filtered-attributes: list, /// The time when the measurement was recorded. From d437a36dc24ae444e64a7a9bf6339ec713a1ee9c Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Sat, 18 Oct 2025 17:17:28 -0500 Subject: [PATCH 08/10] fix(factor-otel): updating WIT Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- crates/factor-otel/src/host.rs | 18 +++++++++++++++--- crates/world/src/conversions.rs | 13 ------------- wit/deps/otel/metrics.wit | 19 +++++-------------- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/crates/factor-otel/src/host.rs b/crates/factor-otel/src/host.rs index 36f322375a..6b40daab56 100644 --- a/crates/factor-otel/src/host.rs +++ b/crates/factor-otel/src/host.rs @@ -1,6 +1,9 @@ +use std::fmt::format; + use anyhow::anyhow; use anyhow::Result; use opentelemetry::trace::TraceContextExt; +use opentelemetry_sdk::error::OTelSdkError; use opentelemetry_sdk::metrics::exporter::PushMetricExporter; use opentelemetry_sdk::trace::SpanProcessor; use spin_world::wasi; @@ -58,14 +61,23 @@ impl wasi::otel::tracing::Host for InstanceState { } impl wasi::otel::metrics::Host for InstanceState { - async fn collect( + async fn export( &mut self, metrics: wasi::otel::metrics::ResourceMetrics, - ) -> spin_core::wasmtime::Result> { + ) -> spin_core::wasmtime::Result> { let mut rm: opentelemetry_sdk::metrics::data::ResourceMetrics = metrics.into(); match self.metric_exporter.export(&mut rm).await { Ok(_) => Ok(Ok(())), - Err(e) => Ok(Err(e.into())), + Err(e) => match e { + OTelSdkError::AlreadyShutdown => { + Ok(Err("Shutdown has already been invoked".to_string())) + } + OTelSdkError::InternalFailure(e) => Ok(Err("Internal failure: ".to_string() + &e)), + OTelSdkError::Timeout(d) => Ok(Err(format!( + "Operation timed out after {} seconds", + d.as_secs() + ))), + }, } } } diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index dfd3d8fe5c..33ebecb8bc 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -557,7 +557,6 @@ mod llm { mod otel { use super::*; use opentelemetry::StringValue; - use opentelemetry_sdk::error::OTelSdkError; use opentelemetry_sdk::trace::{SpanEvents, SpanLinks}; use std::borrow::Cow; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -566,18 +565,6 @@ mod otel { use wasi::otel::tracing as wasi_tracing; use wasi::otel::types as wasi_types; - impl From for wasi::otel::metrics::OtelError { - fn from(value: OTelSdkError) -> Self { - match value { - OTelSdkError::AlreadyShutdown => wasi::otel::metrics::OtelError::AlreadyShutdown, - OTelSdkError::InternalFailure(v) => { - wasi::otel::metrics::OtelError::InternalFailure(v) - } - OTelSdkError::Timeout(d) => wasi::otel::metrics::OtelError::Timeout(d.as_secs()), - } - } - } - impl From for opentelemetry_sdk::metrics::data::ResourceMetrics { fn from(value: wasi_metrics::ResourceMetrics) -> Self { Self { diff --git a/wit/deps/otel/metrics.wit b/wit/deps/otel/metrics.wit index 6a6843f64c..2d1da96f08 100644 --- a/wit/deps/otel/metrics.wit +++ b/wit/deps/otel/metrics.wit @@ -4,13 +4,13 @@ interface metrics { use types.{key-value, instrumentation-scope}; use tracing.{span-id, trace-id}; - /// `collect` gathers all metric data related to a Reader from the SDK - collect: func(metrics: resource-metrics) -> result<_, otel-error>; + /// `export` sends all metric data related to a Reader from the SDK + %export: func(metrics: resource-metrics) -> result<_, error>; + + type error = string; /// `resource-metrics` is a collection of `scope-metrics` and the associated `resource` /// that created them. - /// - /// See https://github.com/open-telemetry/opentelemetry-rust/blob/c811cde1ae21c624870c1b952190e687b16f76b8/opentelemetry-sdk/src/metrics/data/mod.rs#L13 record resource-metrics { /// The entity that collected the metrics. %resource: %resource, @@ -255,13 +255,4 @@ interface metrics { %s64(s64), %u64(u64), } - - /// The WASI representation of the `OTelSdkError`. - /// - /// See https://github.com/open-telemetry/opentelemetry-rust/blob/353bbb0d80fc35a26a00b4f4fed0dcaed23e5523/opentelemetry-sdk/src/error.rs#L15 - variant otel-error { - already-shutdown, - timeout(duration), - internal-failure(string), - } -} +} \ No newline at end of file From 1ce7e140fa7f7c5814e6d859f2cd46ffb808435f Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Wed, 29 Oct 2025 04:08:39 +0000 Subject: [PATCH 09/10] feat(factor-otel): updating WIT and conversions Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- crates/factor-otel/src/host.rs | 5 +- crates/world/src/conversions.rs | 390 ++++++++++++++++---------------- wit/deps/otel/metrics.wit | 84 +++---- wit/deps/otel/world.wit | 2 - 4 files changed, 235 insertions(+), 246 deletions(-) diff --git a/crates/factor-otel/src/host.rs b/crates/factor-otel/src/host.rs index 6b40daab56..e63f032118 100644 --- a/crates/factor-otel/src/host.rs +++ b/crates/factor-otel/src/host.rs @@ -1,5 +1,4 @@ -use std::fmt::format; - +use crate::InstanceState; use anyhow::anyhow; use anyhow::Result; use opentelemetry::trace::TraceContextExt; @@ -9,8 +8,6 @@ use opentelemetry_sdk::trace::SpanProcessor; use spin_world::wasi; use tracing_opentelemetry::OpenTelemetrySpanExt; -use crate::InstanceState; - impl wasi::otel::tracing::Host for InstanceState { async fn on_start(&mut self, context: wasi::otel::tracing::SpanContext) -> Result<()> { let mut state = self.state.write().unwrap(); diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index 33ebecb8bc..abc8d8a461 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -582,7 +582,9 @@ mod otel { match schema_url { Some(url) => opentelemetry_sdk::resource::Resource::builder() - .with_schema_url(attributes, url) // TODO: Does this also need `with_attributes`? + // TODO: I'm unclear about what to do with the `with_schema_url()` method and the + // `with_attribute()` or `with_attributes()` methods. Is this good enough? + .with_schema_url(attributes, url) .build(), None => opentelemetry_sdk::resource::Resource::builder() .with_attributes(attributes) @@ -611,240 +613,220 @@ mod otel { } } - impl From - for Box - { - fn from(value: wasi_metrics::AggregatedMetrics) -> Self { - use wasi_metrics::AggregatedMetrics; - - fn convert_metric_data( - md: wasi_metrics::MetricData, - ) -> Box - where - T: Clone + std::fmt::Debug + Send + Sync + 'static, - wasi_metrics::MetricNumber: ExtractWasiMetricNumber, - { - match md { - wasi_metrics::MetricData::Gauge(gauge) => Box::new(convert_gauge(gauge)), - wasi_metrics::MetricData::Sum(sum) => Box::new(convert_sum(sum)), - wasi_metrics::MetricData::Histogram(hist) => Box::new(convert_histogram(hist)), - wasi_metrics::MetricData::ExponentialHistogram(hist) => { - Box::new(convert_exponential_histogram(hist)) + /// Converts a Wasi exemplar to an OTel exemplar + macro_rules! exemplars_to_otel { + ( + $wasi_exemplar_list:expr, + $exemplar_type:ty + ) => { + $wasi_exemplar_list + .iter() + .map(|e| { + let span_id: [u8; 8] = e + .span_id + .as_bytes() + .try_into() + .expect("Span ID is longer than 8 bytes"); + let trace_id: [u8; 16] = e + .trace_id + .as_bytes() + .try_into() + .expect("Trace ID is longer than 16 bytes"); + opentelemetry_sdk::metrics::data::Exemplar::<$exemplar_type> { + filtered_attributes: e + .filtered_attributes + .to_owned() + .into_iter() + .map(Into::into) + .collect(), + time: e.time.into(), + value: e.value.into(), + span_id, + trace_id, } - } - } - match value { - AggregatedMetrics::S64(md) => convert_metric_data::(md), - AggregatedMetrics::U64(md) => convert_metric_data::(md), - AggregatedMetrics::F64(md) => convert_metric_data::(md), - } - } - } - - fn convert_gauge(value: wasi_metrics::Gauge) -> opentelemetry_sdk::metrics::data::Gauge - where - wasi_metrics::MetricNumber: ExtractWasiMetricNumber, - { - opentelemetry_sdk::metrics::data::Gauge { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.extract_number(), - exemplars: dp - .exemplars - .into_iter() - .map(|e| convert_exemplar(e)) - .collect(), }) - .collect(), - start_time: value.start_time.map(Into::into), - time: value.time.into(), - } + .collect() + }; } - fn convert_sum(value: wasi_metrics::Sum) -> opentelemetry_sdk::metrics::data::Sum - where - wasi_metrics::MetricNumber: ExtractWasiMetricNumber, - { - opentelemetry_sdk::metrics::data::Sum { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - value: dp.value.extract_number(), - exemplars: dp - .exemplars - .into_iter() - .map(|e| convert_exemplar(e)) - .collect(), - }) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), - is_monotonic: value.is_monotonic, - } + /// Converts a WASI Gauge to an OTel Gauge + macro_rules! wasi_gauge_to_otel { + ($gauge:expr, $number_type:ty) => { + Box::new(opentelemetry_sdk::metrics::data::Gauge { + data_points: $gauge + .data_points + .iter() + .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint { + attributes: dp.attributes.iter().map(Into::into).collect(), + value: dp.value.into(), + exemplars: exemplars_to_otel!(dp.exemplars, $number_type), + }) + .collect(), + start_time: match $gauge.start_time { + Some(t) => Some(t.into()), + None => None, + }, + time: $gauge.time.into(), + }) + }; } - fn convert_histogram( - value: wasi_metrics::Histogram, - ) -> opentelemetry_sdk::metrics::data::Histogram - where - wasi_metrics::MetricNumber: ExtractWasiMetricNumber, - { - opentelemetry_sdk::metrics::data::Histogram { - data_points: value - .data_points - .into_iter() - .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count, - bounds: dp.bounds, - bucket_counts: dp.bucket_counts, - min: match dp.min { - Some(v) => Some(v.extract_number()), - None => None, - }, - max: match dp.max { - Some(v) => Some(v.extract_number()), - None => None, - }, - exemplars: dp - .exemplars - .into_iter() - .map(|e| convert_exemplar(e)) - .collect(), - sum: dp.sum.extract_number(), - }) - .collect(), - temporality: value.temporality.into(), - start_time: value.start_time.into(), - time: value.time.into(), - } + /// Converts a WASI Sum to an OTel Sum + macro_rules! wasi_sum_to_otel { + ($sum:expr, $number_type:ty) => { + Box::new(opentelemetry_sdk::metrics::data::Sum { + data_points: $sum + .data_points + .iter() + .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint { + attributes: dp.attributes.iter().map(Into::into).collect(), + exemplars: exemplars_to_otel!(dp.exemplars, $number_type), + value: dp.value.into(), + }) + .collect(), + start_time: $sum.start_time.into(), + time: $sum.time.into(), + temporality: $sum.temporality.into(), + is_monotonic: $sum.is_monotonic, + }) + }; } - fn convert_exponential_histogram( - value: wasi_metrics::ExponentialHistogram, - ) -> opentelemetry_sdk::metrics::data::ExponentialHistogram - where - wasi_metrics::MetricNumber: ExtractWasiMetricNumber, - { - opentelemetry_sdk::metrics::data::ExponentialHistogram { - data_points: value - .data_points - .into_iter() - .map( - |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { - attributes: dp.attributes.into_iter().map(Into::into).collect(), - count: dp.count as usize, - min: match dp.min { - Some(v) => Some(v.extract_number()), + /// Converts a WASI Histogram to an OTel Histogram + macro_rules! wasi_histogram_to_otel { + ($histogram:expr, $number_type:ty) => { + Box::new(opentelemetry_sdk::metrics::data::Histogram { + data_points: $histogram + .data_points + .iter() + .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint { + attributes: dp.attributes.iter().map(Into::into).collect(), + bounds: dp.bounds.to_owned(), + bucket_counts: dp.bucket_counts.to_owned(), + exemplars: exemplars_to_otel!(dp.exemplars, $number_type), + count: dp.count, + max: match dp.max { + Some(m) => Some(m.into()), None => None, }, - max: match dp.max { - Some(v) => Some(v.extract_number()), + min: match dp.min { + Some(m) => Some(m.into()), None => None, }, - sum: dp.sum.extract_number(), - scale: dp.scale, - zero_count: dp.zero_count, - positive_bucket: dp.positive_bucket.into(), - negative_bucket: dp.negative_bucket.into(), - zero_threshold: dp.zero_threshold, - exemplars: dp - .exemplars - .into_iter() - .map(|e| convert_exemplar(e)) - .collect(), - }, - ) - .collect(), - start_time: value.start_time.into(), - time: value.time.into(), - temporality: value.temporality.into(), - } + sum: dp.sum.into(), + }) + .collect(), + start_time: $histogram.start_time.into(), + time: $histogram.time.into(), + temporality: $histogram.temporality.into(), + }) + }; } - impl From for opentelemetry_sdk::metrics::data::ExponentialBucket { - fn from(value: wasi_metrics::ExponentialBucket) -> Self { - Self { - offset: value.offset, - counts: value.counts, - } - } + /// Converts a WASI ExponentialHistogram to an OTel ExponentialHistogram + macro_rules! wasi_exponential_histogram_to_otel { + ($histogram:expr, $number_type:ty) => { + Box::new(opentelemetry_sdk::metrics::data::ExponentialHistogram { + data_points: $histogram + .data_points + .iter() + .map( + |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint { + attributes: dp.attributes.iter().map(Into::into).collect(), + exemplars: exemplars_to_otel!(dp.exemplars, $number_type), + count: dp.count as usize, + max: match dp.max { + Some(m) => Some(m.into()), + None => None, + }, + min: match dp.min { + Some(m) => Some(m.into()), + None => None, + }, + sum: dp.sum.into(), + scale: dp.scale, + zero_count: dp.zero_count, + positive_bucket: dp.positive_bucket.to_owned().into(), + negative_bucket: dp.negative_bucket.to_owned().into(), + zero_threshold: dp.zero_threshold, + }, + ) + .collect(), + start_time: $histogram.start_time.into(), + time: $histogram.time.into(), + temporality: $histogram.temporality.into(), + }) + }; } - fn convert_exemplar( - value: wasi_metrics::Exemplar, - ) -> opentelemetry_sdk::metrics::data::Exemplar - where - wasi_metrics::MetricNumber: ExtractWasiMetricNumber, - { - let span_id: [u8; 8] = value - .span_id - .as_bytes() - .try_into() - .expect("Span ID is longer than 8 bytes"); - let trace_id: [u8; 16] = value - .trace_id - .as_bytes() - .try_into() - .expect("Trace ID is longer than 16 bytes"); - opentelemetry_sdk::metrics::data::Exemplar { - filtered_attributes: value - .filtered_attributes - .into_iter() - .map(Into::into) - .collect(), - time: value.time.into(), - value: value.value.extract_number(), - span_id, - trace_id, + impl From for Box { + fn from(value: wasi_metrics::MetricData) -> Self { + match value { + wasi_metrics::MetricData::F64Sum(s) => wasi_sum_to_otel!(s, f64), + wasi_metrics::MetricData::S64Sum(s) => wasi_sum_to_otel!(s, i64), + wasi_metrics::MetricData::U64Sum(s) => wasi_sum_to_otel!(s, u64), + wasi_metrics::MetricData::F64Gauge(g) => wasi_gauge_to_otel!(g, f64), + wasi_metrics::MetricData::S64Gauge(g) => wasi_gauge_to_otel!(g, i64), + wasi_metrics::MetricData::U64Gauge(g) => wasi_gauge_to_otel!(g, u64), + wasi_metrics::MetricData::F64Histogram(h) => wasi_histogram_to_otel!(h, f64), + wasi_metrics::MetricData::S64Histogram(h) => wasi_histogram_to_otel!(h, i64), + wasi_metrics::MetricData::U64Histogram(h) => wasi_histogram_to_otel!(h, u64), + wasi_metrics::MetricData::F64ExponentialHistogram(h) => { + wasi_exponential_histogram_to_otel!(h, f64) + } + wasi_metrics::MetricData::S64ExponentialHistogram(h) => { + wasi_exponential_histogram_to_otel!(h, i64) + } + wasi_metrics::MetricData::U64ExponentialHistogram(h) => { + wasi_exponential_histogram_to_otel!(h, u64) + } + } } } - impl From for opentelemetry_sdk::metrics::Temporality { - fn from(value: wasi_metrics::Temporality) -> Self { - use opentelemetry_sdk::metrics::Temporality as OT; - use wasi_metrics::Temporality as T; + impl From for f64 { + fn from(value: wasi_metrics::MetricNumber) -> Self { match value { - T::Delta => OT::Delta, - T::LowMemory => OT::LowMemory, - _ => OT::Cumulative, + wasi_metrics::MetricNumber::F64(n) => n, + _ => panic!("error converting WASI MetricNumber to f64"), } } } - trait ExtractWasiMetricNumber { - fn extract_number(self) -> T; + impl From for u64 { + fn from(value: wasi_metrics::MetricNumber) -> Self { + match value { + wasi_metrics::MetricNumber::U64(n) => n, + _ => panic!("error converting WASI MetricNumber to u64"), + } + } } - impl ExtractWasiMetricNumber for wasi_metrics::MetricNumber { - fn extract_number(self) -> f64 { - match self { - wasi_metrics::MetricNumber::F64(v) => v, - _ => panic!("value is not f64"), + impl From for i64 { + fn from(value: wasi_metrics::MetricNumber) -> Self { + match value { + wasi_metrics::MetricNumber::S64(n) => n, + _ => panic!("error converting WASI MetricNumber to i64"), } } } - impl ExtractWasiMetricNumber for wasi_metrics::MetricNumber { - fn extract_number(self) -> i64 { - match self { - wasi_metrics::MetricNumber::S64(v) => v, - _ => panic!("value is not i64"), + impl From for opentelemetry_sdk::metrics::data::ExponentialBucket { + fn from(value: wasi_metrics::ExponentialBucket) -> Self { + Self { + offset: value.offset, + counts: value.counts, } } } - impl ExtractWasiMetricNumber for wasi_metrics::MetricNumber { - fn extract_number(self) -> u64 { - match self { - wasi_metrics::MetricNumber::U64(v) => v, - _ => panic!("value is not u64"), + impl From for opentelemetry_sdk::metrics::Temporality { + fn from(value: wasi_metrics::Temporality) -> Self { + use opentelemetry_sdk::metrics::Temporality; + match value { + wasi_metrics::Temporality::Cumulative => Temporality::Cumulative, + wasi_metrics::Temporality::Delta => Temporality::Delta, + wasi_metrics::Temporality::LowMemory => Temporality::LowMemory, } } } @@ -950,6 +932,12 @@ mod otel { } } + impl From<&wasi_tracing::KeyValue> for opentelemetry::KeyValue { + fn from(kv: &wasi_tracing::KeyValue) -> Self { + opentelemetry::KeyValue::new(kv.key.to_owned(), kv.value.to_owned()) + } + } + impl From for opentelemetry::Value { fn from(value: wasi_types::Value) -> Self { match value { diff --git a/wit/deps/otel/metrics.wit b/wit/deps/otel/metrics.wit index 2d1da96f08..8255684a4e 100644 --- a/wit/deps/otel/metrics.wit +++ b/wit/deps/otel/metrics.wit @@ -4,13 +4,13 @@ interface metrics { use types.{key-value, instrumentation-scope}; use tracing.{span-id, trace-id}; - /// `export` sends all metric data related to a Reader from the SDK + /// Exports a resource's metric data. %export: func(metrics: resource-metrics) -> result<_, error>; + /// An error resulting from `export` being called. type error = string; - /// `resource-metrics` is a collection of `scope-metrics` and the associated `resource` - /// that created them. + /// A collection of `scope-metrics` and the associated `resource` that created them. record resource-metrics { /// The entity that collected the metrics. %resource: %resource, @@ -20,50 +20,58 @@ interface metrics { /// An immutable representation of the entity producing telemetry as attributes. record %resource { + /// Attributes that identify the resource. attributes: list, + /// The schema URL to be recorded in the emitted resource. schema-url: option, } - /// `scope-metrics` is a collection of `metric`s produced by a meter. + /// A collection of `metric`s produced by a meter. record scope-metrics { - /// The `instrumentation-scope` that the meter was created with. + /// The instrumentation scope that the meter was created with. scope: instrumentation-scope, /// The list of aggregations created by the meter. metrics: list, } - /// `metric` is a collection of one or more aggregated time series from an instrument + /// A collection of one or more aggregated time series from a metric. record metric { - /// The name of the instrument that created this data. + /// The name of the metric that created this data. name: string, - /// The description of the instrument, which can be used in documentation. + /// The description of the metric, which can be used in documentation. description: string, - /// The unit in which the instrument reports. + /// The unit in which the metric reports. unit: string, - /// The aggregated data from an instrument. - data: aggregated-metrics, - } - - /// Aggregated metrics data from an instrument. - variant aggregated-metrics { - /// All metric data with `f64` value type. - %f64(metric-data), - /// All metric data with `u64` value type. - %u64(metric-data), - /// All metric data with `s64` value type. - %s64(metric-data), + /// The aggregated data from a metric. + data: metric-data } /// Metric data for all types. variant metric-data { - /// Metric data for `gauge`. - gauge(gauge), - /// Metric data for `sum`. - sum(sum), - /// Metric data for `histogram`. - histogram(histogram), - /// Metric data for `exponential-histogram`. - exponential-histogram(exponential-histogram), + /// Metric data for an f64 gauge. + f64-gauge(gauge), + /// Metric data for an f64 sum. + f64-sum(sum), + /// Metric data for an f64 histogram. + f64-histogram(histogram), + /// Metric data for an f64 exponential-histogram. + f64-exponential-histogram(exponential-histogram), + /// Metric data for an u64 gauge. + u64-gauge(gauge), + /// Metric data for an u64 sum. + u64-sum(sum), + /// Metric data for an u64 histogram. + u64-histogram(histogram), + /// Metric data for an u64 exponential-histogram. + u64-exponential-histogram(exponential-histogram), + /// Metric data for an s64 gauge. + s64-gauge(gauge), + /// Metric data for an s64 sum. + s64-sum(sum), + /// Metric data for an s64 histogram. + s64-histogram(histogram), + /// Metric data for an s64 exponential-histogram. + s64-exponential-histogram(exponential-histogram), } /// A measurement of the current value of an instrument. @@ -76,7 +84,7 @@ interface metrics { time: datetime, } - /// `gauge-data-point` is a single data point in a time series. + /// A single data point in a time series to be associated with a `gauge`. record gauge-data-point { /// `attributes` is the set of key value pairs that uniquely identify the /// time series. @@ -102,7 +110,7 @@ interface metrics { is-monotonic: bool, } - /// `sum-data-point` is a single data point in a time series. + /// A single data point in a time series to be associated with a `sum`. record sum-data-point { /// `attributes` is the set of key value pairs that uniquely identify the /// time series. @@ -126,7 +134,7 @@ interface metrics { temporality: temporality, } - /// A single histogram data point in a time series. + /// A single data point in a time series to be associated with a `histogram`. record histogram-data-point { /// The set of key value pairs that uniquely identify the time series. attributes: list, @@ -159,12 +167,12 @@ interface metrics { temporality: temporality, } - /// A single exponential histogram data point in a time series. + /// A single data point in a time series to be associated with an `exponential-histogram `. record exponential-histogram-data-point { /// The set of key value pairs that uniquely identify the time series. attributes: list, /// The number of updates this histogram has been calculated with. - count: u64, // TODO: check that u64 is an acceptable replacement for usize + count: u64, /// The minimum value recorded. min: option, /// The maximum value recorded. @@ -234,7 +242,7 @@ interface metrics { /// /// New measurements are added to all previous measurements since a start time. /// - /// This is the default temporality + /// This is the default temporality. cumulative, /// A measurement interval that resets each cycle. /// @@ -247,12 +255,10 @@ interface metrics { low-memory, } - /// The number types available for use with the OpenTelemetry SDKs. - /// - /// This makes it easier to use generics when converting to and from WASI data types. + /// The number types available for any given instrument. variant metric-number { %f64(f64), %s64(s64), %u64(u64), } -} \ No newline at end of file +} diff --git a/wit/deps/otel/world.wit b/wit/deps/otel/world.wit index 8bfe740215..5824151cba 100644 --- a/wit/deps/otel/world.wit +++ b/wit/deps/otel/world.wit @@ -5,5 +5,3 @@ world imports { import tracing; import metrics; } - -// TODO: Switch to using wkg From c38f20e538441141843660d6908e217dae180319 Mon Sep 17 00:00:00 2001 From: Andrew Steurer <94206073+asteurer@users.noreply.github.com> Date: Fri, 31 Oct 2025 16:36:26 -0500 Subject: [PATCH 10/10] feat(factor-otel): small refactors Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com> --- crates/factor-otel/Cargo.toml | 2 +- crates/factor-otel/src/host.rs | 19 ++-- crates/world/src/conversions.rs | 171 ++++++++++++++++---------------- 3 files changed, 100 insertions(+), 92 deletions(-) diff --git a/crates/factor-otel/Cargo.toml b/crates/factor-otel/Cargo.toml index 66bb28e40c..1dcdb98c82 100644 --- a/crates/factor-otel/Cargo.toml +++ b/crates/factor-otel/Cargo.toml @@ -22,4 +22,4 @@ tracing-opentelemetry = { workspace = true } toml = "0.5" [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/crates/factor-otel/src/host.rs b/crates/factor-otel/src/host.rs index e63f032118..8ece27d5b1 100644 --- a/crates/factor-otel/src/host.rs +++ b/crates/factor-otel/src/host.rs @@ -67,13 +67,20 @@ impl wasi::otel::metrics::Host for InstanceState { Ok(_) => Ok(Ok(())), Err(e) => match e { OTelSdkError::AlreadyShutdown => { - Ok(Err("Shutdown has already been invoked".to_string())) + let msg = "Shutdown has already been invoked"; + tracing::error!(msg); + Ok(Err(msg.to_string())) + } + OTelSdkError::InternalFailure(e) => { + let detailed_msg = format!("Internal failure: {}", e); + tracing::error!(detailed_msg); + Ok(Err("Internal failure.".to_string())) + } + OTelSdkError::Timeout(d) => { + let detailed_msg = format!("Operation timed out after {} seconds", d.as_secs()); + tracing::error!(detailed_msg); + Ok(Err("Operation timed out.".to_string())) } - OTelSdkError::InternalFailure(e) => Ok(Err("Internal failure: ".to_string() + &e)), - OTelSdkError::Timeout(d) => Ok(Err(format!( - "Operation timed out after {} seconds", - d.as_secs() - ))), }, } } diff --git a/crates/world/src/conversions.rs b/crates/world/src/conversions.rs index abc8d8a461..2362ab8954 100644 --- a/crates/world/src/conversions.rs +++ b/crates/world/src/conversions.rs @@ -561,12 +561,11 @@ mod otel { use std::borrow::Cow; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use wasi::clocks0_2_0::wall_clock; - use wasi::otel::metrics as wasi_metrics; - use wasi::otel::tracing as wasi_tracing; - use wasi::otel::types as wasi_types; - impl From for opentelemetry_sdk::metrics::data::ResourceMetrics { - fn from(value: wasi_metrics::ResourceMetrics) -> Self { + impl From + for opentelemetry_sdk::metrics::data::ResourceMetrics + { + fn from(value: wasi::otel::metrics::ResourceMetrics) -> Self { Self { resource: value.resource.into(), scope_metrics: value.scope_metrics.into_iter().map(Into::into).collect(), @@ -574,16 +573,14 @@ mod otel { } } - impl From for opentelemetry_sdk::Resource { - fn from(value: wasi_metrics::Resource) -> Self { + impl From for opentelemetry_sdk::Resource { + fn from(value: wasi::otel::metrics::Resource) -> Self { let attributes: Vec = value.attributes.into_iter().map(Into::into).collect(); let schema_url: Option = value.schema_url.into(); match schema_url { Some(url) => opentelemetry_sdk::resource::Resource::builder() - // TODO: I'm unclear about what to do with the `with_schema_url()` method and the - // `with_attribute()` or `with_attributes()` methods. Is this good enough? .with_schema_url(attributes, url) .build(), None => opentelemetry_sdk::resource::Resource::builder() @@ -593,8 +590,8 @@ mod otel { } } - impl From for opentelemetry_sdk::metrics::data::ScopeMetrics { - fn from(value: wasi_metrics::ScopeMetrics) -> Self { + impl From for opentelemetry_sdk::metrics::data::ScopeMetrics { + fn from(value: wasi::otel::metrics::ScopeMetrics) -> Self { Self { scope: value.scope.into(), metrics: value.metrics.into_iter().map(Into::into).collect(), @@ -602,8 +599,8 @@ mod otel { } } - impl From for opentelemetry_sdk::metrics::data::Metric { - fn from(value: wasi_metrics::Metric) -> Self { + impl From for opentelemetry_sdk::metrics::data::Metric { + fn from(value: wasi::otel::metrics::Metric) -> Self { Self { name: Cow::Owned(value.name), description: Cow::Owned(value.description), @@ -759,60 +756,64 @@ mod otel { }; } - impl From for Box { - fn from(value: wasi_metrics::MetricData) -> Self { + impl From + for Box + { + fn from(value: wasi::otel::metrics::MetricData) -> Self { match value { - wasi_metrics::MetricData::F64Sum(s) => wasi_sum_to_otel!(s, f64), - wasi_metrics::MetricData::S64Sum(s) => wasi_sum_to_otel!(s, i64), - wasi_metrics::MetricData::U64Sum(s) => wasi_sum_to_otel!(s, u64), - wasi_metrics::MetricData::F64Gauge(g) => wasi_gauge_to_otel!(g, f64), - wasi_metrics::MetricData::S64Gauge(g) => wasi_gauge_to_otel!(g, i64), - wasi_metrics::MetricData::U64Gauge(g) => wasi_gauge_to_otel!(g, u64), - wasi_metrics::MetricData::F64Histogram(h) => wasi_histogram_to_otel!(h, f64), - wasi_metrics::MetricData::S64Histogram(h) => wasi_histogram_to_otel!(h, i64), - wasi_metrics::MetricData::U64Histogram(h) => wasi_histogram_to_otel!(h, u64), - wasi_metrics::MetricData::F64ExponentialHistogram(h) => { + wasi::otel::metrics::MetricData::F64Sum(s) => wasi_sum_to_otel!(s, f64), + wasi::otel::metrics::MetricData::S64Sum(s) => wasi_sum_to_otel!(s, i64), + wasi::otel::metrics::MetricData::U64Sum(s) => wasi_sum_to_otel!(s, u64), + wasi::otel::metrics::MetricData::F64Gauge(g) => wasi_gauge_to_otel!(g, f64), + wasi::otel::metrics::MetricData::S64Gauge(g) => wasi_gauge_to_otel!(g, i64), + wasi::otel::metrics::MetricData::U64Gauge(g) => wasi_gauge_to_otel!(g, u64), + wasi::otel::metrics::MetricData::F64Histogram(h) => wasi_histogram_to_otel!(h, f64), + wasi::otel::metrics::MetricData::S64Histogram(h) => wasi_histogram_to_otel!(h, i64), + wasi::otel::metrics::MetricData::U64Histogram(h) => wasi_histogram_to_otel!(h, u64), + wasi::otel::metrics::MetricData::F64ExponentialHistogram(h) => { wasi_exponential_histogram_to_otel!(h, f64) } - wasi_metrics::MetricData::S64ExponentialHistogram(h) => { + wasi::otel::metrics::MetricData::S64ExponentialHistogram(h) => { wasi_exponential_histogram_to_otel!(h, i64) } - wasi_metrics::MetricData::U64ExponentialHistogram(h) => { + wasi::otel::metrics::MetricData::U64ExponentialHistogram(h) => { wasi_exponential_histogram_to_otel!(h, u64) } } } } - impl From for f64 { - fn from(value: wasi_metrics::MetricNumber) -> Self { + impl From for f64 { + fn from(value: wasi::otel::metrics::MetricNumber) -> Self { match value { - wasi_metrics::MetricNumber::F64(n) => n, + wasi::otel::metrics::MetricNumber::F64(n) => n, _ => panic!("error converting WASI MetricNumber to f64"), } } } - impl From for u64 { - fn from(value: wasi_metrics::MetricNumber) -> Self { + impl From for u64 { + fn from(value: wasi::otel::metrics::MetricNumber) -> Self { match value { - wasi_metrics::MetricNumber::U64(n) => n, + wasi::otel::metrics::MetricNumber::U64(n) => n, _ => panic!("error converting WASI MetricNumber to u64"), } } } - impl From for i64 { - fn from(value: wasi_metrics::MetricNumber) -> Self { + impl From for i64 { + fn from(value: wasi::otel::metrics::MetricNumber) -> Self { match value { - wasi_metrics::MetricNumber::S64(n) => n, + wasi::otel::metrics::MetricNumber::S64(n) => n, _ => panic!("error converting WASI MetricNumber to i64"), } } } - impl From for opentelemetry_sdk::metrics::data::ExponentialBucket { - fn from(value: wasi_metrics::ExponentialBucket) -> Self { + impl From + for opentelemetry_sdk::metrics::data::ExponentialBucket + { + fn from(value: wasi::otel::metrics::ExponentialBucket) -> Self { Self { offset: value.offset, counts: value.counts, @@ -820,19 +821,19 @@ mod otel { } } - impl From for opentelemetry_sdk::metrics::Temporality { - fn from(value: wasi_metrics::Temporality) -> Self { + impl From for opentelemetry_sdk::metrics::Temporality { + fn from(value: wasi::otel::metrics::Temporality) -> Self { use opentelemetry_sdk::metrics::Temporality; match value { - wasi_metrics::Temporality::Cumulative => Temporality::Cumulative, - wasi_metrics::Temporality::Delta => Temporality::Delta, - wasi_metrics::Temporality::LowMemory => Temporality::LowMemory, + wasi::otel::metrics::Temporality::Cumulative => Temporality::Cumulative, + wasi::otel::metrics::Temporality::Delta => Temporality::Delta, + wasi::otel::metrics::Temporality::LowMemory => Temporality::LowMemory, } } } - impl From for opentelemetry_sdk::trace::SpanData { - fn from(value: wasi_tracing::SpanData) -> Self { + impl From for opentelemetry_sdk::trace::SpanData { + fn from(value: wasi::otel::tracing::SpanData) -> Self { let mut span_events = SpanEvents::default(); span_events.events = value.events.into_iter().map(Into::into).collect(); span_events.dropped_count = value.dropped_events; @@ -857,8 +858,8 @@ mod otel { } } - impl From for opentelemetry::trace::SpanContext { - fn from(sc: wasi_tracing::SpanContext) -> Self { + impl From for opentelemetry::trace::SpanContext { + fn from(sc: wasi::otel::tracing::SpanContext) -> Self { let trace_id = opentelemetry::trace::TraceId::from_hex(&sc.trace_id) .unwrap_or(opentelemetry::trace::TraceId::INVALID); let span_id = opentelemetry::trace::SpanId::from_hex(&sc.span_id) @@ -875,7 +876,7 @@ mod otel { } } - impl From for wasi_tracing::SpanContext { + impl From for wasi::otel::tracing::SpanContext { fn from(sc: opentelemetry::trace::SpanContext) -> Self { Self { trace_id: format!("{:x}", sc.trace_id()), @@ -898,68 +899,68 @@ mod otel { } } - impl From for opentelemetry::trace::TraceFlags { - fn from(flags: wasi_tracing::TraceFlags) -> Self { + impl From for opentelemetry::trace::TraceFlags { + fn from(flags: wasi::otel::tracing::TraceFlags) -> Self { Self::new(flags.as_array()[0] as u8) } } - impl From for wasi_tracing::TraceFlags { + impl From for wasi::otel::tracing::TraceFlags { fn from(flags: opentelemetry::trace::TraceFlags) -> Self { if flags.is_sampled() { - wasi_tracing::TraceFlags::SAMPLED + wasi::otel::tracing::TraceFlags::SAMPLED } else { - wasi_tracing::TraceFlags::empty() + wasi::otel::tracing::TraceFlags::empty() } } } - impl From for opentelemetry::trace::SpanKind { - fn from(kind: wasi_tracing::SpanKind) -> Self { + impl From for opentelemetry::trace::SpanKind { + fn from(kind: wasi::otel::tracing::SpanKind) -> Self { match kind { - wasi_tracing::SpanKind::Client => opentelemetry::trace::SpanKind::Client, - wasi_tracing::SpanKind::Server => opentelemetry::trace::SpanKind::Server, - wasi_tracing::SpanKind::Producer => opentelemetry::trace::SpanKind::Producer, - wasi_tracing::SpanKind::Consumer => opentelemetry::trace::SpanKind::Consumer, - wasi_tracing::SpanKind::Internal => opentelemetry::trace::SpanKind::Internal, + wasi::otel::tracing::SpanKind::Client => opentelemetry::trace::SpanKind::Client, + wasi::otel::tracing::SpanKind::Server => opentelemetry::trace::SpanKind::Server, + wasi::otel::tracing::SpanKind::Producer => opentelemetry::trace::SpanKind::Producer, + wasi::otel::tracing::SpanKind::Consumer => opentelemetry::trace::SpanKind::Consumer, + wasi::otel::tracing::SpanKind::Internal => opentelemetry::trace::SpanKind::Internal, } } } - impl From for opentelemetry::KeyValue { - fn from(kv: wasi_tracing::KeyValue) -> Self { + impl From for opentelemetry::KeyValue { + fn from(kv: wasi::otel::tracing::KeyValue) -> Self { opentelemetry::KeyValue::new(kv.key, kv.value) } } - impl From<&wasi_tracing::KeyValue> for opentelemetry::KeyValue { - fn from(kv: &wasi_tracing::KeyValue) -> Self { + impl From<&wasi::otel::tracing::KeyValue> for opentelemetry::KeyValue { + fn from(kv: &wasi::otel::tracing::KeyValue) -> Self { opentelemetry::KeyValue::new(kv.key.to_owned(), kv.value.to_owned()) } } - impl From for opentelemetry::Value { - fn from(value: wasi_types::Value) -> Self { + impl From for opentelemetry::Value { + fn from(value: wasi::otel::types::Value) -> Self { match value { - wasi_types::Value::String(v) => v.into(), - wasi_types::Value::Bool(v) => v.into(), - wasi_types::Value::F64(v) => v.into(), - wasi_types::Value::S64(v) => v.into(), - wasi_types::Value::StringArray(v) => opentelemetry::Value::Array( + wasi::otel::types::Value::String(v) => v.into(), + wasi::otel::types::Value::Bool(v) => v.into(), + wasi::otel::types::Value::F64(v) => v.into(), + wasi::otel::types::Value::S64(v) => v.into(), + wasi::otel::types::Value::StringArray(v) => opentelemetry::Value::Array( v.into_iter() .map(StringValue::from) .collect::>() .into(), ), - wasi_types::Value::BoolArray(v) => opentelemetry::Value::Array(v.into()), - wasi_types::Value::F64Array(v) => opentelemetry::Value::Array(v.into()), - wasi_types::Value::S64Array(v) => opentelemetry::Value::Array(v.into()), + wasi::otel::types::Value::BoolArray(v) => opentelemetry::Value::Array(v.into()), + wasi::otel::types::Value::F64Array(v) => opentelemetry::Value::Array(v.into()), + wasi::otel::types::Value::S64Array(v) => opentelemetry::Value::Array(v.into()), } } } - impl From for opentelemetry::trace::Event { - fn from(event: wasi_tracing::Event) -> Self { + impl From for opentelemetry::trace::Event { + fn from(event: wasi::otel::tracing::Event) -> Self { Self::new( event.name, event.time.into(), @@ -969,8 +970,8 @@ mod otel { } } - impl From for opentelemetry::trace::Link { - fn from(link: wasi_tracing::Link) -> Self { + impl From for opentelemetry::trace::Link { + fn from(link: wasi::otel::tracing::Link) -> Self { Self::new( link.span_context.into(), link.attributes.into_iter().map(Into::into).collect(), @@ -979,20 +980,20 @@ mod otel { } } - impl From for opentelemetry::trace::Status { - fn from(status: wasi_tracing::Status) -> Self { + impl From for opentelemetry::trace::Status { + fn from(status: wasi::otel::tracing::Status) -> Self { match status { - wasi_tracing::Status::Unset => Self::Unset, - wasi_tracing::Status::Ok => Self::Ok, - wasi_tracing::Status::Error(s) => Self::Error { + wasi::otel::tracing::Status::Unset => Self::Unset, + wasi::otel::tracing::Status::Ok => Self::Ok, + wasi::otel::tracing::Status::Error(s) => Self::Error { description: s.into(), }, } } } - impl From for opentelemetry::InstrumentationScope { - fn from(value: wasi_tracing::InstrumentationScope) -> Self { + impl From for opentelemetry::InstrumentationScope { + fn from(value: wasi::otel::tracing::InstrumentationScope) -> Self { let builder = Self::builder(value.name) .with_attributes(value.attributes.into_iter().map(Into::into)); match (value.version, value.schema_url) {