refactor(logging): switch to env-based log format with HTTP tracing
- Replace tracing-bunyan-formatter with tracing-subscriber's built-in fmt layer - Default to compact human-readable format, JSON opt-in via RUST_LOG_FORMAT=json - Add tower-http TraceLayer for automatic HTTP request/response logging - Remove tracing-bunyan-formatter and tracing-log dependencies
This commit is contained in:
parent
fb7bc423b3
commit
06384265d3
4 changed files with 47 additions and 99 deletions
80
Cargo.lock
generated
80
Cargo.lock
generated
|
|
@ -417,9 +417,8 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower 0.4.13",
|
"tower 0.4.13",
|
||||||
"tower-cookies",
|
"tower-cookies",
|
||||||
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-bunyan-formatter",
|
|
||||||
"tracing-log 0.2.0",
|
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
|
@ -968,16 +967,6 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gethostname"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
|
|
@ -3004,6 +2993,7 @@ dependencies = [
|
||||||
"tower 0.5.2",
|
"tower 0.5.2",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3041,24 +3031,6 @@ dependencies = [
|
||||||
"syn 2.0.110",
|
"syn 2.0.110",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-bunyan-formatter"
|
|
||||||
version = "0.3.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2d637245a0d8774bd48df6482e086c59a8b5348a910c3b0579354045a9d82411"
|
|
||||||
dependencies = [
|
|
||||||
"ahash",
|
|
||||||
"gethostname",
|
|
||||||
"log",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"time",
|
|
||||||
"tracing",
|
|
||||||
"tracing-core",
|
|
||||||
"tracing-log 0.1.4",
|
|
||||||
"tracing-subscriber",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.36"
|
version = "0.1.36"
|
||||||
|
|
@ -3069,17 +3041,6 @@ dependencies = [
|
||||||
"valuable",
|
"valuable",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-log"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
"once_cell",
|
|
||||||
"tracing-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-log"
|
name = "tracing-log"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
@ -3091,6 +3052,16 @@ dependencies = [
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-serde"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-subscriber"
|
name = "tracing-subscriber"
|
||||||
version = "0.3.20"
|
version = "0.3.20"
|
||||||
|
|
@ -3101,12 +3072,15 @@ dependencies = [
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log 0.2.0",
|
"tracing-log",
|
||||||
|
"tracing-serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3466,28 +3440,6 @@ dependencies = [
|
||||||
"wasite",
|
"wasite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.62.2"
|
version = "0.62.2"
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,11 @@ sqlx = { version = "0.7", default-features = false, features = [
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1.38", features = ["rt-multi-thread", "macros", "signal"] }
|
tokio = { version = "1.38", features = ["rt-multi-thread", "macros", "signal"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "json", "fmt"] }
|
||||||
tower = "0.4"
|
tower = "0.4"
|
||||||
tower-cookies = "0.10"
|
tower-cookies = "0.10"
|
||||||
|
tower-http = { version = "0.6", features = ["trace"] }
|
||||||
slug = "0.1.6"
|
slug = "0.1.6"
|
||||||
tracing-bunyan-formatter = "0.3.10"
|
|
||||||
tracing-log = "0.2.0"
|
|
||||||
url = "2"
|
url = "2"
|
||||||
uuid = { version = "1", features = ["v4"] }
|
uuid = { version = "1", features = ["v4"] }
|
||||||
webauthn-rs = { version = "0.5", features = ["danger-allow-state-serialisation"] }
|
webauthn-rs = { version = "0.5", features = ["danger-allow-state-serialisation"] }
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ use axum::response::{Html, IntoResponse, Redirect};
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use tower::ServiceBuilder;
|
use tower::ServiceBuilder;
|
||||||
use tower_cookies::CookieManagerLayer;
|
use tower_cookies::CookieManagerLayer;
|
||||||
|
use tower_http::trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer};
|
||||||
|
use tracing::Level;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::application::server::AppState;
|
use crate::application::server::AppState;
|
||||||
|
|
@ -138,7 +140,15 @@ pub fn app_router(state: AppState) -> axum::Router {
|
||||||
.route("/favicon.ico", get(favicon))
|
.route("/favicon.ico", get(favicon))
|
||||||
.nest("/api/v1", api_routes)
|
.nest("/api/v1", api_routes)
|
||||||
.nest("/api/v1/webauthn", webauthn_routes)
|
.nest("/api/v1/webauthn", webauthn_routes)
|
||||||
.layer(ServiceBuilder::new().layer(CookieManagerLayer::new()))
|
.layer(
|
||||||
|
ServiceBuilder::new()
|
||||||
|
.layer(
|
||||||
|
TraceLayer::new_for_http()
|
||||||
|
.make_span_with(DefaultMakeSpan::new().level(Level::INFO))
|
||||||
|
.on_response(DefaultOnResponse::new().level(Level::INFO)),
|
||||||
|
)
|
||||||
|
.layer(CookieManagerLayer::new()),
|
||||||
|
)
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
49
src/main.rs
49
src/main.rs
|
|
@ -6,19 +6,14 @@ use brewlog::presentation::cli::{
|
||||||
Cli, Commands, ServeCommand, bags, brews, cafes, cups, gear, roasters, roasts, tokens,
|
Cli, Commands, ServeCommand, bags, brews, cafes, cups, gear, roasters, roasts, tokens,
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use tracing::{Subscriber, subscriber::set_global_default};
|
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
|
||||||
use tracing_log::LogTracer;
|
|
||||||
use tracing_subscriber::fmt::MakeWriter;
|
|
||||||
use tracing_subscriber::{EnvFilter, Registry, layer::SubscriberExt};
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
// Load .env file if present (before clap parses env vars)
|
// Load .env file if present (before clap parses env vars)
|
||||||
let _ = dotenvy::dotenv();
|
let _ = dotenvy::dotenv();
|
||||||
|
|
||||||
let subscriber = get_subscriber("brewlog".into(), "info".into(), std::io::stdout);
|
init_tracing();
|
||||||
init_subscriber(subscriber);
|
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
|
@ -116,29 +111,21 @@ async fn run_server(command: ServeCommand) -> Result<()> {
|
||||||
serve(config).await
|
serve(config).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_subscriber<Sink>(
|
|
||||||
name: String,
|
|
||||||
env_filter: String,
|
|
||||||
sink: Sink,
|
|
||||||
) -> impl Subscriber + Send + Sync
|
|
||||||
where
|
|
||||||
Sink: for<'a> MakeWriter<'a> + Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
let env_filter =
|
|
||||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(env_filter));
|
|
||||||
let formatting_layer = BunyanFormattingLayer::new(name, sink);
|
|
||||||
|
|
||||||
Registry::default()
|
|
||||||
.with(env_filter)
|
|
||||||
.with(JsonStorageLayer)
|
|
||||||
.with(formatting_layer)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a subscriber as global default to process span data.
|
|
||||||
///
|
|
||||||
/// This should only be called once!
|
|
||||||
#[allow(clippy::expect_used)] // Startup: panicking is appropriate if logging cannot be initialized
|
#[allow(clippy::expect_used)] // Startup: panicking is appropriate if logging cannot be initialized
|
||||||
pub fn init_subscriber(subscriber: impl Subscriber + Send + Sync) {
|
fn init_tracing() {
|
||||||
LogTracer::init().expect("Failed to set logger");
|
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
||||||
set_global_default(subscriber).expect("Failed to set subscriber");
|
|
||||||
|
let use_json = std::env::var("RUST_LOG_FORMAT").is_ok_and(|v| v.eq_ignore_ascii_case("json"));
|
||||||
|
|
||||||
|
let registry = tracing_subscriber::registry().with(env_filter);
|
||||||
|
|
||||||
|
if use_json {
|
||||||
|
registry
|
||||||
|
.with(tracing_subscriber::fmt::layer().json())
|
||||||
|
.init();
|
||||||
|
} else {
|
||||||
|
registry
|
||||||
|
.with(tracing_subscriber::fmt::layer().compact())
|
||||||
|
.init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue