diff --git a/Cargo.lock b/Cargo.lock index 1df5f02..88844d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4977,6 +4977,16 @@ dependencies = [ "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]] name = "tracing-subscriber" version = "0.3.23" @@ -4984,11 +4994,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "nu-ansi-term", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] diff --git a/apt2aptly/Cargo.toml b/apt2aptly/Cargo.toml index 6f1b671..3d0c2ad 100644 --- a/apt2aptly/Cargo.toml +++ b/apt2aptly/Cargo.toml @@ -19,5 +19,5 @@ sync2aptly = { path = "../sync2aptly" } tokio = { version = "1.45.1", features = ["full"] } tracing = "0.1.41" tracing-error = "0.2.1" -tracing-subscriber = "0.3.20" +tracing-subscriber = { version = "0.3.20", features = ["json"] } url = "2.5.4" diff --git a/apt2aptly/src/main.rs b/apt2aptly/src/main.rs index 41ee524..4d7c56f 100644 --- a/apt2aptly/src/main.rs +++ b/apt2aptly/src/main.rs @@ -9,7 +9,7 @@ use aptly_rest::{ api::{publish, repos, snapshots::DeleteOptions}, AptlyRest, AptlyRestError, }; -use clap::{builder::ArgPredicate, Parser}; +use clap::{builder::ArgPredicate, Parser, ValueEnum}; use color_eyre::{ eyre::{bail, ensure, Context}, Result, @@ -23,6 +23,13 @@ use tracing_error::ErrorLayer; use tracing_subscriber::prelude::*; use url::Url; +#[derive(ValueEnum, Clone, Copy, Debug, Default)] +enum LogFormat { + #[default] + Pretty, + Json, +} + #[derive(Parser, Debug)] struct Opts { /// Url for the aptly rest api endpoint @@ -86,6 +93,9 @@ struct Opts { /// Only show changes, don't apply them #[clap(short = 'n', long, default_value_t = false)] dry_run: bool, + /// Log output format + #[clap(long, value_enum, default_value_t = LogFormat::Pretty)] + log_format: LogFormat, } const TEMPLATE_VAR_COMPONENT: &str = "component"; @@ -472,14 +482,29 @@ async fn sync_dist( Ok(()) } +fn init_tracing(format: LogFormat) { + match format { + LogFormat::Pretty => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) + .init(), + LogFormat::Json => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with( + tracing_subscriber::fmt::layer() + .json() + .with_filter(LevelFilter::INFO), + ) + .init(), + } +} + #[tokio::main] async fn main() -> Result<()> { - tracing_subscriber::registry() - .with(ErrorLayer::default()) - .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) - .init(); - color_eyre::install().unwrap(); let opts = Opts::parse(); + init_tracing(opts.log_format); + color_eyre::install()?; + let aptly = if let Some(token) = &opts.api_token { AptlyRest::new_with_token(opts.api_url.clone(), token)? } else { diff --git a/aptly-latest-snapshots/Cargo.toml b/aptly-latest-snapshots/Cargo.toml index 2714c08..3e19fec 100644 --- a/aptly-latest-snapshots/Cargo.toml +++ b/aptly-latest-snapshots/Cargo.toml @@ -17,7 +17,7 @@ thiserror = "2.0.12" tokio = { version = "1.45.1", features = ["full"] } tracing = "0.1.41" tracing-error = "0.2.1" -tracing-subscriber = "0.3.20" +tracing-subscriber = { version = "0.3.20", features = ["json"] } url = "2.5.4" [dev-dependencies] diff --git a/aptly-latest-snapshots/src/main.rs b/aptly-latest-snapshots/src/main.rs index e9f5ce6..d7681c3 100644 --- a/aptly-latest-snapshots/src/main.rs +++ b/aptly-latest-snapshots/src/main.rs @@ -2,13 +2,20 @@ use std::{net::SocketAddr, time::Duration}; use aptly_latest_snapshots::{create_app, periodic_snapshot_refresh, AppState}; use aptly_rest::AptlyRest; -use clap::Parser; +use clap::{Parser, ValueEnum}; use color_eyre::{eyre::WrapErr, Result}; use tracing::info; use tracing::metadata::LevelFilter; use tracing_error::ErrorLayer; use tracing_subscriber::prelude::*; +#[derive(ValueEnum, Clone, Copy, Debug, Default)] +enum LogFormat { + #[default] + Pretty, + Json, +} + #[derive(Parser, Debug)] struct Opts { /// Url for the aptly rest api endpoint @@ -31,17 +38,34 @@ struct Opts { default_value_t = 600, value_parser = clap::value_parser!(u16).range(1..))] refresh_interval_sec: u16, + /// Log output format + #[clap(long, value_enum, default_value_t = LogFormat::Pretty)] + log_format: LogFormat, +} + +fn init_tracing(format: LogFormat) { + match format { + LogFormat::Pretty => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) + .init(), + LogFormat::Json => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with( + tracing_subscriber::fmt::layer() + .json() + .with_filter(LevelFilter::INFO), + ) + .init(), + } } #[tokio::main] async fn main() -> Result<()> { - tracing_subscriber::registry() - .with(ErrorLayer::default()) - .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) - .init(); - color_eyre::install().unwrap(); - let opts = Opts::parse(); + init_tracing(opts.log_format); + color_eyre::install()?; + let aptly = if let Some(token) = &opts.api_token { AptlyRest::new_with_token(opts.api_url.clone(), token)? } else { diff --git a/aptlyctl/Cargo.toml b/aptlyctl/Cargo.toml index 95569e7..b1003f0 100644 --- a/aptlyctl/Cargo.toml +++ b/aptlyctl/Cargo.toml @@ -17,5 +17,5 @@ serde-saphyr = "0.0.27" tokio = { version = "1.45.1", features = ["full"] } tracing = "0.1.41" tracing-error = "0.2.1" -tracing-subscriber = "0.3.20" +tracing-subscriber = { version = "0.3.20", features = ["json"] } url = "2.5.4" diff --git a/aptlyctl/src/main.rs b/aptlyctl/src/main.rs index e37b8de..53de1a6 100644 --- a/aptlyctl/src/main.rs +++ b/aptlyctl/src/main.rs @@ -24,6 +24,13 @@ enum OutputFormat { Yaml, } +#[derive(ValueEnum, Clone, Copy, Debug, Default)] +enum LogFormat { + #[default] + Pretty, + Json, +} + #[derive(Subcommand, Debug)] enum Command { Repo { @@ -60,16 +67,34 @@ struct Opts { /// Authentication token for the API #[clap(long, env = "APTLY_API_TOKEN")] api_token: Option, + /// Log output format + #[clap(long, value_enum, default_value_t = LogFormat::Pretty)] + log_format: LogFormat, +} + +fn init_tracing(format: LogFormat) { + match format { + LogFormat::Pretty => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) + .init(), + LogFormat::Json => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with( + tracing_subscriber::fmt::layer() + .json() + .with_filter(LevelFilter::INFO), + ) + .init(), + } } #[tokio::main] async fn main() -> Result { - tracing_subscriber::registry() - .with(ErrorLayer::default()) - .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) - .init(); - color_eyre::install().unwrap(); let opts = Opts::parse(); + init_tracing(opts.log_format); + color_eyre::install()?; + let aptly = if let Some(token) = opts.api_token { AptlyRest::new_with_token(opts.api_url, &token)? } else { diff --git a/obs2aptly/Cargo.toml b/obs2aptly/Cargo.toml index 1619a6c..1c5cd4b 100644 --- a/obs2aptly/Cargo.toml +++ b/obs2aptly/Cargo.toml @@ -18,7 +18,7 @@ sync2aptly = { path = "../sync2aptly" } tokio = { version = "1.45.1", features = ["full"] } tracing = "0.1.41" tracing-error = "0.2.1" -tracing-subscriber = "0.3.20" +tracing-subscriber = { version = "0.3.20", features = ["json"] } url = "2.5.4" [dev-dependencies] diff --git a/obs2aptly/src/main.rs b/obs2aptly/src/main.rs index 8444c77..c5c03bf 100644 --- a/obs2aptly/src/main.rs +++ b/obs2aptly/src/main.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use aptly_rest::AptlyRest; -use clap::Parser; +use clap::{Parser, ValueEnum}; use color_eyre::Result; use sync2aptly::{AptlyContent, PoolPackagesCache, UploadOptions}; use tracing::metadata::LevelFilter; @@ -14,6 +14,13 @@ enum FilterKind { Binaries, } +#[derive(ValueEnum, Clone, Copy, Debug, Default)] +enum LogFormat { + #[default] + Pretty, + Json, +} + #[derive(Parser, Debug)] struct Opts { /// Url for the aptly rest api endpoint @@ -40,16 +47,34 @@ struct Opts { /// Only show changes, don't apply them #[clap(short = 'n', long, default_value_t = false)] dry_run: bool, + /// Log output format + #[clap(long, value_enum, default_value_t = LogFormat::Pretty)] + log_format: LogFormat, +} + +fn init_tracing(format: LogFormat) { + match format { + LogFormat::Pretty => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) + .init(), + LogFormat::Json => tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with( + tracing_subscriber::fmt::layer() + .json() + .with_filter(LevelFilter::INFO), + ) + .init(), + } } #[tokio::main] async fn main() -> Result<()> { - tracing_subscriber::registry() - .with(ErrorLayer::default()) - .with(tracing_subscriber::fmt::layer().with_filter(LevelFilter::INFO)) - .init(); - color_eyre::install().unwrap(); let opts = Opts::parse(); + init_tracing(opts.log_format); + color_eyre::install()?; + let aptly = if let Some(token) = opts.api_token { AptlyRest::new_with_token(opts.api_url, &token)? } else {