From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 2F0C71FF0E1 for ; Mon, 13 Jul 2026 10:16:28 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 0165A21429; Mon, 13 Jul 2026 10:16:28 +0200 (CEST) From: Shan Shaji To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup 6/6] fix #7024: cli: add option to enable verbose logs Date: Mon, 13 Jul 2026 10:15:29 +0200 Message-ID: <20260713081529.62859-7-s.shaji@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260713081529.62859-1-s.shaji@proxmox.com> References: <20260713081529.62859-1-s.shaji@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1783930529658 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.281 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: LVO2P2FOJFN4JEWNA3KUB5C66LSFT2UR X-Message-ID-Hash: LVO2P2FOJFN4JEWNA3KUB5C66LSFT2UR X-MailFrom: s.shaji@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: earlier, there was no option to enable verbose logging inside the CLI. By default only info level logs were only logged. To get more information, users had to enable debug logs by setting the PBS_LOG environment variable, but that was too much information. To fix this, accept a verbose option and log only necessary information in info level when the flag is set as true. Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=7024 Signed-off-by: Shan Shaji --- pbs-client/src/backup_writer.rs | 9 +++--- pbs-client/src/pxar/create.rs | 30 ++++++++++++++++--- pbs-client/src/pxar/tools.rs | 9 +++++- proxmox-backup-client/src/main.rs | 12 ++++++++ .../src/proxmox_restore_daemon/api.rs | 1 + pxar-bin/src/main.rs | 1 + 6 files changed, 53 insertions(+), 9 deletions(-) diff --git a/pbs-client/src/backup_writer.rs b/pbs-client/src/backup_writer.rs index 8ae0cffe8..bf5a1a491 100644 --- a/pbs-client/src/backup_writer.rs +++ b/pbs-client/src/backup_writer.rs @@ -55,6 +55,7 @@ pub struct UploadOptions { pub encrypt: bool, pub index_type: IndexType, pub progress_logging_callback: Option>, + pub verbose: bool, } /// Index type for upload options. @@ -520,17 +521,17 @@ impl BackupWriter { archive, reused, reused_percent ); } - if enabled!(Level::DEBUG) && upload_stats.chunk_count > 0 { - debug!( + if options.verbose && upload_stats.chunk_count > 0 { + info!( "{}: Reused {} from {} chunks.", archive, upload_stats.chunk_reused, upload_stats.chunk_count ); - debug!( + info!( "{}: Average chunk size was {}.", archive, HumanByte::from(upload_stats.size / upload_stats.chunk_count) ); - debug!( + info!( "{}: Average time per request: {} microseconds.", archive, (upload_stats.duration.as_micros()) / (upload_stats.chunk_count as u128) diff --git a/pbs-client/src/pxar/create.rs b/pbs-client/src/pxar/create.rs index 7012a88dd..308bd20c0 100644 --- a/pbs-client/src/pxar/create.rs +++ b/pbs-client/src/pxar/create.rs @@ -39,7 +39,7 @@ use crate::inject_reused_chunks::InjectChunks; use crate::pxar::Flags; use crate::pxar::look_ahead_cache::{CacheEntry, CacheEntryData, PxarLookaheadCache}; use crate::pxar::metadata::errno_is_unsupported; -use crate::pxar::tools::assert_single_path_component; +use crate::pxar::tools::{assert_single_path_component, log_message}; const CHUNK_PADDING_THRESHOLD: f64 = 0.1; @@ -60,6 +60,8 @@ pub struct PxarCreateOptions { pub previous_ref: Option, /// Maximum number of lookahead cache entries pub max_cache_size: Option, + /// Enable verbose logging + pub verbose: bool, } pub type MetadataArchiveReader = Arc; @@ -271,6 +273,7 @@ struct Archiver { last_reusable_offset: Option, progress_stats: Arc, split_archive: bool, + verbose: bool, } type Encoder<'a, T> = pxar::encoder::aio::Encoder<'a, T>; @@ -383,6 +386,7 @@ where last_reusable_offset: None, progress_stats: archiver_progress_stats.unwrap_or_default(), split_archive, + verbose: options.verbose, }; archiver @@ -549,18 +553,35 @@ impl Archiver { } let range = *offset..*offset + size + size_of::() as u64; + + if self.verbose { + info!("reusable: {file_name:?}"); + } + debug!( "reusable: {file_name:?} at range {range:?} has unchanged metadata." ); return Ok(Some(range)); } - debug!("re-encode: {file_name:?} not a regular file."); + + log_message( + &format!("re-encode: {file_name:?} not a regular file."), + self.verbose, + ); return Ok(None); } - debug!("re-encode: {file_name:?} metadata did not match."); + + log_message( + &format!("re-encode: {file_name:?} metadata did not match."), + self.verbose, + ); return Ok(None); } - debug!("re-encode: {file_name:?} not found in previous archive."); + + log_message( + &format!("re-encode: {file_name:?} not found in previous archive."), + self.verbose, + ); } Ok(None) @@ -2147,6 +2168,7 @@ mod tests { last_reusable_offset: None, progress_stats: Arc::new(PxarArchiverProgressStats::default()), split_archive: true, + verbose: false, }; let accessor = Accessor::new(pxar::PxarVariant::Unified(reader), metadata_size) diff --git a/pbs-client/src/pxar/tools.rs b/pbs-client/src/pxar/tools.rs index 0c8c2927e..3201ffd2d 100644 --- a/pbs-client/src/pxar/tools.rs +++ b/pbs-client/src/pxar/tools.rs @@ -9,6 +9,8 @@ use anyhow::{Context, Error, bail, format_err}; use nix::sys::stat::Mode; use pathpatterns::MatchType; + +use proxmox_log::{debug, info}; use pxar::accessor::ReadAt; use pxar::accessor::aio::{Accessor, Directory, FileEntry}; use pxar::format::StatxTimestamp; @@ -21,7 +23,6 @@ use pbs_datastore::BackupManifest; use pbs_datastore::dynamic_index::{BufferedDynamicReader, LocalDynamicReadAt}; use pbs_datastore::index::IndexFile; use pbs_tools::crypt_config::CryptConfig; -use proxmox_log::{debug, info}; use crate::{BackupReader, RemoteChunkReader}; @@ -485,3 +486,9 @@ pub async fn pxar_metadata_catalog_find<'future, T: Clone + Send + Sync + ReadAt } Ok(()) } + +pub(crate) fn log_message(msg: &str, verbose: bool) { + if verbose { + info!("{msg}"); + } +} diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs index 8ce5540d5..368338699 100644 --- a/proxmox-backup-client/src/main.rs +++ b/proxmox-backup-client/src/main.rs @@ -18,6 +18,7 @@ use pathpatterns::{MatchEntry, MatchType, PatternFlag}; use proxmox_async::blocking::TokioWriterAdapter; use proxmox_human_byte::HumanByte; use proxmox_io::StdChannelWriter; +use proxmox_log::{Level, enabled}; use proxmox_router::{ApiMethod, RpcEnvironment, cli::*}; use proxmox_schema::api; use proxmox_sys::fs::{CreateOptions, file_get_json, image_size, replace_file}; @@ -828,6 +829,12 @@ fn spawn_catalog_upload( optional: true, default: false, }, + "verbose": { + type: Boolean, + description: "Enable verbose logs.", + optional: true, + default: false, + } } } )] @@ -871,6 +878,8 @@ async fn create_backup( let include_dev = param["include-dev"].as_array(); + let verbose = param["verbose"].as_bool().unwrap_or_default() || enabled!(Level::DEBUG); + let entries_max = param["entries-max"] .as_u64() .unwrap_or(pbs_client::pxar::ENCODER_MAX_ENTRIES as u64); @@ -1268,12 +1277,14 @@ async fn create_backup( skip_e2big_xattr, previous_ref, max_cache_size, + verbose: verbose, }; let upload_options = UploadOptions { previous_manifest: previous_manifest.clone(), compress: true, encrypt: crypto.mode == CryptMode::Encrypt, + verbose, ..UploadOptions::default() }; @@ -1321,6 +1332,7 @@ async fn create_backup( compress: true, encrypt: crypto.mode == CryptMode::Encrypt, progress_logging_callback: Some(Arc::new(Box::new(progress_logger))), + verbose, ..UploadOptions::default() }; diff --git a/proxmox-restore-daemon/src/proxmox_restore_daemon/api.rs b/proxmox-restore-daemon/src/proxmox_restore_daemon/api.rs index b7f4fd141..e890681fc 100644 --- a/proxmox-restore-daemon/src/proxmox_restore_daemon/api.rs +++ b/proxmox-restore-daemon/src/proxmox_restore_daemon/api.rs @@ -364,6 +364,7 @@ fn extract( skip_e2big_xattr: false, previous_ref: None, max_cache_size: None, + verbose: false }; let pxar_writer = pxar::PxarVariant::Unified(TokioWriter::new(writer)); diff --git a/pxar-bin/src/main.rs b/pxar-bin/src/main.rs index 953c6e756..385f54a0d 100644 --- a/pxar-bin/src/main.rs +++ b/pxar-bin/src/main.rs @@ -383,6 +383,7 @@ async fn create_archive( skip_e2big_xattr: false, previous_ref: None, max_cache_size: None, + verbose: false, }; let source = PathBuf::from(source); -- 2.47.3