# Network spike monitor Windows 10/11, Python 3.10 or newer. No packages or administrator rights required. Double-click **Start Monitor.cmd**, or run: ```powershell python network_monitor.py ``` Pings `1.1.1.1` once per second. A spike is a reply of at least 100 ms, or (after 10 healthy samples) at least 3 times the healthy median AND 40 ms above it. Missing replies also count. Windows `tracert` runs after **at least three bad probes in each of two consecutive one-minute periods**. Periods are non-overlapping and start when monitoring starts; the rule is evaluated at the first probe after each period ends. For example, three spikes in minute one and three in minute two trigger a trace at about two minutes. Six spikes in one minute followed by a quiet minute do not trigger it. A period with fewer than three bad probes resets the streak; gaps from computer sleep also break it. Monitoring continues while tracing runs. An incident runs tracert repeatedly, one at a time, with a 2-second pause between attempts (`--trace-retry`). It continues even if pings recover, until a trace captures a spike or you stop the monitor. There is no attempt limit. After capture, ping monitoring continues; another qualifying period can start a new incident after the 120-second cooldown (`--cooldown`). Ctrl+C stops monitoring and cancels an active trace. Customize the target and sensitivity: ```powershell python network_monitor.py --target 8.8.8.8 --threshold 80 --required 3 --period 60 --consecutive 2 --cooldown 60 ``` Run one diagnostic immediately, then monitor normally (automatic incidents still repeat until capture): ```powershell python network_monitor.py --trace-now ``` Use `python network_monitor.py --help` for all options. Hostnames resolve to a single IPv4 address at startup so ping and tracert use the same destination. This measures the path to the selected target; it does not measure every Internet service. Run separate instances with separate `--log-dir` directories to compare destinations. ## Preserved evidence Reverse DNS is enabled: raw logs show hop hostnames alongside their IP addresses when available, for example `hop1.subsystem2.spectrum.com [192.0.2.1]`. JSON hop records include both `hostname` and `ip`. Routers without reverse DNS show only an IP; routers that do not reply may show only stars. DNS lookup can make each trace take longer. All logs go to `logs` beside the program by default, or the directory supplied with `--log-dir`: - Only traces that capture a spike are retained. Each has a timestamped `trace_YYYYMMDD_HHMMSS_microseconds.txt` containing the **entire, unmodified stdout and stderr**, plus a matching `.json` with hop timings, command, incident ID, attempt number, and assessment. - While a trace runs, output streams to `.pending.txt`. If it captures a spike, this file becomes the saved `.txt`; otherwise it is deleted, including on normal cancellation without measured spikes. A forced process kill or power failure may leave a temporary `.pending.txt`. - `events.jsonl` appends individual spikes/lost replies, period summaries, and brief incident/attempt results between runs. Healthy pings appear only in the console and are not written to disk. Discarded attempts do not retain their full output or hop arrays here. - Existing logs from earlier versions are left in place. Raw output uses the Windows command's native encoding. No logs are automatically deleted or rotated. A long-running session can grow large; archive logs after stopping the monitor. Probe intervals are best effort; timeouts may make a cycle longer than the requested interval. Values below 1 ms are represented as 0.5 ms for calculations. Parsing requires the Windows ping reply's `TTL` field and `ms` timings; unrecognized successful replies produce an explicit error. ## Interpreting reports A trace is retained when **any individual timed probe at any hop** meets the spike threshold: 100 ms by default, or the relative ping threshold based on the healthy baseline frozen when the incident starts. A single slow probe counts even if the other two replies are fast, downstream hops recover, or the destination never replies. Partial/cancelled traces are also retained if they contain measured slow replies; timeouts alone do not qualify. This captures evidence without claiming the responding router is faulty. Saved JSON includes the individual `spike_probes` with hop, hostname, IP, and RTT. Compact event summaries include `peak_probe_ms`, `spike_limit_ms`, and `spike_probe_count` so you can see why an attempt was kept or discarded. Hop medians and `--hop-jump` are used only for the separate tentative segment assessment, not to decide whether to save a trace. The report looks for an RTT jump that remains elevated through subsequent responding hops, including the destination. It identifies a possible segment, not a proven faulty router. These are round-trip measurements taken at different times, not per-link transit times. Return paths and ICMP prioritization can differ. A spike can end while tracert is still running. Missing hops are not evidence of packet loss in forwarded traffic. Microsoft documents that some routers do not answer traceroute probes: [TRACERT troubleshooting](https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/trace-route-troubleshoot-tcp-ip-problems). ## Verification ```powershell python -m unittest -v python network_monitor.py --target 127.0.0.1 --count 3 --trace-now ``` `--count` ends monitoring after the requested probe count and cancels an active incident capture. A healthy loopback diagnostic should leave no saved trace files.