-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
This is an idea for quarkus-github-bot to build a report for any CI task that exceeds a configured time limit (let's say 4h).
Here is a sample implementation:
import java.io.BufferedReader;
import java.io.FileReader;
import java.time.Duration;
import java.time.Instant;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class GithubActionLogDelaysDetector {
record LineData(long durationSeconds, String lineContent){}
private static final Pattern TIMESTAMP_PATTERN =
Pattern.compile("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1,9}Z");
public static void main(String[] args) throws Exception {
String logFilePath = args[0];
Map<Integer, LineData> lineToData = new TreeMap<>();
try (var reader = new BufferedReader(new FileReader(logFilePath))) {
String line;
Instant previousTimestamp = null;
int previousLineNumber = 0;
int lineNumber = 0;
while ((line = reader.readLine()) != null) {
lineNumber++;
if (!TIMESTAMP_PATTERN.matcher(line).find()) {
continue; // Skip lines without a valid timestamp
}
// Extract and parse timestamp
String timestampStr = line.substring(0, line.indexOf('Z') + 1);
Instant currentTimestamp = Instant.parse(timestampStr);
String lineContent = line.substring(timestampStr.length()).trim(); // Extract content after timestamp
if (previousTimestamp != null && previousLineNumber > 0) {
// Calculate duration in seconds between consecutive valid lines
long durationSeconds = Duration.between(previousTimestamp, currentTimestamp).getSeconds();
lineToData.put(previousLineNumber, new LineData(durationSeconds, lineContent));
}
previousTimestamp = currentTimestamp;
previousLineNumber = lineNumber;
}
}
// Sort by duration, limit to 100, and print
Map<Integer, LineData> sortedMap = lineToData.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.comparingLong(LineData::durationSeconds).reversed()))
.limit(100)
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
// Print results
System.out.println("Line Number | Duration (seconds) | Line Content");
System.out.println("------------|--------------------|-------------");
sortedMap.forEach((lineNum, data) ->
System.out.printf("%11d | %18d | %s%n", lineNum, data.durationSeconds(), data.lineContent()));
}
}
Output Sample:
Line Number | Duration (seconds) | Line Content
------------|--------------------|-------------
76209 | 116 | 2025-06-24 10:16:05,712 INFO [tc.icr.io/.1.0.0] (build-11) Container icr.io/db2_community/db2:12.1.0.0 started in PT1M57.788383587S
63580 | 32 | [INFO]
10889 | 30 | 2025-06-24 08:53:25,840 INFO [io.quarkus] (main) quarkus-undertow-deployment stopped in 0.010s
63706 | 30 | 2025-06-24 10:11:20,063 INFO [tc.doc.io/gvenzl/oracle-free:23-slim-faststart] (build-4) Container docker.io/gvenzl/oracle-free:23-slim-faststart started in PT31.172087664S
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels