Skip to content

Commit

Permalink
update trace lib
Browse files Browse the repository at this point in the history
  • Loading branch information
phantie committed Apr 29, 2024
1 parent 4ba508c commit 3e2105b
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 143 deletions.
2 changes: 1 addition & 1 deletion backend/src/authentication.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
db,
error::{ApiError, ApiResult},
telemetry::spawn_blocking_with_tracing,
trace::spawn_blocking_with_tracing,
};
use anyhow::Context;
use axum_sessions::extractors::ReadableSession;
Expand Down
2 changes: 1 addition & 1 deletion backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub mod db;
pub mod error;
pub mod serve_files;
pub mod startup;
pub mod telemetry;
pub mod timeout;
pub mod trace;

mod routes;
mod static_routes;
7 changes: 4 additions & 3 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use backend::conf::{self};
use backend::serve_files;
use backend::startup::Application;
use backend::telemetry;
use backend::trace;

#[tokio::main]
async fn main() -> hyper::Result<()> {
let env = conf::Env::derive();
let env_conf = conf::EnvConf::derive(env);

let subscriber = telemetry::TracingSubscriber::new("site").build(std::io::stdout);
telemetry::init_global_default(subscriber);
trace::TracingSubscriber::new()
.pretty(env_conf.log.pretty)
.set_global_default();

tracing::debug!("Env: {}", env);
tracing::debug!("{:?}", env_conf);
Expand Down
53 changes: 2 additions & 51 deletions backend/src/startup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,7 @@ use axum_sessions::{
SessionLayer,
};
use std::sync::Arc;
use tower_http::{
add_extension::AddExtensionLayer,
compression::CompressionLayer,
trace::{DefaultMakeSpan, DefaultOnRequest, DefaultOnResponse, TraceLayer},
LatencyUnit, ServiceBuilderExt,
};

#[derive(Clone, Default)]
pub struct RequestIdProducer {
counter: Arc<std::sync::atomic::AtomicU64>,
}

impl tower_http::request_id::MakeRequestId for RequestIdProducer {
fn make_request_id<B>(
&mut self,
_request: &hyper::http::Request<B>,
) -> Option<tower_http::request_id::RequestId> {
let request_id = self
.counter
.fetch_add(1, std::sync::atomic::Ordering::SeqCst)
.to_string()
.parse()
.unwrap();

Some(tower_http::request_id::RequestId::new(request_id))
}
}
use tower_http::{add_extension::AddExtensionLayer, compression::CompressionLayer};

pub fn router(conf: Conf, db: cozo::DbInstance) -> Router<AppState> {
use crate::routes::*;
Expand Down Expand Up @@ -83,29 +57,6 @@ pub fn router(conf: Conf, db: cozo::DbInstance) -> Router<AppState> {

let ws_router = Router::new().route("/users_online", get(ws_users_online));

let request_tracing_layer = tower::ServiceBuilder::new()
.set_x_request_id(RequestIdProducer::default())
.layer(
TraceLayer::new_for_http()
.make_span_with(DefaultMakeSpan::new().level(tracing::Level::DEBUG).include_headers(true))
.make_span_with(|request: &hyper::http::Request<hyper::Body>| {
tracing::info_span!(
"request",
method = %request.method(),
uri = %request.uri(),
version = ?request.version(),
request_id = %request.headers().get("x-request-id").unwrap().to_str().unwrap(),
)
})
.on_request(DefaultOnRequest::new().level(tracing::Level::INFO))
.on_response(
DefaultOnResponse::new()
.level(tracing::Level::INFO)
.latency_unit(LatencyUnit::Seconds),
),
)
.propagate_x_request_id();

Router::new()
.nest("/api", api_router)
.nest("/ws", ws_router)
Expand All @@ -114,7 +65,7 @@ pub fn router(conf: Conf, db: cozo::DbInstance) -> Router<AppState> {
.layer(axum::middleware::from_fn(endpoint_hit_middleware))
.layer(AddExtensionLayer::new(db.clone()))
.layer(AddExtensionLayer::new(conf.clone()))
.layer(request_tracing_layer)
.layer(crate::trace::request_trace_layer())
.layer({
// let store = axum_sessions::async_session::MemoryStore::new();
let store = BonsaiDBSessionStore { db: db.clone() };
Expand Down
79 changes: 0 additions & 79 deletions backend/src/telemetry.rs

This file was deleted.

165 changes: 165 additions & 0 deletions backend/src/trace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Tracing definitions
//

use tracing::{subscriber::set_global_default, Subscriber};
use tracing_log::LogTracer;
use tracing_subscriber::{
filter,
layer::{Layer, SubscriberExt},
EnvFilter, Registry,
};

pub struct TracingSubscriber {
crate_level: tracing::Level,
rust_log_fallback: String,
pretty: bool,
}

impl Default for TracingSubscriber {
fn default() -> Self {
Self {
crate_level: tracing::Level::DEBUG,
rust_log_fallback: "debug".into(),
pretty: false,
}
}
}

impl TracingSubscriber {
pub fn new() -> Self {
Self::default()
}

#[allow(unused)]
pub fn crate_level(mut self, value: tracing::Level) -> Self {
self.crate_level = value;
self
}

#[allow(unused)]
pub fn rust_log_fallback(mut self, value: impl AsRef<str>) -> Self {
self.rust_log_fallback = value.as_ref().into();
self
}

#[allow(unused)]
pub fn pretty(mut self, value: bool) -> Self {
self.pretty = value;
self
}

pub fn set_global_default(self) {
LogTracer::init().expect("Failed to set logger");
set_global_default(self.build()).expect("Failed to set subscriber");
}

fn build(self) -> Box<dyn Subscriber + Sync + Send> {
// depends on RUST_LOG env var
let env_filter = EnvFilter::try_from_default_env()
// if unset, use rust_log_fallback
.or_else(|_| EnvFilter::try_new(self.rust_log_fallback))
.expect("correct RUST_LOG");

let target_filter = filter::Targets::new()
.with_target("server", self.crate_level)
.with_target("hyper", tracing::Level::INFO)
.with_default(tracing::Level::TRACE);

// ugly
if self.pretty {
Box::new(
Registry::default().with(
tracing_subscriber::fmt::layer()
.pretty()
.with_filter(env_filter)
.with_filter(target_filter),
),
)
} else {
Box::new(
Registry::default().with(
tracing_subscriber::fmt::layer()
.with_filter(env_filter)
.with_filter(target_filter),
),
)
}
}
}

#[derive(Clone, Default)]
pub struct RequestIdProducer {
counter: std::sync::Arc<std::sync::atomic::AtomicU64>,
}

impl tower_http::request_id::MakeRequestId for RequestIdProducer {
fn make_request_id<B>(
&mut self,
_request: &hyper::http::Request<B>,
) -> Option<tower_http::request_id::RequestId> {
let request_id = self
.counter
.fetch_add(1, std::sync::atomic::Ordering::SeqCst)
.to_string()
.parse()
.unwrap();

Some(tower_http::request_id::RequestId::new(request_id))
}
}

pub fn request_trace_layer() -> tower::ServiceBuilder<
tower::layer::util::Stack<
tower_http::request_id::PropagateRequestIdLayer,
tower::layer::util::Stack<
tower_http::trace::TraceLayer<
tower_http::classify::SharedClassifier<
tower_http::classify::ServerErrorsAsFailures,
>,
impl Fn(&hyper::Request<hyper::Body>) -> tracing::Span + Clone,
>,
tower::layer::util::Stack<
tower_http::request_id::SetRequestIdLayer<RequestIdProducer>,
tower::layer::util::Identity,
>,
>,
>,
> {
pub use tower_http::{
trace::{DefaultMakeSpan, DefaultOnRequest, DefaultOnResponse},
LatencyUnit, ServiceBuilderExt,
};

tower::ServiceBuilder::new()
.set_x_request_id(RequestIdProducer::default())
.layer(
tower_http::trace::TraceLayer::new_for_http()
.make_span_with(DefaultMakeSpan::new().level(tracing::Level::DEBUG).include_headers(true))
.make_span_with(|request: &hyper::http::Request<hyper::Body>| {
tracing::debug_span!(
"request",
method = %request.method(),
uri = %request.uri(),
version = ?request.version(),
request_id = %request.headers().get("x-request-id").unwrap().to_str().unwrap(),
)
})
.on_request(DefaultOnRequest::new().level(tracing::Level::INFO))
.on_response(
DefaultOnResponse::new()
.level(tracing::Level::INFO)
.latency_unit(LatencyUnit::Seconds),
),
)
.propagate_x_request_id()
}

/// Spawns a blocking task in the scope of the current tracing span.
pub fn spawn_blocking_with_tracing<F, R>(f: F) -> tokio::task::JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let current_span = tracing::Span::current();
tokio::task::spawn_blocking(move || current_span.in_scope(f))
}
12 changes: 4 additions & 8 deletions backend/tests/app/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
use backend::conf;
use backend::startup::Application;
use backend::telemetry;
use backend::trace;
use hyper::StatusCode;
use once_cell::sync::Lazy;
use reqwest::{RequestBuilder, Response};
use static_routes::*;
use uuid::Uuid;

static TRACING: Lazy<()> = Lazy::new(|| {
let subscriber = telemetry::TracingSubscriber::new("testing");

if std::env::var("TEST_LOG").is_ok() {
telemetry::init_global_default(subscriber.build(std::io::stdout));
} else {
telemetry::init_global_default(subscriber.build(std::io::sink));
};
trace::TracingSubscriber::new()
.pretty(false)
.set_global_default();
});

pub async fn spawn_app() -> TestApp {
Expand Down

0 comments on commit 3e2105b

Please sign in to comment.