Skip to content

Commit

Permalink
render events and objects from a trace
Browse files Browse the repository at this point in the history
  • Loading branch information
drmorr0 committed Sep 27, 2024
1 parent 6a9bc0c commit 354e34f
Show file tree
Hide file tree
Showing 11 changed files with 317 additions and 22 deletions.
58 changes: 54 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ anyhow = { version = "1.0.75", features = ["backtrace"] }
async-recursion = "1.0.5"
async-trait = "0.1.80"
bytes = "1.5.0"
chrono = "0.4.38"
clap = { version = "4.3.21", features = ["cargo", "derive", "string"] }
clap_complete = "4.5.6"
clockabilly = "0.1.0"
derive_setters = "0.1.6"
dirs = "5.0.1"
either = "1.12.0"
futures = "0.3.28"
Expand All @@ -42,6 +44,7 @@ object_store = { version = "0.11.0", features = ["aws", "gcp", "azure", "http"]
# remove this fork once https://github.com/uutils/parse_datetime/pull/80 is merged and a new version released
parse_datetime_fork = { version = "0.6.0-custom" }
paste = "1.0.14"
ratatui = "0.28.1"
regex = "1.10.2"
reqwest = { version = "0.11.18", default-features = false, features = ["json", "rustls-tls"] }
rmp-serde = "1.1.2"
Expand All @@ -64,7 +67,6 @@ hyper = "0.14.27"
mockall = "0.11.4"
rstest = "0.18.2"
tracing-test = "0.2.4"
ratatui = "0.28.1"

[workspace.dependencies.kube]
version = "0.85.0"
Expand Down
3 changes: 3 additions & 0 deletions sk-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ kube = { workspace = true }
k8s-openapi = { workspace = true }
reqwest = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
sk-api = { workspace = true }
sk-core = { workspace = true }
sk-store = { workspace = true }
tokio = { workspace = true }
ratatui = { workspace = true }
chrono = { workspace = true }
derive_setters = { workspace = true }

[dev-dependencies]
assertables = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions sk-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ enum SkSubcommand {
Version,

#[command(about = "explore or prepare trace data for simulation")]
Xray,
Xray(xray::Args),
}

#[tokio::main]
Expand All @@ -68,6 +68,6 @@ async fn main() -> EmptyResult {
println!("skctl {}", crate_version!());
Ok(())
},
SkSubcommand::Xray => xray::cmd(),
SkSubcommand::Xray(args) => xray::cmd(args).await,
}
}
11 changes: 9 additions & 2 deletions sk-cli/src/xray/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ use super::{

pub(super) fn handle_event(_model: &Model) -> anyhow::Result<Message> {
if let Event::Key(key) = read()? {
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
return Ok(Message::Quit);
if key.kind == KeyEventKind::Press {
return Ok(match key.code {
KeyCode::Char(' ') => Message::Select,
KeyCode::Down | KeyCode::Char('j') => Message::Down,
KeyCode::Esc => Message::Deselect,
KeyCode::Up | KeyCode::Char('k') => Message::Up,
KeyCode::Char('q') => Message::Quit,
_ => Message::Unknown,
});
}
}
Ok(Message::Unknown)
Expand Down
24 changes: 19 additions & 5 deletions sk-cli/src/xray/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
mod event;
mod model;
mod update;
mod util;
mod view;

use ratatui::backend::Backend;
use ratatui::Terminal;
use sk_core::external_storage::{
ObjectStoreWrapper,
SkObjectStore,
};
use sk_core::prelude::*;
use sk_store::TraceStore;

use self::event::handle_event;
use self::model::{
Expand All @@ -18,8 +24,18 @@ use self::update::{
};
use self::view::view;

pub fn cmd() -> EmptyResult {
let model = Model::new();
#[derive(clap::Args)]
pub struct Args {
#[arg(long_help = "location of the input trace file")]
pub trace_path: String,
}

pub async fn cmd(args: &Args) -> EmptyResult {
let object_store = SkObjectStore::new(&args.trace_path)?;
let trace_data = object_store.get().await?.to_vec();
let store = TraceStore::import(trace_data, &None)?;

let model = Model::new(&args.trace_path, store);
let term = ratatui::init();
let res = run_loop(term, model);
ratatui::restore();
Expand All @@ -28,10 +44,8 @@ pub fn cmd() -> EmptyResult {

fn run_loop<B: Backend>(mut term: Terminal<B>, mut model: Model) -> EmptyResult {
while model.app_state != ApplicationState::Done {
term.draw(|frame| view(&model, frame))?;

term.draw(|frame| view(&mut model, frame))?;
let msg: Message = handle_event(&model)?;

update(&mut model, msg);
}
Ok(())
Expand Down
32 changes: 30 additions & 2 deletions sk-cli/src/xray/model.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
use ratatui::widgets::ListState;
use sk_store::{
TraceEvent,
TraceStorable,
TraceStore,
};

#[derive(Eq, PartialEq)]
pub(super) enum ApplicationState {
Running,
Expand All @@ -6,10 +13,31 @@ pub(super) enum ApplicationState {

pub(super) struct Model {
pub(super) app_state: ApplicationState,
pub(super) base_trace: TraceStore,
pub(super) trace_path: String,
pub(super) events: Vec<TraceEvent>,

pub(super) event_list_state: ListState,
pub(super) object_list_state: ListState,
pub(super) object_contents_list_state: ListState,
pub(super) event_selected: bool,
pub(super) object_selected: bool,
}

impl Model {
pub(super) fn new() -> Model {
Model { app_state: ApplicationState::Running }
pub(super) fn new(trace_path: &str, base_trace: TraceStore) -> Model {
let events = base_trace.iter().map(|(evt, _)| evt).cloned().collect();
Model {
app_state: ApplicationState::Running,
base_trace,
trace_path: trace_path.into(),
events,

event_list_state: ListState::default().with_selected(Some(0)),
object_list_state: ListState::default(),
object_contents_list_state: ListState::default(),
event_selected: false,
object_selected: false,
}
}
}
33 changes: 33 additions & 0 deletions sk-cli/src/xray/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,46 @@ use super::{
};

pub(super) enum Message {
Deselect,
Down,
Quit,
Select,
Unknown,
Up,
}

pub(super) fn update(model: &mut Model, msg: Message) {
match msg {
Message::Deselect => {
if model.object_selected {
model.object_selected = false;
model.object_contents_list_state.select(None);
} else {
model.event_selected = false;
}
},
Message::Down => match (model.event_selected, model.object_selected) {
(true, true) => model.object_contents_list_state.select_next(),
(true, false) => model.object_list_state.select_next(),
(false, _) => model.event_list_state.select_next(),
},
Message::Quit => model.app_state = ApplicationState::Done,
Message::Select => match (model.event_selected, model.object_selected) {
(true, true) => (),
(true, false) => {
model.object_selected = true;
model.object_contents_list_state.select(Some(0));
},
(false, _) => {
model.event_selected = true;
model.object_list_state.select(Some(0));
},
},
Message::Unknown => (),
Message::Up => match (model.event_selected, model.object_selected) {
(true, true) => model.object_contents_list_state.select_previous(),
(true, false) => model.object_list_state.select_previous(),
(false, _) => model.event_list_state.select_previous(),
},
}
}
10 changes: 10 additions & 0 deletions sk-cli/src/xray/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use chrono::TimeDelta;

pub(super) fn format_duration(d: TimeDelta) -> String {
let day_str = match d.num_days() {
x if x > 0 => format!("{x}d "),
_ => String::new(),
};

format!("{}{:02}:{:02}:{:02}", day_str, d.num_hours() % 24, d.num_minutes() % 60, d.num_seconds() % 60)
}
Loading

0 comments on commit 354e34f

Please sign in to comment.