feat: add -v/-vv verbosity flags and trace-level hex dumps
Add clap CLI argument parsing with three log-level controls: -q/--quiet errors only (default) info — connections and value changes -v debug — every packet's cmd/src/flags logged on TX and RX -vv trace — full 32-byte hex dump of every packet on the wire RUST_LOG env var continues to work as a fine-grained override for any of the above levels. Also expand the TX log line to include src and flags fields to match the RX line, making the two symmetric.
This commit is contained in:
+6
-5
@@ -10,8 +10,9 @@ name = "qmk-host"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
hidapi = "2" # Cross-platform Raw HID access
|
||||
anyhow = "1" # Ergonomic error handling
|
||||
log = "0.4" # Logging facade
|
||||
env_logger = "0.11" # Logger implementation (RUST_LOG env var)
|
||||
ctrlc = "3" # Ctrl+C / SIGINT handler
|
||||
hidapi = "2" # Cross-platform Raw HID access
|
||||
anyhow = "1" # Ergonomic error handling
|
||||
log = "0.4" # Logging facade
|
||||
env_logger = "0.11" # Logger implementation (RUST_LOG env var)
|
||||
ctrlc = "3" # Ctrl+C / SIGINT handler
|
||||
clap = { version = "4", features = ["derive"] } # CLI argument parsing
|
||||
|
||||
+9
-3
@@ -15,7 +15,7 @@ use std::time::Duration;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use hidapi::HidApi;
|
||||
use log::{debug, error, info, warn};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
use crate::protocol::{Packet, PACKET_SIZE, USAGE_ID, USAGE_PAGE};
|
||||
|
||||
@@ -122,10 +122,14 @@ fn io_loop(
|
||||
// --- Drain the outgoing write queue (non-blocking) -----------------
|
||||
while let Ok(pkt) = rx.try_recv() {
|
||||
write_buf[1..].copy_from_slice(&pkt.0);
|
||||
trace!("[kbd {:02x}] TX {:02x?}", device_id, &write_buf[1..]);
|
||||
if let Err(e) = device.write(&write_buf) {
|
||||
error!("[kbd {:02x}] write error: {}", device_id, e);
|
||||
} else {
|
||||
debug!("[kbd {:02x}] sent cmd=0x{:02x}", device_id, pkt.cmd());
|
||||
debug!(
|
||||
"[kbd {:02x}] TX cmd=0x{:02x} src=0x{:02x} flags=0x{:02x}",
|
||||
device_id, pkt.cmd(), pkt.src(), pkt.flags()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,11 +140,13 @@ fn io_loop(
|
||||
}
|
||||
Ok(_n) => {
|
||||
let pkt = Packet(read_buf);
|
||||
trace!("[kbd {:02x}] RX {:02x?}", device_id, &read_buf[..]);
|
||||
if pkt.is_custom() {
|
||||
debug!(
|
||||
"[kbd {:02x}] received cmd=0x{:02x} flags=0x{:02x}",
|
||||
"[kbd {:02x}] RX cmd=0x{:02x} src=0x{:02x} flags=0x{:02x}",
|
||||
device_id,
|
||||
pkt.cmd(),
|
||||
pkt.src(),
|
||||
pkt.flags()
|
||||
);
|
||||
if to_broker.send((device_id, pkt)).is_err() {
|
||||
|
||||
+58
-3
@@ -16,7 +16,11 @@
|
||||
//! # Usage
|
||||
//!
|
||||
//! ```
|
||||
//! RUST_LOG=debug qmk-host
|
||||
//! qmk-host # info-level output (connections, value changes)
|
||||
//! qmk-host -v # debug-level: log every packet cmd/src/flags
|
||||
//! qmk-host -vv # trace-level: full 32-byte hex dump of every packet
|
||||
//! qmk-host -q # quiet: errors only
|
||||
//! RUST_LOG=debug qmk-host # env var still works as an override
|
||||
//! ```
|
||||
//!
|
||||
//! # Permissions
|
||||
@@ -36,6 +40,7 @@ use std::sync::mpsc;
|
||||
use std::thread;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Parser;
|
||||
use log::{error, info, warn};
|
||||
|
||||
mod app_monitor;
|
||||
@@ -47,9 +52,59 @@ mod volume;
|
||||
|
||||
use protocol::{DEV_HOST, Packet};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CLI
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Raw HID bridge for QMK keyboards.
|
||||
///
|
||||
/// Syncs layer state between keyboards and delivers host data (volume,
|
||||
/// brightness) via the QMK raw-HID interface.
|
||||
#[derive(Parser)]
|
||||
#[command(name = "qmk-host", version)]
|
||||
struct Args {
|
||||
/// Increase log verbosity.
|
||||
///
|
||||
/// Pass once (-v) for debug output (every packet's command, source and
|
||||
/// flags). Pass twice (-vv) for trace output (full 32-byte hex dump of
|
||||
/// every packet sent and received). The RUST_LOG environment variable
|
||||
/// still overrides this flag when set.
|
||||
#[arg(short, long, action = clap::ArgAction::Count)]
|
||||
verbose: u8,
|
||||
|
||||
/// Suppress all output except errors.
|
||||
#[arg(short, long)]
|
||||
quiet: bool,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
/// Resolve the effective log-level filter string from the CLI flags.
|
||||
/// The caller passes this to `env_logger` as the default; `RUST_LOG`
|
||||
/// will still override it if set.
|
||||
fn log_level(&self) -> &'static str {
|
||||
if self.quiet {
|
||||
"error"
|
||||
} else {
|
||||
match self.verbose {
|
||||
0 => "info",
|
||||
1 => "debug",
|
||||
_ => "trace",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Entry point
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Initialise logging. Set RUST_LOG=debug for verbose output.
|
||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
||||
let args = Args::parse();
|
||||
|
||||
env_logger::Builder::from_env(
|
||||
env_logger::Env::default().default_filter_or(args.log_level()),
|
||||
)
|
||||
.init();
|
||||
|
||||
info!("qmk-host starting");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user