Releases: BitpingApp/Bitping-Node
26.6.2-1
Changelog
⚙️ Miscellaneous Tasks
-
Bump version to 1.3.4
-
Widen prod RUST_LOG to surface orchestrator/handshake events
The existing span-allowlist (send_job/attempt_send_job/handle_commands/
job_events) filtered out every INFO/WARN from orchestrator (NewNode
Connection upserts), handshake validation (new per-variant response
sends), the ping-failure tracker, and the dispatch-skip metric. The
2026-05-30 cohort wedge wasn't diagnosable from Loki because Jane's peer
had zero log lines on the hub side — not because the hub didn't know
about her, but because none of the relevant code paths' events were
allow-listed. Adds module-scoped INFO/WARN directives without opening
the firehose on every libp2p substream.
⛰️ Features
- Publish ghcr.io docker images via kaniko
Both customer apps now publish multi-arch images to
ghcr.io/bitpingapp/{p2proxy,distributed-metrics}: after the
goreleaser GitHub Release step. Closes the deferred TODO that meant
the hosted-metrics-operator's per-user MetricsInstance deployments
were chasing a bitping/distributed-metrics:1.3.4 nobody was publishing.
-
Dockerfiles: multi-stage, alpine downloads + verifies the binary
from the GitHub release goreleaser just created, then distroless
runtime. No bind-mount-binary handshake with goreleaser. -
.customer_docker template: kaniko parallel matrix amd64/arm64,
pushes per-arch tags. Auth via the same GitHub App token already
minted for releases (.gh_token_mint anchor factored out so the
release + docker jobs share one impl). -
.customer_docker_manifest template: manifest-tool combines per-arch
tags into the versioned + :latest manifest lists. -
HTTP CDN Monitoring (v3) — crowdsourced eyeball view
MVP dashboard showing what makes Bitping's distributed-metrics unique
vs Catchpoint/ThousandEyes/Datadog Synthetics. 8 collapsible sections,
22 panels, scoped by endpoint × continent × country × ISP with two
SLO target variables (P95 latency, success rate).
Differentiator panels:
-
Crowdsourced reach (live counts of countries/ISPs/cities/OSes probing)
-
Per-monitor health card (one row per endpoint with drift + SLO status)
-
TLS handshake failures by country (state-level interference detector)
-
Error-type heatmap (country × type) — censorship + ISP-misconfig signal
-
Distinct response-body hashes per endpoint (cache coherence /
split-horizon detection nobody else can see) -
ISP performance deep dive (residential ISP comparison)
-
Emit CDN-grade metrics (phase timings, protocol, cache status, edge POP, cert expiry)
Extends HttpCollector::record_success_metrics to emit 10 new metric
families derived from PerformHttpResponse.results[].result fields the
collector was previously discarding:
- http_dns_resolve_ms / http_tcp_connect_ms / http_tls_handshake_ms /
http_ttfb_ms / http_content_download_ms — per-phase timings from
result.metrics (the optional phases are skipped when null, matching
the API semantics). - http_protocol{protocol=h1|h2|h3} — from result.negotiatedProtocol.
- http_address_family{family=ipv4|ipv6} — from result.addressFamilyUsed.
- http_fallback_total{from_protocol,to_protocol} — one increment per
entry in result.fallbackChain. - http_cdn_provider{provider=cloudflare|fastly|cloudfront|akamai|vercel|
bunny|gcore|netlify|none} — response-header sniff via a new cdn_headers
module. - http_cache_status{status=hit|miss|stale|expired|bypass|dynamic|unknown}
— normalised across cf-cache-status, x-cache, x-vercel-cache, cdn-cache,
and server-timing cdn-cache desc. - http_edge_pop{pop} — IATA code extracted per provider (cf-ray suffix,
x-amz-cf-pop prefix, x-served-by middle segment, x-vercel-id prefix,
bunny server suffix). - http_cache_age_seconds — Age response header.
- http_ssl_expires_days_remaining + http_ssl_chain_valid — from
result.sslInfo (gated on the customer monitor enabling sslInfo=true).
cdn_headers module includes nine provider fixtures (one per supported
CDN + a no-CDN baseline) plus case-insensitive lookup and cache-status
normalisation tests; all green via cargo test.
No proto / API changes needed — the bitping-api was already returning
every field; the collector is the bottleneck this commit removes.
Bumps Cargo.toml to 1.3.5.
- Add ssl_info/transport HttpConfig knobs + live CDN metrics smoke test
Two follow-ons to the CDN-metrics emission landed in 221f57b:
-
HttpConfig gains two optional fields the collector previously
hardcoded:ssl_info: Option<bool>— opts the probe into TLS cert capture.
Without this the http_ssl_chain_valid / http_ssl_expires_days_remaining
gauges are dead code in production.transport: Option<String>— TCP (default) / AUTO / QUIC. AUTO is
what populates http_fallback_total (the chain only has entries when
happy-eyeballs tried h3 first and fell back).
Both default to None so existing customer configs are unchanged.
-
New
tests/cdn_metrics_live.rsintegration test (#[ignore], runs
against the real Bitping API with BITPING_API_KEY set). Probes
cloudflare.com / aws.amazon.com / vercel.com with ssl_info=true,
transport=AUTO and asserts the full metric set lands in the rendered
Prometheus snapshot, including provider-label correctness. Verified
output:- Cloudflare: protocol=h3, pop=SIN, ssl_chain_valid=1,
ssl_expires_days_remaining=65.9 - CloudFront: pop=MEL, cache_status, cache_age_seconds
- Vercel: pop=CDG1, cache_status=hit, cache_age_seconds
- Cloudflare: protocol=h3, pop=SIN, ssl_chain_valid=1,
To enable the new integration test, mod collectors and the
generate_api! macro move from src/main.rs into src/lib.rs so
tests/* can use distributed_metrics::collectors::http::HttpCollector;.
Behavioural no-op — main.rs still owns setup, CONFIG, render_prom, main.
- V5 — eight new CDN insight sections wired to BIT-562 metrics
Adds 8 sections + 12 data panels to dashboards/http-cdn-monitoring.json
(also pushed live to uid bitping-http-cdn-mvp), all wired to the new
metric families distributed-metrics 1.3.5 emits:
- CDN: Latency waterfall — DNS / TCP / TLS / TTFB / Content download
stacked timeseries from http_dns_resolve_ms / http_tcp_connect_ms /
http_tls_handshake_ms / http_ttfb_ms / http_content_download_ms (P50). - CDN: Provider distribution — bar gauge + per-endpoint table from
http_cdn_provider{provider}. - CDN: Cache performance — status mix (stacked) and per-endpoint hit
rate from http_cache_status{status}. - CDN: Edge POP geography — pop × endpoint table from
http_edge_pop{pop}. Picks up cf-ray / x-amz-cf-pop / x-served-by /
x-vercel-id / bunny IATA codes. - CDN: HTTP version adoption — h1/h2/h3 stacked + HTTP/3 share stat
from http_protocol{protocol}. (h3 series require customer monitor
with transport: AUTO.) - CDN: IPv6 reachability — share stat + per-endpoint family table
from http_address_family{family}. - CDN: Certificate expiry watch — per-endpoint min days remaining +
chain validity from http_ssl_expires_days_remaining +
http_ssl_chain_valid. Empty until at least one monitor sets
ssl_info: true (panel description calls this out). - CDN: Origin RTT (proxy) — TTFB P95 for endpoints whose CDN is NOT
reporting cache hits. Approximates upstream origin response time.
Header description updated to list the new section names. Existing 35
panels (overview, per-monitor, crowdsourced reach, latency, errors,
geo, CDN diagnostics, ISP deep dive) untouched. Total panels: 55
(8 original rows + 27 original data + 8 new rows + 12 new data).
Live dashboard pushed via Grafana MCP patch operations against uid
bitping-http-cdn-mvp (version now 7 in Grafana).
- Observability for handshake variants and dispatch skips
The 2026-05-30 cohort wedge investigation drifted onto wrong hypotheses
for hours because the hub had no telemetry to answer either question:
"did this peer ever finish handshaking?" and "is find_node skipping this
peer, and why?" Both fixed here.
- handshake/validation.rs: per-variant info!/warn! on every response we
sign and ship back, tagged with structuredvariantfield. The Ack
path was previously silent (counter only) — now every accepted node
leaves a Loki breadcrumb. Backoff / Reauthenticate / Error keep their
warn level but get the variant tag for grouping. - connection_pool/mod.rs: apply_filters refactored from
-> boolto
-> Option<&'static str>returning the rejection reason. find_node_iter
increments find_node_skipped_total{reason} counter on every silent
return-false plus emits a trace!() per peer for deep-dive. Reasons:
dedup_loser_unique_by_ip, capability_mismatch, req_{continent,country,
city,os,isp,proxy,mobile,residential,peer_id}, excluded. Exclusion AND-
chain semantics preserved (a peer is excluded only when every named
exclusion fires).
🐛 Bug Fixes
-
Update spec
-
Mode: replace makes goreleaser asset upload idempotent
The 1.3.4 distributed-metrics release attempt landed in an inconsistent
state — release tag created, partial asset uploads, then 422 already_exists
on retry. mode: replace tells goreleaser to delete existing assets with the
same name before upload, so re-runs converge on a clean release.
-
Delete stale GitHub release before goreleaser
-
Pass kaniko docker auth via release-job artifact
-
Publish docker images to Docker Hub via DOCKER_PAT
GitHub App lacks packages:write scope so ghcr.io push hit 'installation
not allowed to Create organization package'. Switching to Docker Hub
(bitping account) since:
- DOCKER_PAT is already wired up as a GitLab CI variable
- The hosted-metrics-operator's metrics_image config already points at
bitping/distributed-metrics:, so no operator config flip
needed once 1.3.4 publishes - Old 1.3.0 pods on the cluster are already pulling from the same repo
Image tags land under docker.io/bitping/{distributed-metrics,p2proxy}
with per-arch suffixes (-amd64/-arm64) and the manifest-tool job ties
them under : + :latest multi-a...
26.5.30-1
Changelog
⚙️ CI/CD
- Drop DMG bundling, ship .app.zip via ditto
Tauri's bundle_dmg.sh depends on the SetFile Carbon tool that Xcode 14+
removed (tauri-apps/tauri#3055, open since 2021). Drop dmg from
bundle.targets in tauri.conf.json so Tauri stops trying to build it, and
produce a codesigned + notarized .app.zip via ditto -c -k --keepParent --sequesterRsrc in the after_script. ditto preserves the notarization
staple that a plain zip would strip.
Naming mirrors the legacy DMG (Bitping.Desktop__.app.zip)
so the customer website download links and the GitHub release flow only
change extension. The Tauri updater path (.app.tar.gz + .sig) is
unaffected — that artifact is governed by createUpdaterArtifacts, not
bundle.targets.
⚙️ Miscellaneous Tasks
- Bump version to 1.3.3
⛰️ Features
- Tolerate transient ping failures before disconnect
Add PingFailureTracker counting consecutive hub-side ping failures per
peer. Disconnect only after MAX_CONSECUTIVE_PING_FAILURES (3) in a row —
a single timed-out ping is a transient blip for a globally-distributed
residential/mobile fleet, not a dead node. Ping success resets the
counter.
- Surface proto ErrorCode as error_type label
Replace the substring-based error-message taxonomy in the HTTP collector
with the typed ErrorCode field forwarded by bitping-api. The proto enum
value is used verbatim — strip the redundant ERROR_CODE_ prefix and
lowercase — so new variants flow into the metric label automatically with
no hand-curated mapping table to keep in sync. Missing/unrecognised codes
bucket as "unknown" and log a warning.
26.5.25-1
26.5.15-1
26.5.14-1
26.5.12-1
26.5.8-3
26.5.7-1
Changelog
[26.5.7-1] - 2026-05-07
What's Changed
bitpingd
- New ratatui TUI with Dashboard / System Info / Logs tabs, live stats, an
a responsive layout - Animated startup splash with purple→green shimmer across the bitpingd
logo - Interactive login form (email / password / MFA) on TTYs, with pre-fill
fromBITPING_EMAIL/BITPING_PASSWORD/BITPING_MFA - Press
einside the TUI to export logs (editable path, defaults to
~/.bitpingd/bitpingd_logs_<timestamp>.txt) - System Info shows peer ID, bandwidth, node health (Super Node / Node
Issues), and per-protocol bandwidth class - Coloured, multi-line error messages for headless operators — tells you
what to do next instead of dumping a stack trace - Fatal config errors (missing creds, MFA required, etc.) now exit non-zer
immediately; transient errors keep retrying - Native terminal copy/select now works inside the TUI (mouse capture
removed) - Removed legacy
~/.bitping/credentials.jsonmigration path - Replaced
.unwrap()calls with proper error handling — fewer panics in
production
Bitping Desktop
- New Logs page (with auto-tail, jump-to-latest, and export-to-file)
- Logs entry added to the mobile bottom navigation
- Node health now computed from the real capability matrix (was hardcoded
to "Super Node") - Translations added for
logs,export_logs,exportingacross all 8
supported languages
Networking
- Custom hub handshake behaviour with off-thread validation — auth no
longer blocks the swarm event loop - Multi-hub awareness: hubs share their cluster peer list with nodes; nodes
rotate bootstrap addresses on reconnect for smoother failover - Bogon filtering on observed addresses
Fixes
- ICMP ping reliability fixes
- Settings startup race fixed