Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Added
* Add `--snapshot-to` CLI option for saving the current state snapshot to a file when pressing `d`

### Fixed

* Fix Ctrl+C handling to use SIGINT signal instead of keypress #491 - @chiranjeevi-max
Expand Down
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub struct Opt {
/// Enable debug logging to a file
pub log_to: Option<PathBuf>,

#[arg(long, value_hint = ValueHint::FilePath)]
/// Write a current-state snapshot to this file when the user presses 'd'
pub snapshot_to: Option<PathBuf>,

#[command(flatten)]
pub verbosity: Verbosity<InfoLevel>,

Expand Down
20 changes: 19 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ fn main() -> eyre::Result<()> {
)?;
}

let os_input = os::get_input(opts.interface.as_deref(), !opts.no_resolve, opts.dns_server)?;
let os_input = os::get_input(
opts.interface.as_deref(),
!opts.no_resolve,
opts.dns_server,
opts.snapshot_to.as_deref(),
)?;
if opts.raw {
let terminal_backend = RawTerminalBackend {};
start(terminal_backend, os_input, opts);
Expand Down Expand Up @@ -89,6 +94,7 @@ pub struct OsInputOutput {
pub terminal_events: Box<dyn Iterator<Item = Event> + Send>,
pub dns_client: Option<dns::Client>,
pub write_to_stdout: Box<dyn FnMut(&str) + Send>,
pub write_to_file: Option<Box<dyn FnMut(&str) + Send>>,
}

pub fn start<B>(terminal_backend: B, os_input: OsInputOutput, opts: Opt)
Expand Down Expand Up @@ -124,6 +130,8 @@ where
let network_utilization = Arc::new(Mutex::new(Utilization::new()));
let ui = Arc::new(Mutex::new(Ui::new(terminal_backend, &opts)));

let mut write_to_file = os_input.write_to_file;

let display_handler = thread::Builder::new()
.name("display_handler".to_string())
.spawn({
Expand Down Expand Up @@ -267,6 +275,16 @@ where
table_cycle_offset.store(new, Ordering::SeqCst);
ui.draw(paused, elapsed_time, new);
}
Event::Key(KeyEvent {
modifiers: KeyModifiers::NONE,
code: KeyCode::Char('d'),
kind: KeyEventKind::Press,
..
}) => {
if let Some(writer) = write_to_file.as_mut() {
ui.output_text(writer);
}
}
_ => (),
};
}
Expand Down
22 changes: 22 additions & 0 deletions src/os/shared.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::{
fs::OpenOptions,
io::{self, ErrorKind, Write},
net::Ipv4Addr,
path::Path,
time::{self, Duration},
};

Expand Down Expand Up @@ -105,10 +107,26 @@ fn create_write_to_stdout() -> Box<dyn FnMut(&str) + Send> {
})
}

pub fn create_write_to_file(path: &Path) -> eyre::Result<Box<dyn FnMut(&str) + Send>> {
let mut file = OpenOptions::new()
.create(true)
.append(true)
.open(path)
.map_err(|err| eyre!("Failed to open file in {path:?} due to {err}"))?;
let path = path.to_path_buf();

Ok(Box::new(move |output| {
if let Err(e) = writeln!(&mut file, "{output}") {
warn!("Failed to write dump to file {path:?}: {e}");
}
}))
}

pub fn get_input(
interface_name: Option<&str>,
resolve: bool,
dns_server: Option<Ipv4Addr>,
snapshot_path: Option<&Path>,
) -> eyre::Result<OsInputOutput> {
// get the user's requested interface, if any
// IDEA: allow requesting multiple interfaces
Expand Down Expand Up @@ -219,13 +237,17 @@ pub fn get_input(
};

let write_to_stdout = create_write_to_stdout();
let write_to_file = snapshot_path
.map(|path| create_write_to_file(path))
.transpose()?;

Ok(OsInputOutput {
interfaces_with_frames,
get_open_sockets,
terminal_events: Box::new(TerminalEvents),
dns_client,
write_to_stdout,
write_to_file,
})
}

Expand Down
1 change: 1 addition & 0 deletions src/tests/cases/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ pub fn os_input_output_factory(
terminal_events: keyboard_events,
dns_client,
write_to_stdout,
write_to_file: None,
}
}

Expand Down