Skip to content

Commit

Permalink
show-job: add -s argument to show per-step times just like web UI
Browse files Browse the repository at this point in the history
Signed-off-by: Olof Johansson <[email protected]>
  • Loading branch information
olofj committed Dec 6, 2023
1 parent 34aced5 commit 9a9c3cc
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/commands/job_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub async fn job_history(
creds,
project,
pipelines,
Some(job_name),
Some(vec![job_name]),
Some(max_age),
None,
)
Expand Down
80 changes: 70 additions & 10 deletions src/commands/show_job.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::sync::Arc;

use anyhow::Result;
Expand Down Expand Up @@ -37,17 +38,76 @@ pub async fn show_job(
} else {
log
};
let skip = match args.tail {
Some(t) => log.lines().count().saturating_sub(t),
_ => 0,
};
for l in log.lines().skip(skip) {
let l = if args.prefix {
format!("{}: {}", job.name, l)
} else {
l.to_string()

if args.stats {
let mut starts = HashMap::new();

let mut level = 0;

let mut table = Table::new();
table.set_format(*format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
let titles = row!["Section", "Time", "Command"];
table.set_titles(titles);

let mut cursteps: Vec<_> = Vec::new();
let startidx: Vec<_> = log.match_indices("section_start:").collect();
let endidx: Vec<_> = log.match_indices("section_end:").collect();

for (idx, _) in itertools::merge(startidx, endidx) {
let sec = &log[idx..];
let mut f = sec.split(&[':', '\r', '\n'][..]);
match f.next() {
Some("section_start") => {
let stime = f.next().unwrap();
let stime = stime.parse::<usize>().unwrap();
let sstep = f.next().unwrap();
let scmd = f.next().unwrap_or("none");
let scmd = strip_ansi_escapes::strip_str(scmd);
starts.insert(sstep.to_string(), (stime, scmd.to_string()));
cursteps.push(sstep);
level += 1;
}
Some("section_end") => {
level -= 1;
cursteps.pop();
let stime = f.next().unwrap();
let stime = stime.parse::<usize>().unwrap();
let sstep = f.next().unwrap();
table.add_row(row![
" ".repeat(level) + sstep,
r->format_seconds((stime - starts[sstep].0) as f64),
starts[sstep].1
]);
}
None => {
while let Some(sstep) = cursteps.pop() {
table.add_row(row![
" ".repeat(level) + sstep,
"(running)",
starts[sstep].1
]);
level -= 1;
}
}
Some(s) => {
println!("Unknown section {}", s);
}
};
}
table.printstd();
} else {
let skip = match args.tail {
Some(t) => log.lines().count().saturating_sub(t),
_ => 0,
};
println!("{}", l);
for l in log.lines().skip(skip) {
let l = if args.prefix {
format!("{}: {}", job.name, l)
} else {
l.to_string()
};
println!("{}", l);
}
}
}

Expand Down
33 changes: 22 additions & 11 deletions src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async fn multifetch(
credentials: Credentials,
base_url: &str,
sem: &Arc<Semaphore>,
job_name: Option<&str>,
job_names: Option<Vec<&str>>,
max_age: isize,
) -> Result<Vec<Job>, anyhow::Error> {
let client = Client::new();
Expand All @@ -123,7 +123,6 @@ async fn multifetch(
.parse::<usize>()
.unwrap_or(1);


let oldest_valid_page = Arc::new(AtomicUsize::new(total_pages)); // Initialize with 1, assuming the first page is always valid
let fetched_pages = Arc::new(AtomicUsize::new(1));

Expand All @@ -134,9 +133,11 @@ async fn multifetch(
.filter(|j| {
let job_age = seconds_ago(&j.created_at.naive_utc());
if job_age > max_age {
oldest_valid_page.store(1, Ordering::Relaxed);
oldest_valid_page.store(1, Ordering::Relaxed);
}
job_name.map_or(true, |name| j.name == name)
job_names
.as_ref()
.map_or(true, |names| names.contains(&j.name.as_str()))
&& job_age <= max_age
})
.collect();
Expand All @@ -153,6 +154,7 @@ async fn multifetch(
let sem = sem.clone();
let oldest_valid_page = oldest_valid_page.clone();
let fetched_pages = fetched_pages.clone();
let job_names = job_names.clone();

async move {
let _permit = sem.acquire().await.unwrap();
Expand All @@ -165,10 +167,13 @@ async fn multifetch(
.get(&page_url)
.bearer_auth(&credentials.token)
.send()
.await
.unwrap();
.await;
if response.is_err() {
return Ok(Vec::new()); // Return empty vector if the call failed
}

let text = response
.unwrap()
.text()
.await
.map_err(Into::<anyhow::Error>::into)
Expand All @@ -183,7 +188,10 @@ async fn multifetch(
for job in jobs {
let job_age = seconds_ago(&job.created_at.naive_utc());
if job_age <= max_age {
if job_name == None || Some(job.name.as_str()) == job_name {
if job_names
.as_ref()
.map_or(true, |names| names.contains(&job.name.as_str()))
{
valid_jobs.push(job);
}
} else {
Expand Down Expand Up @@ -243,7 +251,7 @@ pub async fn find_jobs(
credentials: &Credentials,
project: &str,
pipelines: Vec<usize>,
job_name: Option<&str>,
job_names: Option<Vec<&str>>,
max_age: Option<isize>,
status: Option<String>,
) -> Result<Vec<Job>, anyhow::Error> {
Expand Down Expand Up @@ -276,12 +284,13 @@ pub async fn find_jobs(

let mut job_futures = Vec::new();

for (index, base_url) in base_urls.iter().enumerate() {
for (_index, base_url) in base_urls.iter().enumerate() {
let job_names = job_names.clone();
job_futures.push(multifetch(
credentials.clone(),
base_url,
&semaphore,
job_name,
job_names,
max_age,
));
}
Expand All @@ -290,7 +299,9 @@ pub async fn find_jobs(
let mut ret = Vec::new();
for mut jobs in jobs_results {
jobs.retain(|job| {
job_name.map_or(true, |name| job.name == name)
job_names
.as_ref()
.map_or(true, |names| names.contains(&job.name.as_str()))
&& seconds_ago(&job.created_at.naive_utc()) <= max_age
});
ret.extend(jobs);
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ pub struct ShowJobArgs {
/// Number of lines of output to show (negative number)
#[clap(short = 't', long = "tail")]
tail: Option<usize>,
/// Show per-section stats for job
#[clap(short = 's', long = "stats", action = ArgAction::SetTrue)]
stats: bool,
/// Show job prefix for every line of log
#[clap(long = "prefix")]
prefix: bool,
Expand Down

0 comments on commit 9a9c3cc

Please sign in to comment.