Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
241 changes: 228 additions & 13 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ categories = ["wasm"]
keywords = ["wasm"]

[workspace]
members = [".", "crates/http-server", "crates/interceptor"]
members = [".", "crates/http-server", "crates/interceptor", "crates/opentelemetry"]

[workspace.package]
version = "0.5.0-alpha.1"
version = "0.5.0-alpha.2"
license = "Apache-2.0"
repository = "https://github.com/modulewise/composable-runtime"
edition = "2024"
Expand All @@ -23,21 +23,26 @@ anyhow = "1"
clap = { version = "4.6", features = ["derive"] }
http-body-util = "0.1"
hyper = { version = "1", features = ["http1", "http2"] }
hyper-util = { version = "0.1", features = ["tokio"] }
hyper-util = { version = "0.1", features = ["server-graceful", "tokio"] }
opentelemetry = "0.31"
opentelemetry-otlp = { version = "0.31", default-features = false }
opentelemetry_sdk = "0.31"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
tempfile = "3"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "time"] }
tracing = "0.1"
uuid = { version = "1", features = ["v4"] }
wasm-encoder = "0.245"
wasmparser = "0.245"
wasmtime = "42"
wat = "1.245"
wit-parser = "0.245"

[dependencies]
anyhow.workspace = true
clap.workspace = true
composable-interceptor = { version = "0.5.0-alpha.1", path = "crates/interceptor" }
composable-interceptor = { version = "0.5.0-alpha.2", path = "crates/interceptor" }
http-body-util.workspace = true
hyper = { workspace = true, features = ["client", "http1", "http2"] }
oci-client = "0.16"
Expand All @@ -51,11 +56,11 @@ tokio-util = { version = "0.7", optional = true }
toml = "1"
tracing.workspace = true
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
uuid = { version = "1", features = ["v4"] }
uuid.workspace = true
wac-graph = "0.9"
wac-types = "0.9"
wasm-pkg-client = "0.15"
wasmtime = "42"
wasmtime = { workspace = true }
wasmtime-wasi = "42"
wasmtime-wasi-config = "42"
wasmtime-wasi-http = "42"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ That incrementally introduces each concept along the way:
- [http-server](examples/http-server): The greeter component invoked by the runtime when HTTP requests arrive, either directly or via a messaging channel depending on the route
- [interceptor](examples/interceptor): An interceptor component, dynamically generated from generic advice, logs before and after greeter function calls
- [messsaging](examples/messaging): The greeter component invoked when messages arrive via `composable publish`
- [otel](examples/otel): A guest component uses wasi:otel backed by either a host-capability or an adapter component
- [otel-components](examples/otel-components): A guest component uses wasi:otel backed by either a host-capability or an adapter component
- [otel-service](examples/otel-service): Trace propagation using the OtelService and HttpService sub-crates
- [service](examples/service): A custom Service provides a ConfigHandler, HostCapability, and its own lifecycle

This project also provides a foundation for the
Expand Down
6 changes: 5 additions & 1 deletion crates/http-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ keywords = ["wasm"]
[dependencies]
anyhow.workspace = true
clap = { workspace = true, optional = true }
composable-runtime = { version = "0.5.0-alpha.1", path = "../..", features = ["messaging"] }
composable-runtime = { version = "0.5.0-alpha.2", path = "../..", features = ["messaging"] }
http-body-util.workspace = true
hyper = { workspace = true, features = ["server", "http1"] }
hyper-util.workspace = true
opentelemetry.workspace = true
opentelemetry_sdk = { workspace = true, features = ["rt-tokio", "experimental_trace_batch_span_processor_with_async_runtime", "trace"] }
opentelemetry-otlp = { workspace = true, features = ["grpc-tonic", "http-proto", "reqwest-client", "trace"] }
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
tracing.workspace = true
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
uuid = { workspace = true }

[features]
default = ["cli"]
Expand Down
31 changes: 30 additions & 1 deletion crates/http-server/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub struct ServerConfig {
pub name: String,
pub port: u16,
pub routes: Vec<RouteConfig>,
/// OTLP endpoint for host-side span export. If absent, no host spans are exported.
pub otlp_endpoint: Option<String>,
/// OTLP protocol: "grpc" (default) or "http/protobuf".
pub otlp_protocol: String,
}

pub type SharedConfig = Arc<Mutex<Vec<ServerConfig>>>;
Expand Down Expand Up @@ -68,7 +72,10 @@ impl ConfigHandler for HttpServerConfigHandler {
}

fn claimed_properties(&self) -> HashMap<&str, &[&str]> {
HashMap::from([("server", ["type", "port", "route"].as_slice())])
HashMap::from([(
"server",
["type", "port", "route", "otlp-endpoint", "otlp-protocol"].as_slice(),
)])
}

fn handle_category(
Expand Down Expand Up @@ -105,6 +112,26 @@ impl ConfigHandler for HttpServerConfigHandler {
}
};

let otlp_endpoint = match properties.remove("otlp-endpoint") {
Some(serde_json::Value::String(s)) => Some(s),
Some(got) => {
return Err(anyhow::anyhow!(
"Server '{name}': 'otlp-endpoint' must be a string, got {got}"
));
}
None => None,
};

let otlp_protocol = match properties.remove("otlp-protocol") {
Some(serde_json::Value::String(s)) => s,
Some(got) => {
return Err(anyhow::anyhow!(
"Server '{name}': 'otlp-protocol' must be a string, got {got}"
));
}
None => "grpc".to_string(),
};

let routes = parse_routes(name, &mut properties)?;

if !properties.is_empty() {
Expand All @@ -118,6 +145,8 @@ impl ConfigHandler for HttpServerConfigHandler {
name: name.to_string(),
port,
routes,
otlp_endpoint,
otlp_protocol,
});
Ok(())
}
Expand Down
Loading