|
28 | 28 | r"(?P<timeslice>\d+)" |
29 | 29 | ) |
30 | 30 |
|
| 31 | +WORKFLOW_CRASH_RE = re.compile( |
| 32 | + r"\[ERROR\]\s*Workflow crashed\b.*?\bcode was set to\s*(?P<code>\d+)" |
| 33 | +) |
| 34 | + |
| 35 | +def find_workflow_crash_error_code(logfile: Path): |
| 36 | + error_codes = [] |
| 37 | + |
| 38 | + with logfile.open("r", errors="replace") as f: |
| 39 | + for line in f: |
| 40 | + match = WORKFLOW_CRASH_RE.search(line) |
| 41 | + if match: |
| 42 | + error_codes.append(int(match.group("code"))) |
| 43 | + |
| 44 | + return error_codes |
| 45 | + |
31 | 46 |
|
32 | 47 | def parse_hms_to_seconds(hms: str) -> float: |
33 | 48 | hhmmss, *frac = hms.split(".") |
@@ -472,6 +487,13 @@ def main(): |
472 | 487 | durations_by_timeslice, starts_by_timeslice, ends_by_timeslice = read_timeslice_durations( |
473 | 488 | args.logfile |
474 | 489 | ) |
| 490 | + |
| 491 | + workflow_crash_error_codes = find_workflow_crash_error_code(args.logfile) |
| 492 | + if workflow_crash_error_codes: |
| 493 | + print( |
| 494 | + f"{RED}{BOLD}Workflow crash error code(s) detected:{RESET} " |
| 495 | + f"{RED}{workflow_crash_error_codes}{RESET}" |
| 496 | + ) |
475 | 497 |
|
476 | 498 | excluded_timeslices, processing_sequences, wall_time_mean = analyze_processing_sequences( |
477 | 499 | starts_by_timeslice, |
@@ -643,6 +665,7 @@ def save_summary_output(output_file: Path, lines): |
643 | 665 |
|
644 | 666 | summary_lines = [ |
645 | 667 | f"Input file: {args.logfile}", |
| 668 | + f"Workflow crash error codes: {workflow_crash_error_codes if workflow_crash_error_codes else 'none'}", |
646 | 669 | f"Complete timeslices found: {n_total}", |
647 | 670 | f"Timeslices used after dropping first/last two: {n_used}", |
648 | 671 | f"First used timeslice: {trimmed_timeslices[0]}", |
|
0 commit comments