Skip to content

Commit

Permalink
feat!: Add axum tooling to provide w3c tracecontexts in response payl…
Browse files Browse the repository at this point in the history
…oads (#780)

* feat!: Add axum tooling to provide w3c tracecontexts in response payloads

* Fix wasm errors

* Tracelayer needs to come before we start adding otel spans.

* Remove default for unit struct

* chore: Feature gate otel dependencies.

---------

Co-authored-by: Jordan Santell <jordan@subconscious.network>
  • Loading branch information
justinabrahms and jsantell committed Jan 16, 2024
1 parent 0213b51 commit 4d84bea
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 19 deletions.
140 changes: 135 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ anyhow = { version = "1" }
async-recursion = { version = "1" }
async-stream = { version = "0.3" }
axum = { version = "^0.6.18" }
axum-tracing-opentelemetry = { version = "0.15.0" }
base64 = { version = "^0.21" }
byteorder = { version = "~1.4" } # keep in sync with pinned libipld-* crates
bytes = { version = "^1" }
Expand Down
3 changes: 2 additions & 1 deletion rust/noosphere-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ homepage = "https://github.com/subconsciousnetwork/noosphere"
readme = "README.md"

[features]
default = []
default = ["observability"]
helpers = ["tracing-subscriber", "noosphere-ns"]
rocksdb = ["noosphere/rocksdb"]
observability = ["noosphere-gateway/observability"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
3 changes: 3 additions & 0 deletions rust/noosphere-gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ homepage = "https://github.com/subconsciousnetwork/noosphere"
readme = "README.md"

[features]
default = []
test-kubo = []
observability = ["axum-tracing-opentelemetry"]

[dependencies]
tracing = { workspace = true }
Expand All @@ -29,6 +31,7 @@ noosphere-core = { version = "0.18.0", path = "../noosphere-core", features = ["
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
anyhow = { workspace = true }
axum = { workspace = true, features = ["headers", "macros"] }
axum-tracing-opentelemetry = { workspace = true, optional = true }
iroh-car = { workspace = true }
thiserror = { workspace = true }
strum = { workspace = true }
Expand Down
28 changes: 19 additions & 9 deletions rust/noosphere-gateway/src/gateway.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
use crate::GatewayManager;
use crate::{
handlers,
worker::{
start_cleanup, start_ipfs_syndication, start_name_system, NameSystemConfiguration,
NameSystemConnectionType,
},
};
use anyhow::Result;
use axum::extract::DefaultBodyLimit;
use axum::http::{HeaderValue, Method};
Expand All @@ -14,14 +22,8 @@ use tower_http::cors::{Any, CorsLayer};
use tower_http::trace::TraceLayer;
use url::Url;

use crate::GatewayManager;
use crate::{
handlers,
worker::{
start_cleanup, start_ipfs_syndication, start_name_system, NameSystemConfiguration,
NameSystemConnectionType,
},
};
#[cfg(feature = "observability")]
use axum_tracing_opentelemetry::middleware::{OtelAxumLayer, OtelInResponseLayer};

const DEFAULT_BODY_LENGTH_LIMIT: usize = 100 /* MB */ * 1000 * 1000;

Expand Down Expand Up @@ -112,7 +114,15 @@ impl Gateway {
.layer(Extension(name_system_tx))
.layer(Extension(cleanup_tx))
.layer(DefaultBodyLimit::max(DEFAULT_BODY_LENGTH_LIMIT))
.layer(cors)
.layer(cors);

#[cfg(feature = "observability")]
let app = {
app.layer(OtelInResponseLayer) // include trace context in response
.layer(OtelAxumLayer::default()) // initialize otel trace on incoming request
};

let app = app
.layer(TraceLayer::new_for_http())
.with_state(Arc::new(manager));

Expand Down
4 changes: 3 additions & 1 deletion rust/noosphere-ns/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ toml = { version = "~0.8", optional = true }

# noosphere_ns::server
axum = { workspace = true, features = ["json", "headers", "macros"], optional = true }
axum-tracing-opentelemetry = { workspace = true, optional = true }
reqwest = { version = "~0.11", default-features = false, features = ["json", "rustls-tls"], optional = true }
tower-http = { workspace = true, features = ["trace"], optional = true }
url = { version = "^2", features = [ "serde" ], optional = true }
Expand All @@ -63,9 +64,10 @@ libipld-cbor = { workspace = true }
tempfile = { workspace = true }

[features]
default = ["orb-ns", "api-server"]
default = ["orb-ns", "api-server", "observability"]
api-server = ["axum", "reqwest", "url", "tower-http"]
orb-ns = ["clap", "noosphere", "home", "toml", "noosphere-ipfs"]
observability = ["axum-tracing-opentelemetry"]

[[bin]]
name = "orb-ns"
Expand Down
17 changes: 14 additions & 3 deletions rust/noosphere-ns/src/server/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use std::net::TcpListener;
use std::sync::Arc;
use tower_http::trace::TraceLayer;

#[cfg(feature = "observability")]
use axum_tracing_opentelemetry::middleware::{OtelAxumLayer, OtelInResponseLayer};

pub async fn start_name_system_api_server(
ns: Arc<NameSystem>,
listener: TcpListener,
Expand All @@ -29,9 +32,17 @@ pub async fn start_name_system_api_server(
.route(&Route::Address.to_string(), get(handlers::get_address))
.route(&Route::GetRecord.to_string(), get(handlers::get_record))
.route(&Route::PostRecord.to_string(), post(handlers::post_record))
.route(&Route::Bootstrap.to_string(), post(handlers::bootstrap))
.with_state(handlers::RouterState { ns, peer_id })
.layer(TraceLayer::new_for_http());
.route(&Route::Bootstrap.to_string(), post(handlers::bootstrap));

#[cfg(feature = "observability")]
let app = {
app.layer(OtelInResponseLayer) // include trace context in response
.layer(OtelAxumLayer::default()) // initialize otel trace on incoming request
};

let app = app
.layer(TraceLayer::new_for_http())
.with_state(handlers::RouterState { ns, peer_id });

Server::from_tcp(listener)?
.serve(app.into_make_service())
Expand Down

0 comments on commit 4d84bea

Please sign in to comment.