diff --git a/Cargo.lock b/Cargo.lock index a7eb2e6ce..d21cb3ade 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1868,6 +1868,7 @@ dependencies = [ "assert_matches", "async-trait", "futures", + "http", "itertools 0.14.0", "miden-air", "miden-lib", @@ -1887,6 +1888,8 @@ dependencies = [ "tokio", "tokio-stream", "tonic", + "tower 0.5.2", + "tower-http 0.6.2", "tracing", "url", "winterfell", @@ -3687,6 +3690,7 @@ dependencies = [ "http", "http-body", "pin-project-lite", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 2c05af39a..ad06641b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,8 @@ thiserror = { version = "2.0", default-features = false } tokio = { version = "1.40", features = ["rt-multi-thread"] } tokio-stream = { version = "0.1" } tonic = { version = "0.12" } +tower = "0.5" +tower-http = { version = "0.6" } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json"] } url = { version = "2.5", features = ["serde"] } diff --git a/bin/faucet/Cargo.toml b/bin/faucet/Cargo.toml index 83194cc0f..a06cf1de3 100644 --- a/bin/faucet/Cargo.toml +++ b/bin/faucet/Cargo.toml @@ -34,8 +34,8 @@ thiserror = { workspace = true } tokio = { workspace = true, features = ["fs"] } toml = { version = "0.8" } tonic = { workspace = true } -tower = "0.5" -tower-http = { version = "0.6", features = ["cors", "set-header", "trace"] } +tower = { workspace = true } +tower-http = { workspace = true, features = ["cors", "set-header", "trace"] } tracing = { workspace = true } url = { workspace = true } diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index dabf8d7bd..41871fcd4 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -20,6 +20,7 @@ tracing-forest = ["miden-node-utils/tracing-forest"] [dependencies] async-trait = { version = "0.1" } futures = { version = "0.3" } +http = { version = "1.2" } itertools = { workspace = true } miden-lib = { workspace = true } miden-node-proto = { workspace = true } @@ -35,6 +36,8 @@ thiserror = { workspace = true } tokio = { workspace = true, features = ["macros", "net", "rt-multi-thread", "sync", "time"] } tokio-stream = { workspace = true, features = ["net"] } tonic = { workspace = true } +tower = { workspace = true } +tower-http = { workspace = true, features = ["util"] } tracing = { workspace = true } url = { workspace = true } diff --git a/crates/block-producer/src/server.rs b/crates/block-producer/src/server.rs index 251d0b339..2ba26a772 100644 --- a/crates/block-producer/src/server.rs +++ b/crates/block-producer/src/server.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; use miden_node_proto::generated::{ block_producer::api_server, requests::SubmitProvenTransactionRequest, @@ -15,6 +15,7 @@ use miden_objects::{ use tokio::{net::TcpListener, sync::Mutex}; use tokio_stream::wrappers::TcpListenerStream; use tonic::Status; +use tower_http::{classify::GrpcFailureClass, trace::TraceLayer}; use tracing::{debug, info, instrument}; use crate::{ @@ -211,8 +212,17 @@ impl BlockProducerRpcServer { } async fn serve(self, listener: TcpListener) -> Result<(), tonic::transport::Error> { + let trace_layer = TraceLayer::new_for_grpc() + .make_span_with(miden_node_utils::tracing::grpc::block_producer_trace_fn) + .on_request(|_request: &http::Request<_>, _span: &tracing::Span| todo!()) + .on_response( + |_response: &http::Response<_>, _latency: Duration, _span: &tracing::Span| todo!(), + ) + .on_failure( + |_error: GrpcFailureClass, _latency: Duration, _span: &tracing::Span| todo!(), + ); tonic::transport::Server::builder() - .trace_fn(miden_node_utils::tracing::grpc::block_producer_trace_fn) + .layer(trace_layer) .add_service(api_server::ApiServer::new(self)) .serve_with_incoming(TcpListenerStream::new(listener)) .await diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 73995dca5..f5fe8fb1a 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -35,6 +35,7 @@ tracing = { workspace = true } tracing-forest = { version = "0.1", optional = true, features = ["chrono"] } tracing-opentelemetry = { version = "0.29" } tracing-subscriber = { workspace = true } + # Optional dependencies enabled by `vergen` feature. # This must match the version expected by `vergen-gitcl`. vergen = { "version" = "9.0", optional = true } diff --git a/crates/utils/src/tracing/grpc.rs b/crates/utils/src/tracing/grpc.rs index 1e951af12..ab343317f 100644 --- a/crates/utils/src/tracing/grpc.rs +++ b/crates/utils/src/tracing/grpc.rs @@ -6,7 +6,7 @@ use tracing_opentelemetry::OpenTelemetrySpanExt; /// Creates an `info` span following the open-telemetry standard: `block-producer.rpc/{method}`. /// Additionally also pulls in remote tracing context which allows the server trace to be connected /// to the client's origin trace. -pub fn block_producer_trace_fn(request: &http::Request<()>) -> tracing::Span { +pub fn block_producer_trace_fn(request: &http::Request) -> tracing::Span { let span = if let Some("SubmitProvenTransaction") = request.uri().path().rsplit('/').next() { tracing::info_span!("block-producer.rpc/SubmitProvenTransaction") } else { @@ -22,7 +22,7 @@ pub fn block_producer_trace_fn(request: &http::Request<()>) -> tracing::Span { /// Creates an `info` span following the open-telemetry standard: `store.rpc/{method}`. Additionally /// also pulls in remote tracing context which allows the server trace to be connected to the /// client's origin trace. -pub fn store_trace_fn(request: &http::Request<()>) -> tracing::Span { +pub fn store_trace_fn(request: &http::Request) -> tracing::Span { let span = match request.uri().path().rsplit('/').next() { Some("ApplyBlock") => tracing::info_span!("store.rpc/ApplyBlock"), Some("CheckNullifiers") => tracing::info_span!("store.rpc/CheckNullifiers"), @@ -47,7 +47,7 @@ pub fn store_trace_fn(request: &http::Request<()>) -> tracing::Span { /// Adds remote tracing context to the span. /// /// Could be expanded in the future by adding in more open-telemetry properties. -fn add_otel_span_attributes(span: tracing::Span, request: &http::Request<()>) -> tracing::Span { +fn add_otel_span_attributes(span: tracing::Span, request: &http::Request) -> tracing::Span { // Pull the open-telemetry parent context using the HTTP extractor. We could make a more // generic gRPC extractor by utilising the gRPC metadata. However that // (a) requires cloning headers,