Network spike monitor
Windows 7 SP1 or newer, Python 3.8 or newer (use Python 3.8 on Windows 7). No packages or administrator rights required to run the monitor.
Windows 7 setup
Install Python 3.8.10 using its Windows installer (32-bit) or Windows installer (64-bit) to match your system. Select Add Python 3.8 to PATH during installation, then open a new command prompt. Use the traditional installer listed under Files, not the newer Python install manager. Python 3.8 is the last branch compatible with Windows 7; 3.8.10 is its last release with official Windows installers. Windows 7 must have Service Pack 1 and the updates needed by the Python installer.
Check python --version reports Python 3.8.x on Windows 7. On newer Windows, a newer supported Python release is fine. The monitor's ping and tracert options, trace cancellation, and logging use Python 3.8-compatible APIs. Python 3.8 is no longer maintained. Compatibility tests run on Python 3.8 on a newer Windows system; a physical Windows 7 installation has not been tested.
Start monitoring
Double-click Start Monitor.cmd, or run:
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:
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):
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.txtcontaining the entire, unmodified stdout and stderr, plus a matching.jsonwith 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.jsonlappends 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.
Verification
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.