Repository navigation
Releases: mehaskari/xping
Release list
xping v1.6.0
[1.6.0] - 2026-10-13
Added
- Fedora and EPEL 10:
sudo dnf copr enable mehaskari/xping && sudo dnf install xping, built automatically for every release. xping reportshows the 95th percentile, and--since 7d --compare
compares each target with the week before: uptime, median and p95 with
the change marked green (better) or red (worse).xping monitor --install-service: keep monitoring in the background.
The same monitor command runs as a per-user service, a LaunchAgent on
macOS or a systemd user unit on Linux, started at login and restarted
if it stops, with its output in~/.xping/monitor.log. The checks are
validated before anything is installed.--service-statusshows
whether it runs;--uninstall-serviceremoves it. No root needed.xping history --clear --older-than 30ddeletes only runs older than
that and keeps the rest (files left empty are removed), so a monitor
saving all day does not grow without bound.- VPN awareness.
xping netshows a VPN tunnel and whether internet
traffic goes through it (found by asking the routing table how 1.1.1.1
is reached, since many VPNs leave the default route alone).xping doctornames the VPN next to the network interface and puts high
latency down to the tunnel rather than to your network.--jsonhas
internet_interface,vpn_interfacesandvia_vpn.
Changed
- Releases reach the Snap Store's stable channel automatically (each
architecture as soon as its build of the release is ready). - Snap builds of unreleased commits are versioned
X.Y.Z+gitN.HASH;
only the release commit itself isX.Y.Z. - Packaging held to the distributions' own tools: the Debian package
builds in Debian unstable with the tests running and no network, is
lintian-clean and passes autopkgtest; a Fedora spec (also used by COPR)
builds with%check, passes rpmlint and installs. Both run in CI. xping monitorchange lines (in a log or pipe) line up: the check
name and type columns are padded to the widest name, so the details
start in the same column on every line.
xping v1.5.2
[1.5.2] - 2026-10-07
Fixed
xping reportwith nothing saved says so plainly ("nothing saved yet")
and suggestsxping monitor --save; a filter or--sincethat leaves
nothing says "in this period" and points toxping history.xping reportcharts break the line where nothing was measured (e.g.
while monitor was stopped) instead of drawing a straight line across.xping monitorand watch mode write each line at once when the output is
a file or a pipe, sotail -fon a log follows them live (the output
used to sit in a buffer until several kilobytes had accumulated).
xping v1.5.1
[1.5.1] - 2026-10-06
Added
- A default check file,
~/.xping/checks.toml:xping checkand
xping monitoruse it when no file is given, and say how to create it
when it does not exist.xping check --initcreates it with checks that
work anywhere (your router, 1.1.1.1, 8.8.8.8, DNS, HTTPS); it never
overwrites an existing file. xping monitor HOST HOST:PORT URL…without a file: hosts are pinged,
HOST:PORTgets a TCP connect, URLs an HTTP check.- Homebrew:
brew install mehaskari/tap/xping(man page and completion
for bash, zsh and fish included). The tap follows PyPI releases on its
own, after building and testing each new version on macOS. blocklistchecks IPv6 addresses too (nibble format) on the lists
that publish IPv6 data, Spamhaus ZEN and DroneBL — both for an IPv6
address given directly and for a domain's IPv6 mail and web servers,
which were previously listed as "not checked".xping report: the saved history as one HTML page. An overview of
every target (state, uptime, outages, latest value), and per target the
uptime, outages and downtime, latest and median value, a chart of the
headline metric over time with failures and outages marked, and the
list of outages. One self-contained file, no scripts, nothing loaded
from the network, light and dark theme.-o FILE(or-for stdout),
--since,--last,--title; narrow to one command or target.mtr --tcp/--port PORT: every probe is a TCP SYN to that port
(443 by default), liketrace --tcp, so mtr works where ICMP is
dropped. Also in check files (tcp = true,port).--fail-after Nand--recover-after Nfor watch mode (--watch/
--until-upon ping, tcp, udp, http, health) andxping monitor
(also per check:fail_after,recover_after). A target counts as
DOWN only after N failed checks in a row and as UP again after N
passing ones, so a single blip neither flips the state nor alerts
anybody. Uptime still counts every check; outages, the "down at the
end" verdict and alerts follow the confirmed state, and an outage is
measured from its first failed check.--until-upwaits for N passes.
ping --watchkeeps its 3-lost-pings rule as the default.xping monitormarks a check◐while its latest runs disagree with
the confirmed state.
xping v1.5.0
[1.5.0] - 2026-10-05
Deprecated
- Short options that meant something else in one command than in all
the others. The old spelling still works until 2.0 and prints a
warning on stderr:trace -p N(probes;-pis--portselsewhere): use--probes N.propagation -t TYPE(-tis--timeoutelsewhere): use-r/
--type.ping -w(-wis--workerselsewhere): use--watch.wifi -i NAME(-iis--intervalelsewhere): use-I/
--interface.
Added
xping monitor FILE: a live dashboard for a check file. Every
check runs again and again, each on its own schedule (everyin the
file, or--every). In a terminal the state is a table redrawn in
place: up or down, the latest value of the check's headline metric, a
trend of the last 16 runs, uptime and how long the current state has
lasted; narrow terminals drop the least important columns, then
shorten check names, and hide the detail rather than show two letters
of it. Elsewhere
(cron, systemd, a pipe) it prints one line per state change.--notify
/--webhookalert on every change,--savekeeps each result in the
history under the same name as the single command,--rounds Nstops
after N runs. Ctrl-C ends with a summary (uptime, outages, longest
outage, average); the exit code says whether everything was up.
Durations drop a zero remainder:1mrather than1m00s.ping --until-upand--every, liketcp,udp,httpand
health: ping once per check until the host answers, then exit 0
(xping ping 10.0.0.1 --until-up -q && ssh 10.0.0.1).- Check files support
trace,mtr,wifi,doctorandspeedtest,
with their thresholds (max_loss/max_latencyfor mtr,
min_signalfor wifi,min_download/min_uploadfor speedtest).
Speedtest checks run on their own after the parallel ones. xping check --savekeeps the whole report in the history, one
history per check file.speedtest --min-download MBPSand--min-upload MBPS: exit 1 when
the link is slower than that.
Changed
- Every terminal view is now tested with realistic results, with colour
on and off: the layout must be identical either way (the cause of past
column drift), and escape codes in remote text (whois, DNS,
certificates) must never reach the terminal. Coverage rose from 79% to
82%, and the minimum from 75% to 80%. - mypy now checks every module: the last three on the baseline
(exporters/tables.py,verdict.py,diagnostics/speedtest.py) are
typed, and the baseline is gone. ping --watchnow judges the whole session when you stop it:
--max-loss/--max-latencyand the exit code apply (1 when every
ping was lost), and--savekeeps the session in history. An
unresolvable host now exits 1 instead of 0.- Python 3.13 and 3.14 are tested in CI (Linux and macOS) and listed
as supported on PyPI. Python 3.10 stays supported: Ubuntu 22.04,
which the PPA builds for, ships it. --saveconfirms the save with the run number and thexping history
command to use, except with-qor an export format, where the output
has to stay clean.
Fixed
xping.diagnostics.checkcan be imported on its own (it failed with a
circular-import error when it was the first xping module loaded, e.g.
from a script using xping as a library). The pass/fail verdicts moved
fromxping.cli.verdicttoxping.verdict, below the CLI layer; a
test now imports every module standalone and keeps the lower layers
free of CLI imports.xping historyno longer shows an empty trend line for a single run,
and says "1 run" rather than "1 runs".
xping v1.4.9
[1.4.9] - 2026-10-03
Added
- History:
--saveandxping history.--saveon ping, trace, mtr, health, tls, tcp, udp, http, smtp,
dnscheck, blocklist, ntp, speedtest, wifi and doctor keeps the result
in~/.xping/history/<command>/(or setsave = trueunder
[defaults]in the config file).xping historylists what is recorded.xping history COMMAND TARGETshows the runs with the command's key
metrics, a trend line, the pass rate, and the latest run against the
median. It supports--last,--since 7d,--clear, and
--json/--csv.- Nothing is recorded without
--save. The newest 500 runs per
command and target are kept.
Changed
xping diffis easier to trust and to read.- Jitter and the maximum RTT get a 10% noise band; other metrics keep
3%. - New notes warn when the two runs have different or small sample
sizes. - Notes also explain likely causes: a higher minimum RTT points to a
route or ISP change, and higher jitter with an unchanged minimum
points to a busy or weak local link. - JSON output has a new
notesfield.
- Jitter and the maximum RTT get a 10% noise band; other metrics keep
xping wifinames two stronger access points when they are nearly
equal, so the tip no longer flips between runs as signals fluctuate.
Development
-
CI type-checks the code with mypy. Every module is checked except three
that need a larger rework, which are listed as a baseline in
pyproject.toml. Fixing the reported issues turned up a name that
shadowed the colour helper inlookup, plus many missingNone
checks and annotations. -
The minimum test coverage rose from 55% to 75% (actual: 79%). The CI run
page shows a coverage summary. -
A documentation site at https://mehaskari.github.io/xping/, built with
MkDocs (Material) fromdocs/. It has search, dark mode and a table of
contents. Every docs change is built in strict mode, so a broken link
or section anchor fails the check. The site is published frommain.
xping v1.4.8
[1.4.8] - 2026-09-27
Changed
xping wifidetects a clearly stronger access point nearby (8 dB or
more, same security, same name where known). This is a device "stuck"
on a far access point, and toggling Wi-Fi fixes it. 5/6 GHz access
points are preferred.xping smtplists MX records one per line, showing the first three.
smtpandtlsshow certificate names short ("Google Trust Services
(WE2)" instead of the full distinguished name); JSON output keeps the
full names.- CI and release workflows use current action versions, which run on
Node.js 24 instead of the deprecated Node.js 20: checkout v7,
setup-python v7, upload-artifact v7, download-artifact v8 (a hash
mismatch now fails the download), action-gh-release v3 and CodeQL v4.
All of them are still pinned to commit SHAs. Dependabot now proposes
action updates as one grouped PR.
xping v1.4.7
[1.4.7] - 2026-09-27
Security
- Terminal escape sequences and control characters from servers are
removed before display and CSV/Markdown export. Before, a malicious
server could move the cursor, overwrite output or write to the clipboard. - The DNS parsers no longer hang on a compression pointer loop, which
a malicious response could trigger. - Raw DNS queries use a random transaction ID on a connected socket and
drop mismatched replies, which makes spoofing hard. diggets names through-q/-t, so a name such as-f/etc/passwd
from a check file can no longer read local files.profile list --namesprints only valid names. Bash completion passes
them tocompgen -W, which expands$(...).httpcounts the body instead of storing it, and stops at 100 MB.
WHOIS responses are capped at 1 MB.- The completion rc block single-quotes the script path. CI and release
workflows use read-only tokens and pass secrets as environment
variables. - Every GitHub Action in CI and release workflows is pinned to a commit
SHA, so a moved or hijacked tag can't change what runs with release
credentials. Dependabot keeps the pins current.
Added
xping smtp HOST— checks a mail server.- It checks the greeting, the EHLO extensions, STARTTLS (or implicit
TLS on 465) and certificate verification for the server's name. - It shows the AUTH mechanisms and size limit offered over TLS, and
whether the server's reverse DNS resolves back. - A mail domain is tested through its preferred MX;
--no-mxtests
the host itself. - It ends with QUIT and never sends mail.
--port 25|587|465. Missing or invalid TLS is a warning unless
--require-tlsis given.--min-dayschecks certificate expiry.- It is an
smtptype in check files.
- It checks the greeting, the EHLO extensions, STARTTLS (or implicit
xping diff BEFORE AFTER— compare two--jsonresults of the
same check. Either side can be-for stdin.- It recognises the kind of result and compares the numbers that
matter, each with its "better" direction: RTT, jitter, loss, HTTP
phases, TLS days, speed, clock offset, Wi-Fi signal and so on. - It shows the route changes of
trace/mtr, added and removed DNS
records, and status changes indnscheck/doctor/check/
blocklist. - Changes under 3% count as noise.
--max-regression PCTexits 1 on a bigger regression or a worse
status.
- It recognises the kind of result and compares the numbers that
xping wifi— Wi-Fi link quality.- It shows signal and noise (dBm) with a grade, the SNR, the channel,
band and width, the link rate and MCS, the standard, the security,
and how many nearby networks share (or on 2.4 GHz overlap) your
channel. - It gives advice: move closer, interference, switch to 5 GHz, or the
least used of channels 1 / 6 / 11. --nearbylists the networks around you.--min-signal DBMmakes it
an alarm.- Data comes from
system_profiler(macOS),iw/nmcli(Linux) or
netsh wlan(Windows), with no root and no network traffic.
- It shows signal and noise (dBm) with a grade, the SNR, the channel,
Changed
xping blocklistshows a compact summary instead of one row per list
per address, which was 43 rows for a typical domain.- Each checked address or domain gets one row, e.g. "clean on 8/8 IP
lists". - Any result that is not clean is still shown in full.
--allrestores the full table.- The closing line now says "43 checks on 11 lists" instead of the
misleading "43 lists".
- Each checked address or domain gets one row, e.g. "clean on 8/8 IP
xping ntpshows the measurement accuracy (± half the round trip),
and says when the offset is within it. JSON output has a new
uncertainty_msfield.xping udpandxping ntpno longer repeat the address on an "IP"
line when the target already is an IP.
xping v1.4.6
[1.4.6] - 2026-09-26
Added
xping udp HOST PORT— is a UDP service answering? Each probe is
open (a reply came back), closed (ICMP port unreachable) or no
response (filtered, or the service ignored the request). The request
is chosen by port — a DNS root query for 53/5353, SNTP for 123, SNMPv2c
GET sysDescr (communitypublic) for 161 — or set with--probe/
--payload HEX. It supports--max-latency,--watch,--until-up
and alerts, and is audptype in check files.xping blocklist IP|DOMAIN— checks spam blocklists (DNSBL).- An IP is checked on Spamhaus ZEN, SpamCop, Barracuda, PSBL,
Mailspike, UCEPROTECT L1, DroneBL and s5h. - A domain is checked on Spamhaus DBL, SURBL and URIBL, and the IPv4
addresses of its MX and A hosts are checked on the IP lists. - Results are listed, policy (Spamhaus PBL end-user ranges, which
don't fail), clean, refused (lists that refuse public resolvers)
or error. --zoneadds more lists. It is ablocklisttype in check files and
exits 1 when the target is listed.
- An IP is checked on Spamhaus ZEN, SpamCop, Barracuda, PSBL,
- DNSSEC in
xping dnscheck.- Three queries to a validating resolver (1.1.1.1, then 8.8.8.8) with
the DO flag: DS at the parent, a signed SOA and its AD flag, and a
checking-disabled retry after SERVFAIL. - Results: signed and validated (ok); broken "bogus" signatures,
meaning validating resolvers cannot resolve the domain (fail); signed
without DS, i.e. not active (warn); not signed (info). - Answers are retried over TCP when truncated.
- Three queries to a validating resolver (1.1.1.1, then 8.8.8.8) with
xping lookup --doh PROVIDER— DNS over HTTPS (RFC 8484 wire
format) tocloudflare,google,quad9or anyhttps://URL.
It gets past resolvers that filter, rewrite or hijack plain DNS. JSON
output now includestransport(dig,udpordoh) andresolver.- Personal defaults in
~/.xping/config.toml.- A
[defaults]section applies to every command, and there is one
section per command (e.g.[ping] count = 10,
[lookup] doh = "cloudflare"). Keys are long option names. - The command line always wins. In mutually exclusive pairs, the flag
given on the command line drops the file's value for the other one
(-6beatsipv4 = true). - Unknown sections, options or values are errors that name the file,
section and key. xping configshows the active settings or explains what is wrong,
andxping config --exampleprints a starter file.XPING_CONFIGselects another file, andXPING_CONFIG=noneignores
it.- The
xping HOSTshorthand uses the[ping]section.
- A
xping ntp [SERVER]— the system clock offset against an NTP
server (defaultpool.ntp.org) over SNTP. It shows the offset, the
delay, the stratum, the reference and whether the server is
synchronised, using the lowest-delay of several samples.
--max-offset MSmakes it an alarm. It is anntptype (threshold
max_offset) in check files.
xping v1.4.5
[1.4.5] - 2026-09-26
Added
-
xping doctor [host]— answers "why is my internet not working?".
It checks, in order: network interface (and DHCP), default gateway,
internet by IP (no DNS), DNS (your resolvers vs. a public one),
connection quality, captive portal, HTTPS (interception and system
clock), IPv6 and, optionally, a host (--port, default 443). It ends
with one plain-language diagnosis and what to do. Exit code 1 when a
step fails;--json,--csv(one row per step) and--markdown
work as usual. -
xping http: per-phase timing waterfall and security headers.- The TLS handshake is now timed separately from the TCP connect. The
time to download the body and the time spent following redirects
are timed too. - The phases are drawn as a waterfall, like a browser's network tab.
- The TLS version and cipher are shown.
- A security-header audit covers HTTPS / http→https upgrade, HSTS
(max-age ≥ 180 days), CSP,X-Content-Type-Options,
X-Frame-Options(or CSPframe-ancestors),Referrer-Policy,
Permissions-Policy, and version-revealingServer/
X-Powered-Byheaders. It is informational only. - New JSON fields:
tls_ms,transfer_ms,redirect_ms,
tls_version,tls_cipher,security,security_missing. CSV /
Markdown gain a "Security headers" table.
- The TLS handshake is now timed separately from the TCP connect. The
-
xping trace --tcp/--port N— traceroute with TCP SYN probes
to a real service port (443 by default;--portimplies--tcp).
It gets through firewalls that drop ICMP, where a normal traceroute
ends in* * *. No root needed: Linux reads the router from the TCP
socket's error queue (IP_RECVERR), macOS from an unprivileged ICMP
socket. IPv4 and IPv6; not available on Windows. -
Alerts in watch mode:
--notifyand--webhook URLon
ping --watchand on--watch/--until-upfortcp,httpand
health.- An event fires on every DOWN / UP change, and the UP message includes
how long the outage lasted. --notifyuses Notification Center (macOS) ornotify-send(Linux),
and the terminal bell elsewhere.--webhookPOSTs a JSON event withtext/contentfields that
Slack, Discord, Mattermost and Google Chat display directly. It is
sent in the background, and a failure is reported only once.ping --watchtreats three consecutive lost pings as an outage.
- An event fires on every DOWN / UP change, and the UP message includes
Changed
xping http:tcp_msis now the TCP connect time alone. It used to
include the TLS handshake, which is now reported astls_ms.
Fixed
- The progress spinner (used by
doctor,http,trace,net, …)
printed its message on one line per animation frame when the message
was wider than the terminal. It is now cut to fit, with "…". - Misaligned columns in
http(timing, connection, security and
response headers),trace(host column after the RTT) andall
(summary). Padding counted the invisible colour codes, so columns
drifted, especially with colour off (NO_COLOR, piped output).
Coloured text is now padded by its visible width. - Summary tables (trace, ping, watch, speedtest, …) had a misaligned
value column and uneven borders whenever a cell was coloured; the
table renderer measured cells including their colour codes. xping trace: the rule under the hop list was shorter than the rules
around the column header; all rules now have the same width.xping traceprinted the separator line twice before its summary.xping http: the last line of the redirect chain always showed
status 200, even when the final response was an error.- Project links pointed to
github.com/mehdiaskari/xping, which does not
exist. The correct repository,github.com/mehaskari/xping, is now used
in the PyPI metadata (pyproject.toml,setup.cfg),xping about, the
man page, the snap and Debian metadata, README and CONTRIBUTING. - The WHOIS/RDAP bootstrap download (
data.iana.org) now uses the same
TLS context as every other HTTPS request (certifi, TLS 1.2+), so it
also works on Python builds without a usable system CA store.
Docs
- New user guide,
docs/guide.md. It covers every
command with all options and defaults, what the output means, and how
scores are computed (health,dnscheck,speedtest,osdetect).
It also has the check-file reference, recipes, files/privacy, platform
notes and a FAQ. It is linked from the README and the PyPI project
links. A test fails if a command or long option is missing from it. - Man page:
--proto udpin thelistendescription rendered as
--protoudp. - README: current install options (PPA for Ubuntu 24.04 and derivatives,
Snap with stable/edge channels, PyPI with the completion step). The
non-existent AUR package is removed. New sections for listening
ports, OS fingerprint and "Files & privacy" (what is stored, which
commands contact third parties), plus completion environment
variables. - CONTRIBUTING: PR workflow with branch protection, an up-to-date
"add a new command" checklist (verdicts, CSV tables; completion is
automatic), and notes on the real-shell completion tests. - RELEASE: the PR-based release flow, macOS-compatible
sed, the
current CI matrix, snap edge → stable promotion, and a correct
rollback (PyPI yanking happens on the website;twine yankdoes not
exist). - SECURITY: 1.4.x supported; the design section describes unprivileged
ICMP, strict TLS, which files are written, third-party contacts, and
shell-free subprocesses. The obsolete--outputmention is removed. - PACKAGING: completion packaging, snap channels, six-file version
checklist, and the corrected PPA series (noble). - Man page: PRIVACY section, accurate DEPENDENCIES, completions in FILES.
- Debian: a real
README.Debianinstead of the template placeholder,
and the unusedxping-docs.docsis dropped. The bug report template
asks for the install method and shell.
xping v1.4.1
[1.4.1] - 2026-09-25
Fixed
-
Tab completion did not work (reported on macOS). There were three causes:
- the zsh script never registered itself when sourced;
- zsh's own
_hostscompletion also claims a command namedxping
and took over; - on macOS's bash 3.2, the documented
source <(xping completion bash)
silently does nothing.
Completion scripts for bash, zsh and fish are rewritten and verified by
pressing Tab in real shells (zsh via zpty, bash 3.2 and 5, fish 3.7).
Added
xping completion --install/--uninstall: sets up completion for your
shell in one step. It writes the script and adds a marked, idempotent block
to~/.zshrc,~/.bashrcor~/.bash_profile(bash on macOS); fish is
set up via~/.config/fish/completions/.- Richer completion: option descriptions (zsh, fish), fixed-choice values
(--proto,--type, shells), hostnames plus saved profile names
wherever a host is expected,.toml/.jsonfiles forxping check,
and profile names forprofile show/remove. In zsh, mutually exclusive
options are not offered together. - The Debian/Ubuntu package installs completion for bash, zsh and fish
automatically; the snap provides bash completion. xping profile list --namesprints bare profile names (used by
completion).