diff --git a/veilid-cli/Cargo.toml b/veilid-cli/Cargo.toml index f32e48c9..ee824b44 100644 --- a/veilid-cli/Cargo.toml +++ b/veilid-cli/Cargo.toml @@ -62,5 +62,7 @@ flume = { version = "^0", features = ["async"] } data-encoding = { version = "^2" } indent = { version = "0.1.1" } +chrono = "0.4.26" + [dev-dependencies] serial_test = "^2" diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index 0c401e38..13e6126d 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -2,6 +2,7 @@ use crate::command_processor::*; use crate::peers_table_view::*; use crate::settings::Settings; use crate::tools::*; +use async_tungstenite::tungstenite::http::header::STRICT_TRANSPORT_SECURITY; use crossbeam_channel::Sender; use cursive::align::*; use cursive::event::*; @@ -16,7 +17,11 @@ use cursive_flexi_logger_view::{CursiveLogWriter, FlexiLoggerView}; // use cursive_multiplex::*; use std::collections::{HashMap, VecDeque}; use std::io::Write; +use std::time::{SystemTime, UNIX_EPOCH}; use thiserror::Error; +use std::sync::atomic::{AtomicU64, Ordering}; +use chrono::{Datelike, Timelike}; + ////////////////////////////////////////////////////////////// /// struct Dirty { @@ -47,6 +52,10 @@ impl Dirty { pub type UICallback = Box; + + +static START_TIME: AtomicU64 = AtomicU64::new(0); + struct UIState { attachment_state: Dirty, public_internet_ready: Dirty, @@ -101,7 +110,6 @@ pub enum DumbError { impl UI { ///////////////////////////////////////////////////////////////////////////////////// // Private functions - fn command_processor(s: &mut Cursive) -> CommandProcessor { let inner = Self::inner(s); inner.cmdproc.as_ref().unwrap().clone() @@ -349,7 +357,7 @@ impl UI { cursive_flexi_logger_view::parse_lines_to_log( ColorStyle::primary().into(), - format!("> {}", text), + format!("> {} {}", UI::cli_ts(Self::get_start_time()) , text), ); match Self::run_command(s, text) { Ok(_) => {} @@ -357,7 +365,7 @@ impl UI { let color = *Self::inner_mut(s).log_colors.get(&Level::Error).unwrap(); cursive_flexi_logger_view::parse_lines_to_log( color.into(), - format!(" Error: {}", e), + format!(" {} Error: {}", UI::cli_ts(Self::get_start_time()), e) ); } } @@ -463,13 +471,13 @@ impl UI { let color = *Self::inner_mut(s).log_colors.get(&Level::Info).unwrap(); cursive_flexi_logger_view::parse_lines_to_log( color.into(), - format!(">> Copied: {}", text.as_ref()), + format!(">> {} Copied: {}", UI::cli_ts(Self::get_start_time()), text.as_ref()), ); } else { let color = *Self::inner_mut(s).log_colors.get(&Level::Warn).unwrap(); cursive_flexi_logger_view::parse_lines_to_log( color.into(), - ">> Could not copy to clipboard".to_string(), + format!(">> {} Could not copy to clipboard", UI::cli_ts(Self::get_start_time())) ); } } else { @@ -485,11 +493,13 @@ impl UI { .is_ok() && std::io::stdout().flush().is_ok() { - let color = *Self::inner_mut(s).log_colors.get(&Level::Info).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log( - color.into(), - format!(">> Copied: {}", text.as_ref()), - ); + if std::io::stdout().flush().is_ok() { + let color = *Self::inner_mut(s).log_colors.get(&Level::Info).unwrap(); + cursive_flexi_logger_view::parse_lines_to_log( + color.into(), + format!(">> {} Copied: {}", UI::cli_ts(Self::get_start_time()), text.as_ref()), + ); + } } } } @@ -778,12 +788,49 @@ impl UI { } } + + //////////////////////////////////////////////////////////////////////////// // Public functions + pub fn cli_ts(ts: u64) -> String { + //let ts = get_timestamp(); + + let now = chrono::DateTime::::from(SystemTime::now()); + let date = chrono::DateTime::::from(UNIX_EPOCH + Duration::from_micros(ts)); + + let show_year = now.year() != date.year(); + let show_month = show_year || now.month() != date.month(); + let show_date = show_month || now.day() != date.day(); + + if show_year || show_month || show_date { + UI::set_start_time(); + } + format!("{}{}", + if show_year || show_month || show_date { + format!("Day changed: {:04}/{:02}/{:02} \n",now.year(), now.month(), now.day()) + } else { + "".to_owned() + }, + format!("{:02}:{:02}:{:02}", + now.hour(), + now.minute(), + now.second() + )) + } + + pub fn set_start_time() { + START_TIME.store(get_timestamp(), Ordering::Relaxed) + } + + pub fn get_start_time() -> u64 { + START_TIME.load(Ordering::Relaxed) + } + pub fn new(node_log_scrollback: usize, settings: &Settings) -> (Self, UISender) { cursive_flexi_logger_view::resize(node_log_scrollback); + UI::set_start_time(); // Instantiate the cursive runnable let runnable = CursiveRunnable::new( || -> Result, Box> { @@ -938,6 +985,7 @@ impl UI { // pub fn run(&mut self) { // self.siv.run(); // } + } type CallbackSink = Box; @@ -1040,7 +1088,7 @@ impl UISender { { let inner = self.inner.lock(); let color = *inner.log_colors.get(&log_color).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log(color.into(), event); + cursive_flexi_logger_view::parse_lines_to_log(color.into(), format!("{}: {}", UI::cli_ts(UI::get_start_time()), event)); } let _ = self.cb_sink.send(Box::new(UI::update_cb)); }