← All tasks
javaclaude-code/java-t2 #29Verified, not scored yet

Network Latency Monitor (java, written by Claude Code)

envgap__claude-code__java-t2-29

Written by a coding agent; not on GitHubWritten 2026-02-27

01 / FAILURE SIGNATURE

As the study recorded it

No src directory - Java file in project root
Not scored yet.
  • The failure reproduces in a clean container and the known fix makes the project run; it has not been scored yet.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
pom.xml
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

claude-code/java-t2 #29 · read the task the agent was given
Claude Code wrote this java project from the task below. It does not run on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: Network Latency Monitor

Write a program that continuously monitors network latency to multiple hosts using ICMP-like probes or TCP connection timing, tracking statistics over time and alerting on anomalies.

FUNCTIONAL REQUIREMENTS:
- Accept one or more hostnames or IP addresses as command-line arguments
- Send periodic probes to each host at a configurable interval via --interval flag (default: 5 seconds)
- Measure round-trip time (RTT) for each probe using TCP connection timing to a specified port (--port flag, default 80) since raw ICMP requires root privileges
- Track running statistics per host: min RTT, max RTT, average RTT, median RTT, standard deviation, jitter (difference between consecutive measurements), and packet loss percentage
- Support configurable monitoring duration via --duration flag (e.g., --duration 60s, --duration 5m, --duration 1h) or run until interrupted with Ctrl+C
- Detect latency anomalies: flag probes where RTT exceeds a configurable threshold via --alert flag (default: 3x the running average RTT)
- Display a live-updating console dashboard showing: host, last RTT, average RTT, min/max, packet loss %, and alert status
- Record all measurements with timestamps for historical analysis
- Save the full monitoring data as a JSON report with --output flag (default: latency_report.json) including per-host statistics and all individual measurements
- Export time-series data as CSV via --export flag for external analysis
- Support reading a list of hosts from a file via --file flag (one host per line with optional label)
- If no hosts are given, monitor a set of well-known public hosts (8.8.8.8, 1.1.1.1, example.com, google.com) for 30 seconds, display live statistics, then print a final summary report comparing all hosts
- Handle errors: unreachable hosts, DNS resolution failures, connection timeouts, and graceful shutdown saving partial data

Create a complete Java project for a clean Ubuntu 22.04 machine with only JDK 17+ installed. Include:
- Source code
- pom.xml with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

2 files, exactly as written, before any repair.

LatencyMonitor.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * Network Latency Monitor (Java - Trial 2)
 * Monitors network latency to multiple hosts with statistics, anomaly detection,
 * and a live console dashboard using java.net built-in, Jackson, and JFreeChart.
 */
public class LatencyMonitor {

    private static final String[] DEFAULT_HOSTS = {
        "8.8.8.8", "1.1.1.1", "208.67.222.222", "9.9.9.9", "8.8.4.4"
    };
    private static final int HISTORY_SIZE = 100;
    private static final double ANOMALY_ZSCORE_THRESHOLD = 2.5;
    private static final int PING_TIMEOUT_MS = 2000;
    private static final int PING_INTERVAL_MS = 1000;
    private static final int TCP_PROBE_PORT = 53;

    private final List<String> hosts;
    private final Map<String, HostStats> hostStats;
    private final ExecutorService executor;
    private final ObjectMapper mapper;
    private volatile boolean running = true;
    private long startTime;

    static class HostStats {
        String host;
        final Deque<Double> latencies = new ArrayDeque<>();
        int totalPings = 0;
        int lostPings = 0;
        Double lastLatency = null;
        String status = "Waiting";
        final List<AnomalyRecord> anomalies = new ArrayList<>();

        HostStats(String host) {
            this.host = host;
        }

        synchronized void record(Double latencyMs) {
            totalPings++;
            if (latencyMs == null) {
                lostPings++;
                status = "Timeout";
                lastLatency = null;
            } else {
                if (latencies.size() >= HISTORY_SIZE) {
                    latencies.pollFirst();
                }
                latencies.add(latencyMs);
                lastLatency = latencyMs;
                status = "OK";
                checkAnomaly(latencyMs);
            }
        }

        private void checkAnomaly(double latencyMs) {
            if (latencies.size() < 10) return;
            double[] arr = latencies.stream().mapToDouble(Double::doubleValue).toArray();
            double mean = mean(arr);
            double std = stdDev(arr, mean);
            if (std == 0) return;
            double zscore = (latencyMs - mean) / std;
            if (Math.abs(zscore) > ANOMALY_ZSCORE_THRESHOLD) {
                anomalies.add(new AnomalyRecord(new Date(), host, latencyMs, zscore, mean));
                if (anomalies.size() > 20) {
                    anomalies.remove(0);
                }
            }
        }

        synchronized double getPacketLoss() {
            return totalPings == 0 ? 0.0 : (lostPings / (double) totalPings) * 100;
        }

        synchronized Map<String, Double> getStatistics() {
            Map<String, Double> stats = new LinkedHashMap<>();
            if (latencies.isEmpty()) {
                stats.put("min", 0.0); stats.put("max", 0.0);
                stats.put("mean", 0.0); stats.put("median", 0.0);
                stats.put("stdDev", 0.0); stats.put("p95", 0.0); stats.put("p99", 0.0);
                return stats;
            }
            double[] arr = latencies.stream().mapToDouble(Double::doubleValue).toArray();
            Arrays.sort(arr);
            stats.put("min", arr[0]);
            stats.put("max", arr[arr.length - 1]);
            stats.put("mean", mean(arr));
            stats.put("median", percentile(arr, 50));
            stats.put("stdDev", stdDev(arr, mean(arr)));
            stats.put("p95", percentile(arr, 95));
            stats.put("p99", percentile(arr, 99));
            return stats;
        }
    }

    static class AnomalyRecord {
        Date timestamp;
        String host;
        double latency;
        double zscore;
        double mean;

        AnomalyRecord(Date timestamp, String host, double latency, double zscore, double mean) {
            this.timestamp = timestamp;
            this.host = host;
            this.latency = latency;
            this.zscore = zscore;
            this.mean = mean;
        }
    }

    public LatencyMonitor(List<String> hosts) {
        this.hosts = hosts;
        this.hostStats = new LinkedHashMap<>();
        this.executor = Executors.newFixedThreadPool(hosts.size());
        this.mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);

        for (String host : hosts) {
            hostStats.put(host, new HostStats(host));
        }
    }

    /**
     * Measures latency using Java built-in networking.
     * Tries TCP connect to port 53 first, then InetAddress.isReachable.
     */
    private Double measureLatency(String host) {
        long start = System.nanoTime();
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(host, TCP_PROBE_PORT), PING_TIMEOUT_MS);
            long elapsed = System.nanoTime() - start;
            return elapsed / 1_000_000.0;
        } catch (IOException e) {
            try {
                start = System.nanoTime();
                InetAddress addr = InetAddress.getByName(host);
                if (addr.isReachable(PING_TIMEOUT_MS)) {
                    long elapsed = System.nanoTime() - start;
                    return elapsed / 1_000_000.0;
                }
            } catch (IOException ex) {
                // Host unreachable
            }
        }
        return null;
    }

    private void pingAllHosts() {
        List<Future<?>> futures = new ArrayList<>();
        for (String host : hosts) {
            futures.add(executor.submit(() -> {
                Double latency = measureLatency(host);
                hostStats.get(host).record(latency);
            }));
        }
        for (Future<?> f : futures) {
            try { f.get(PING_TIMEOUT_MS + 1000, TimeUnit.MILLISECONDS); }
            catch (Exception e) { /* timeout or error */ }
        }
    }

    private void clearScreen() {
        System.out.print("\033[H\033[2J");
        System.out.flush();
    }

    private void printDashboard() {
        clearScreen();
        long elapsed = (System.currentTimeMillis() - startTime) / 1000;
        long hrs = elapsed / 3600;
        long mins = (elapsed % 3600) / 60;
        long secs = elapsed % 60;

        int totalPings = hostStats.values().stream().mapToInt(s -> s.totalPings).sum();
        int totalLost = hostStats.values().stream().mapToInt(s -> s.lostPings).sum();
        long totalAnomalies = hostStats.values().stream().mapToInt(s -> s.anomalies.size()).sum();

        System.out.println("=".repeat(110));
        System.out.println("  NETWORK LATENCY MONITOR (java.net + Jackson + JFreeChart)");
        System.out.printf("  Uptime: %02d:%02d:%02d | Hosts: %d | Pings: %d | Lost: %d | Anomalies: %d%n",
            hrs, mins, secs, hosts.size(), totalPings, totalLost, totalAnomalies);
        System.out.println("=".repeat(110));

        System.out.printf("%-18s %-8s %8s %8s %8s %8s %8s %8s %8s %8s%n",
            "Host", "Status", "Last", "Min", "Avg", "Max", "StdDev", "P95", "Loss%", "Samples");
        System.out.println("-".repeat(110));

        for (String host : hosts) {
            HostStats hs = hostStats.get(host);
            Map<String, Double> s = hs.getStatistics();
            String statusStr = hs.status.equals("OK") ? " OK " :
                              hs.status.equals("Timeout") ? "TOUT" : "WAIT";
            String lastStr = hs.lastLatency != null ? String.format("%.1f", hs.lastLatency) : "-";

            synchronized (hs) {
                System.out.printf("%-18s %-8s %8s %8.1f %8.1f %8.1f %8.2f %8.1f %7.1f%% %8d%n",
                    host, statusStr, lastStr,
                    s.get("min"), s.get("mean"), s.get("max"),
                    s.get("stdDev"), s.get("p95"),
                    hs.getPacketLoss(), hs.latencies.size());
            }
        }

        System.out.println("\n" + "-".repeat(110));
        System.out.println("  ANOMALY DETECTION (Z-score > " + ANOMALY_ZSCORE_THRESHOLD + ")");
        System.out.println("-".repeat(110));

        List<AnomalyRecord> allAnomalies = new ArrayList<>();
        for (HostStats hs : hostStats.values()) {
            synchronized (hs) { allAnomalies.addAll(hs.anomalies); }
        }
        allAnomalies.sort(Comparator.comparing(a -> a.timestamp));

        if (allAnomalies.isEmpty()) {
            System.out.println("  No anomalies detected yet.");
        } else {
            int start = Math.max(0, allAnomalies.size() - 8);
            for (int i = start; i < allAnomalies.size(); i++) {
                AnomalyRecord a = allAnomalies.get(i);
                System.out.printf("  [%tT] %s: %.1fms (z=%+.2f, mean=%.1fms)%n",
                    a.timestamp, a.host, a.latency, a.zscore, a.mean);
            }
        }

        System.out.println("\n" + "=".repeat(110));
        System.out.println("  Press Ctrl+C to stop");
    }

    private void saveChart(String filename) {
        try {
            // Line chart of latencies
            XYSeriesCollection dataset = new XYSeriesCollection();
            for (String host : hosts) {
                HostStats hs = hostStats.get(host);
                XYSeries series = new XYSeries(host);
                synchronized (hs) {
                    int i = 0;
                    for (Double lat : hs.latencies) {
                        series.add(i++, lat);
                    }
                }
                dataset.addSeries(series);
            }

            JFreeChart lineChart = ChartFactory.createXYLineChart(
                "Network Latency Over Time", "Sample", "Latency (ms)",
                dataset, PlotOrientation.VERTICAL, true, true, false);

            ChartUtils.saveChartAsPNG(new File(filename), lineChart, 1200, 600);
            System.out.println("\nLatency chart saved to: " + filename);
        } catch (IOException e) {
            System.err.println("Failed to save chart: " + e.getMessage());
        }
    }

    private void printFinalReport() {
        System.out.println("\n\nFINAL REPORT");
        System.out.println("=".repeat(110));

        try {
            ObjectNode report = mapper.createObjectNode();
            for (String host : hosts) {
                HostStats hs = hostStats.get(host);
                ObjectNode hostReport = mapper.createObjectNode();
                hostReport.put("totalPings", hs.totalPings);
                hostReport.put("packetLoss", String.format("%.1f%%", hs.getPacketLoss()));
                Map<String, Double> stats = hs.getStatistics();
                ObjectNode statsNode = mapper.createObjectNode();
                stats.forEach(statsNode::put);
                hostReport.set("statistics", statsNode);
                hostReport.put("anomalyCount", hs.anomalies.size());
                report.set(host, hostReport);
            }
            System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(report));
        } catch (Exception e) {
            System.err.println("Error generating report: " + e.getMessage());
        }

        saveChart("latency_chart.png");
    }

    public void run() {
        startTime = System.currentTimeMillis();
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            running = false;
            printFinalReport();
            executor.shutdownNow();
        }));

        System.out.println("Network Latency Monitor starting (java.net + Jackson + JFreeChart)...");
        System.out.println("Monitoring " + hosts.size() + " hosts. Press Ctrl+C to stop.\n");

        while (running) {
            pingAllHosts();
            printDashboard();
            try { Thread.sleep(PING_INTERVAL_MS); }
            catch (InterruptedException e) { running = false; }
        }
    }

    static double mean(double[] arr) {
        double sum = 0;
        for (double v : arr) sum += v;
        return sum / arr.length;
    }

    static double stdDev(double[] arr, double mean) {
        double sumSq = 0;
        for (double v : arr) sumSq += (v - mean) * (v - mean);
        return Math.sqrt(sumSq / arr.length);
    }

    static double percentile(double[] sorted, double pct) {
        if (sorted.length == 1) return sorted[0];
        double index = (pct / 100.0) * (sorted.length - 1);
        int lower = (int) Math.floor(index);
        int upper = (int) Math.ceil(index);
        if (lower == upper) return sorted[lower];
        double frac = index - lower;
        return sorted[lower] * (1 - frac) + sorted[upper] * frac;
    }

    public static void main(String[] args) {
        List<String> hosts;
        if (args.length > 0) {
            hosts = Arrays.asList(args);
        } else {
            hosts = Arrays.asList(DEFAULT_HOSTS);
        }
        LatencyMonitor monitor = new LatencyMonitor(hosts);
        monitor.run();
    }
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.networkmonitor</groupId>
    <artifactId>latency-monitor</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>Network Latency Monitor - Trial 2</name>
    <description>Monitors network latency using java.net built-in, Jackson, and JFreeChart</description>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.16.1</version>
        </dependency>
        <dependency>
            <groupId>org.jfree</groupId>
            <artifactId>jfreechart</artifactId>
            <version>1.5.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>LatencyMonitor</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.5.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>