diff --git a/Cargo.lock b/Cargo.lock index 8ebeb7f46..9fd3f80d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -602,8 +602,6 @@ dependencies = [ [[package]] name = "containerd-shim" version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecfe3bbd2e126cbd3b37ebc7faadedeeb5a87a389dc1668f1f0f4d246e46769" dependencies = [ "cgroups-rs", "command-fds", @@ -615,6 +613,7 @@ dependencies = [ "mio", "nix 0.28.0", "oci-spec", + "opentelemetry 0.21.0", "os_pipe", "page_size", "prctl", @@ -623,14 +622,15 @@ dependencies = [ "signal-hook", "thiserror", "time", + "tracing", + "tracing-log", + "tracing-opentelemetry 0.22.0", "windows-sys 0.52.0", ] [[package]] name = "containerd-shim-protos" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e4ef8fa542cd6964b2705983d02de4f4bdaaac8d25feabcef5c43a87ac58291" dependencies = [ "protobuf 3.2.0", "ttrpc", @@ -658,6 +658,9 @@ dependencies = [ "nix 0.28.0", "oci-spec", "oci-tar-builder", + "opentelemetry 0.22.0", + "opentelemetry-otlp", + "opentelemetry_sdk 0.22.1", "prost-types 0.12.4", "protobuf 3.2.0", "rand", @@ -669,6 +672,8 @@ dependencies = [ "tokio", "tokio-stream", "tracing", + "tracing-opentelemetry 0.23.0", + "tracing-subscriber", "ttrpc", "ttrpc-codegen", "wasmparser 0.206.0", @@ -734,6 +739,7 @@ dependencies = [ "oci-spec", "serial_test", "sha256", + "tokio", "ttrpc", "wasi-common", "wasmtime", @@ -2231,6 +2237,15 @@ dependencies = [ "libc", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "matchit" version = "0.7.0" @@ -2435,6 +2450,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2576,6 +2601,125 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" +dependencies = [ + "futures-core", + "futures-sink", + "indexmap 2.2.6", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900d57987be3f2aeb70d385fff9b27fb74c5723cc9a52d904d4f9c807a0667bf" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a016b8d9495c639af2145ac22387dcb88e44118e45320d9238fbf4e7889abcb" +dependencies = [ + "async-trait", + "futures-core", + "http", + "opentelemetry 0.22.0", + "opentelemetry-proto", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk 0.22.1", + "prost 0.12.4", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8fddc9b68f5b80dae9d6f510b88e02396f006ad48cac349411fbecc80caae4" +dependencies = [ + "opentelemetry 0.22.0", + "opentelemetry_sdk 0.22.1", + "prost 0.12.4", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9ab5bd6c42fb9349dcf28af2ba9a0667f697f9bdcca045d39f2cec5543e2910" + +[[package]] +name = "opentelemetry_sdk" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f16aec8a98a457a52664d69e0091bac3a0abd18ead9b641cb00202ba4e0efe4" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "once_cell", + "opentelemetry 0.21.0", + "ordered-float", + "percent-encoding", + "rand", + "thiserror", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e90c7113be649e31e9a0f8b5ee24ed7a16923b322c3c5ab6367469c049d6b7e" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "once_cell", + "opentelemetry 0.22.0", + "ordered-float", + "percent-encoding", + "rand", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + [[package]] name = "os_pipe" version = "1.1.4" @@ -2586,6 +2730,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "page_size" version = "0.6.0" @@ -3176,8 +3326,17 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", +] + +[[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", ] [[package]] @@ -3188,9 +3347,15 @@ checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.2", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.2" @@ -3645,6 +3810,15 @@ dependencies = [ "tokio", ] +[[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 = "shared-buffer" version = "0.1.3" @@ -3929,6 +4103,16 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", +] + [[package]] name = "time" version = "0.3.29" @@ -4227,6 +4411,72 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 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.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c67ac25c5407e7b961fafc6f7e9aa5958fd297aada2d20fa2ae1737357e55596" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry 0.21.0", + "opentelemetry_sdk 0.21.2", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time 0.2.4", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9be14ba1bbe4ab79e9229f7f89fab8d120b865859f10527f31c033e599d2284" +dependencies = [ + "js-sys", + "once_cell", + "opentelemetry 0.22.0", + "opentelemetry_sdk 0.22.1", + "smallvec", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "web-time 1.1.0", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -4375,6 +4625,12 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.8.0" @@ -5472,6 +5728,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[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 = "webc" version = "5.6.0" diff --git a/Cargo.toml b/Cargo.toml index 1dfef128b..34f45a7d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,8 @@ homepage = "https://github.com/containerd/runwasi" anyhow = "1.0" cap-std = "1.0" chrono = { version = "0.4", default-features = false, features = ["clock"] } -containerd-shim = "0.7.1" -containerd-shim-wasm = { path = "crates/containerd-shim-wasm", version = "0.5.0" } +containerd-shim = { path = "../rust-extensions-fork/crates/shim" } +containerd-shim-wasm = { path = "crates/containerd-shim-wasm" } containerd-shim-wasm-test-modules = { path = "crates/containerd-shim-wasm-test-modules", version = "0.4.0"} oci-tar-builder = { path = "crates/oci-tar-builder", version = "0.4.0" } crossbeam = { version = "0.8.4", default-features = false } diff --git a/Makefile b/Makefile index aac0dcfe9..4bb1f710a 100644 --- a/Makefile +++ b/Makefile @@ -134,7 +134,7 @@ test-oci-tar-builder: .PHONY: install install-% install: $(RUNTIMES:%=install-%); -install-%: build-% +install-%: mkdir -p $(PREFIX)/bin $(INSTALL) $(TARGET_DIR)/$(TARGET)/$(OPT_PROFILE)/containerd-shim-$*-v1 $(PREFIX)/bin/ $(LN) ./containerd-shim-$*-v1 $(PREFIX)/bin/containerd-shim-$*d-v1 diff --git a/crates/containerd-shim-wasm/Cargo.toml b/crates/containerd-shim-wasm/Cargo.toml index ae3ee7538..e49dbf8f2 100644 --- a/crates/containerd-shim-wasm/Cargo.toml +++ b/crates/containerd-shim-wasm/Cargo.toml @@ -30,24 +30,46 @@ tempfile = { workspace = true, optional = true } thiserror = { workspace = true } ttrpc = { workspace = true } wat = { workspace = true } -tokio = { version = "1.37.0", features = [ "full" ] } +tokio = { version = "1.37.0", features = ["full"] } futures = { version = "0.3.30" } wasmparser = "0.206.0" tokio-stream = { version = "0.1" } -prost-types = "0.12" # should match version in containerd-shim +prost-types = "0.12" # should match version in containerd-shim sha256 = { workspace = true } tracing = { workspace = true } +# opentelemetry +opentelemetry = { version = "0.22", features = ["trace"], optional = true } +opentelemetry-otlp = { version = "0.15.0", features = [ + "tonic", +], optional = true } +opentelemetry_sdk = { version = "0.22", features = [ + "rt-tokio", +], optional = true } +tracing-subscriber = { version = "0.3", features = [ + "env-filter", +], optional = true } +tracing-opentelemetry = { version = "0.23", optional = true } + + [target.'cfg(unix)'.dependencies] caps = "0.5" # this must match the version pulled by libcontainer dbus = { version = "0", features = ["vendored"] } -libcontainer = { workspace = true, features = ["libseccomp", "systemd", "v1", "v2"]} +libcontainer = { workspace = true, features = [ + "libseccomp", + "systemd", + "v1", + "v2", +] } nix = { workspace = true, features = ["sched", "mount"] } containerd-client = "0.5.0" [target.'cfg(windows)'.dependencies] -windows-sys = { workspace = true, features = ["Win32_Foundation", "Win32_Storage_FileSystem"] } +windows-sys = { workspace = true, features = [ + "Win32_Foundation", + "Win32_Storage_FileSystem", +] } [build-dependencies] ttrpc-codegen = { version = "0.4.2" } @@ -56,8 +78,20 @@ ttrpc-codegen = { version = "0.4.2" } containerd-shim-wasm-test-modules = { workspace = true } env_logger = { workspace = true } tempfile = { workspace = true } -oci-tar-builder = { workspace = true} -rand= "0.8" +oci-tar-builder = { workspace = true } +rand = "0.8" [features] -testing = ["dep:containerd-shim-wasm-test-modules", "dep:env_logger", "dep:tempfile", "dep:oci-tar-builder"] +testing = [ + "dep:containerd-shim-wasm-test-modules", + "dep:env_logger", + "dep:tempfile", + "dep:oci-tar-builder", +] +opentelemetry = [ + "dep:opentelemetry", + "dep:opentelemetry-otlp", + "dep:opentelemetry_sdk", + "dep:tracing-subscriber", + "dep:tracing-opentelemetry", +] diff --git a/crates/containerd-shim-wasm/src/sandbox/cli.rs b/crates/containerd-shim-wasm/src/sandbox/cli.rs index 0fa51eb13..429ad3e45 100644 --- a/crates/containerd-shim-wasm/src/sandbox/cli.rs +++ b/crates/containerd-shim-wasm/src/sandbox/cli.rs @@ -3,14 +3,20 @@ use std::sync::mpsc::channel; use std::sync::Arc; use containerd_shim::{parse, run, Config}; -use tracing::{instrument, Span}; +use opentelemetry::global::{set_text_map_propagator, shutdown_tracer_provider}; +use opentelemetry_sdk::propagation::TraceContextPropagator; +use tracing::instrument; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::{EnvFilter, Registry}; use ttrpc::Server; use crate::sandbox::manager::Shim; -use crate::sandbox::shim::Local; +use crate::sandbox::shim::{init_tracer, Local}; use crate::sandbox::{Instance, ManagerService, ShimCli}; use crate::services::sandbox_ttrpc::{create_manager, Manager}; +const OTEL_EXPORTER_OTLP_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_ENDPOINT"; + pub mod r#impl { pub use git_version::git_version; } @@ -37,7 +43,47 @@ macro_rules! revision { }; } -#[instrument(skip_all, parent = Span::current(), level= "Info")] +/// Main entry point for the shim with OpenTelemetry tracing. +/// +/// It parses the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable to determine +/// if the shim should be started with OpenTelemetry tracing. +/// +/// If the environment variable is not set, the shim will be started without tracing. +/// If the environment variable is empty, the shim will be started without tracing. +#[cfg(feature = "opentelemetry")] +pub fn shim_main_with_otel<'a, I>( + name: &str, + version: &str, + revision: impl Into>, + shim_version: impl Into>, + config: Option, +) where + I: 'static + Instance + Sync + Send, + I::Engine: Default, +{ + let otel_endpoint = std::env::var(OTEL_EXPORTER_OTLP_ENDPOINT); + if otel_endpoint.is_err() || otel_endpoint.clone().unwrap().is_empty() { + shim_main::(name, version, revision, shim_version, config); + } else { + let tracer = + init_tracer(&otel_endpoint.unwrap(), name).expect("Failed to initialize tracer."); + let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); + set_text_map_propagator(TraceContextPropagator::new()); + + // Create an environment filter + let filter = EnvFilter::try_new("info,h2=off") // Set default level to `info` and exclude all traces from `h2` + .expect("Invalid filter directive"); + + let subscriber = Registry::default().with(telemetry).with(filter); + + tracing::subscriber::set_global_default(subscriber) + .expect("setting default subscriber failed"); + shim_main::(name, version, revision, shim_version, config); + shutdown_tracer_provider(); + } +} + +#[instrument(skip_all, level = "Info")] pub fn shim_main<'a, I>( name: &str, version: &str, @@ -49,6 +95,7 @@ pub fn shim_main<'a, I>( I::Engine: Default, { let os_args: Vec<_> = std::env::args_os().collect(); + let flags = parse(&os_args[1..]).unwrap(); let argv0 = PathBuf::from(&os_args[0]); let argv0 = argv0.file_stem().unwrap_or_default().to_string_lossy(); @@ -62,6 +109,7 @@ pub fn shim_main<'a, I>( std::process::exit(0); } + let shim_version = shim_version.into().unwrap_or("v1"); let lower_name = name.to_lowercase(); @@ -95,7 +143,9 @@ pub fn shim_main<'a, I>( } _ => { eprintln!("error: unrecognized binary name, expected one of {shim_cli}, {shim_client}, or {shim_daemon}."); + shutdown_tracer_provider(); std::process::exit(1); } } + shutdown_tracer_provider(); } diff --git a/crates/containerd-shim-wasm/src/sandbox/instance.rs b/crates/containerd-shim-wasm/src/sandbox/instance.rs index 32498be54..e7aa2b7b4 100644 --- a/crates/containerd-shim-wasm/src/sandbox/instance.rs +++ b/crates/containerd-shim-wasm/src/sandbox/instance.rs @@ -137,7 +137,7 @@ pub trait Instance: 'static { /// Waits for the instance to finish and retunrs its exit code /// This is a blocking call. - #[instrument(skip_all, parent = Span::current(), level= "Info")] + #[instrument(skip(self), parent = Span::current(), level= "Info")] fn wait(&self) -> (u32, DateTime) { self.wait_timeout(None).unwrap() } diff --git a/crates/containerd-shim-wasm/src/sandbox/shim/cli.rs b/crates/containerd-shim-wasm/src/sandbox/shim/cli.rs index 0486cb4d8..69dade439 100644 --- a/crates/containerd-shim-wasm/src/sandbox/shim/cli.rs +++ b/crates/containerd-shim-wasm/src/sandbox/shim/cli.rs @@ -14,7 +14,6 @@ use tracing::{instrument, Span}; use crate::sandbox::instance::Instance; use crate::sandbox::shim::events::{RemoteEventSender, ToTimestamp}; use crate::sandbox::shim::local::Local; -use crate::sys::networking::setup_namespaces; /// Cli implements the containerd-shim cli interface using `Local` as the task service. pub struct Cli { @@ -46,7 +45,7 @@ where { type T = Local; - #[instrument(skip_all, parent = Span::current(), level= "Info")] + #[instrument(skip_all, level = "Info")] fn new(_runtime_id: &str, args: &Flags, _config: &mut shim::Config) -> Self { Cli { engine: Default::default(), @@ -71,22 +70,27 @@ where .and_then(|a| a.get("io.kubernetes.cri.sandbox-id")) .unwrap_or(&id); - setup_namespaces(&spec) - .map_err(|e| shim::Error::Other(format!("failed to setup namespaces: {}", e)))?; + let otel_endpoint = std::env::var_os("OTEL_EXPORTER_OTLP_ENDPOINT") + .map(|s| s.to_string_lossy().to_string()) + .unwrap_or_else(|| "".to_string()); - let (_child, address) = shim::spawn(opts, grouping, vec![])?; + let (_child, address) = shim::spawn( + opts, + grouping, + vec![("OTEL_EXPORTER_OTLP_ENDPOINT", &otel_endpoint)], + )?; write_address(&address)?; Ok(address) } - #[instrument(skip_all, parent = Span::current(), level = "Info")] + #[instrument(skip_all, level = "Info")] fn wait(&mut self) { self.exit.wait(); } - #[instrument(skip_all, parent = Span::current(), level= "Info")] + #[instrument(skip_all, level = "Info")] fn create_task_service(&self, publisher: RemotePublisher) -> Self::T { let events = RemoteEventSender::new(&self.namespace, publisher); let exit = self.exit.clone(); @@ -100,7 +104,7 @@ where ) } - #[instrument(skip_all, parent = Span::current(), level= "Info")] + #[instrument(skip_all, level = "Info")] fn delete_shim(&mut self) -> shim::Result { Ok(api::DeleteResponse { exit_status: 137, diff --git a/crates/containerd-shim-wasm/src/sandbox/shim/instance_option.rs b/crates/containerd-shim-wasm/src/sandbox/shim/instance_option.rs index c5f0ec093..0b078a592 100644 --- a/crates/containerd-shim-wasm/src/sandbox/shim/instance_option.rs +++ b/crates/containerd-shim-wasm/src/sandbox/shim/instance_option.rs @@ -44,7 +44,7 @@ impl Instance for InstanceOption { } } - #[instrument(skip_all, parent = Span::current(), level= "Info")] + #[instrument(skip(self, t), parent = Span::current(), level= "Info")] fn wait_timeout(&self, t: impl Into>) -> Option<(u32, DateTime)> { match self { Self::Instance(i) => i.wait_timeout(t), diff --git a/crates/containerd-shim-wasm/src/sandbox/shim/local.rs b/crates/containerd-shim-wasm/src/sandbox/shim/local.rs index 62cd529a8..cfad24868 100644 --- a/crates/containerd-shim-wasm/src/sandbox/shim/local.rs +++ b/crates/containerd-shim-wasm/src/sandbox/shim/local.rs @@ -230,8 +230,6 @@ impl Local { .context("could not spawn thread to wait exit") .map_err(Error::from)?; - debug!("started: {:?}", req); - Ok(StartResponse { pid, ..Default::default() diff --git a/crates/containerd-shim-wasm/src/sandbox/shim/mod.rs b/crates/containerd-shim-wasm/src/sandbox/shim/mod.rs index 225dd8f81..57b854435 100644 --- a/crates/containerd-shim-wasm/src/sandbox/shim/mod.rs +++ b/crates/containerd-shim-wasm/src/sandbox/shim/mod.rs @@ -7,7 +7,10 @@ mod events; mod instance_data; mod instance_option; mod local; +mod otel; mod task_state; pub use cli::Cli; pub(crate) use local::Local; +#[cfg(feature = "opentelemetry")] +pub use otel::init_tracer; diff --git a/crates/containerd-shim-wasm/src/sandbox/shim/otel.rs b/crates/containerd-shim-wasm/src/sandbox/shim/otel.rs new file mode 100644 index 000000000..a9bb41013 --- /dev/null +++ b/crates/containerd-shim-wasm/src/sandbox/shim/otel.rs @@ -0,0 +1,31 @@ +use opentelemetry::trace::TraceError; +use opentelemetry::KeyValue; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_sdk::{runtime, trace as sdktrace, Resource}; + +/// Initialize a new OpenTelemetry tracer with the OTLP exporter. +/// The `otel_endpoint` is the endpoint passed down from the +/// environment variable `OTEL_EXPORTER_OTLP_ENDPOINT` from Containerd. +/// +/// The `name` is the name of the service that will be used as a resource. +/// +/// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options +pub fn init_tracer( + otel_endpoint: &str, + name: &str, +) -> Result { + opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint(otel_endpoint), + ) + .with_trace_config( + sdktrace::config().with_resource(Resource::new(vec![KeyValue::new( + "service.name", + name.to_string(), + )])), + ) + .install_batch(runtime::Tokio) +} diff --git a/crates/containerd-shim-wasm/src/sandbox/sync.rs b/crates/containerd-shim-wasm/src/sandbox/sync.rs index 9b8fe4823..a8495929d 100644 --- a/crates/containerd-shim-wasm/src/sandbox/sync.rs +++ b/crates/containerd-shim-wasm/src/sandbox/sync.rs @@ -100,6 +100,10 @@ impl WaitableCell { let timeout = timeout.into(); let cvar = &self.inner.cvar; let guard = self.inner.mutex.lock().unwrap(); + + let span = tracing::span!(tracing::Level::INFO, "wait_timeout"); + let _enter = span.enter(); + let _guard = match timeout { None => cvar .wait_while(guard, |_| self.inner.cell.get().is_none()) @@ -110,6 +114,9 @@ impl WaitableCell { .map(|(guard, _)| guard) .unwrap(), }; + + let _re_enter = span.enter(); + self.inner.cell.get() } } diff --git a/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs b/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs index 7cc76444e..522cd9a39 100644 --- a/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs +++ b/crates/containerd-shim-wasm/src/sys/unix/container/instance.rs @@ -151,7 +151,7 @@ impl SandboxInstance for Instance { /// Waits for the instance to finish and retunrs its exit code /// Returns None if the timeout is reached before the instance has finished. /// This is a blocking call. - #[instrument(skip_all, parent = Span::current(), level= "Info")] + #[instrument(skip(self, t), parent = Span::current(), level= "Info")] fn wait_timeout(&self, t: impl Into>) -> Option<(u32, DateTime)> { self.exit_code.wait_timeout(t).copied() } diff --git a/crates/containerd-shim-wasmtime/Cargo.toml b/crates/containerd-shim-wasmtime/Cargo.toml index 05a8e7fa1..e8b002534 100644 --- a/crates/containerd-shim-wasmtime/Cargo.toml +++ b/crates/containerd-shim-wasmtime/Cargo.toml @@ -6,7 +6,7 @@ edition.workspace = true [dependencies] anyhow = { workspace = true } containerd-shim = { workspace = true } -containerd-shim-wasm = { workspace = true } +containerd-shim-wasm = { workspace = true, features = ["opentelemetry"] } log = { workspace = true } oci-spec = { workspace = true, features = ["runtime"] } ttrpc = { workspace = true } @@ -33,6 +33,9 @@ wasmtime = { version = "17.0", default-features = false, features = [ wasmtime-wasi = { version = "17.0", features = ["exit"] } wasi-common = "17.0" +# OpenTelemetry dependencies +tokio = { version = "1.35", features = ["full"] } + [dev-dependencies] containerd-shim-wasm = { workspace = true, features = ["testing"] } serial_test = { workspace = true } diff --git a/crates/containerd-shim-wasmtime/src/main.rs b/crates/containerd-shim-wasmtime/src/main.rs index ccbcb6137..f367532c6 100644 --- a/crates/containerd-shim-wasmtime/src/main.rs +++ b/crates/containerd-shim-wasmtime/src/main.rs @@ -1,6 +1,7 @@ -use containerd_shim_wasm::sandbox::cli::{revision, shim_main, version}; +use containerd_shim_wasm::sandbox::cli::{revision, shim_main_with_otel, version}; use containerd_shim_wasmtime::WasmtimeInstance; -fn main() { - shim_main::("wasmtime", version!(), revision!(), "v1", None); +#[tokio::main] +async fn main() { + shim_main_with_otel::("wasmtime", version!(), revision!(), "v1", None); }