feat(fips): fallback telemetry — per-reason counters in fips.status + last-transport recording on all dial sites
Phase A2 of docs/FIPS-UPTIME-AND-UI-STATE-PLAN.md (RC6). Fallbacks to Tor were debug!-only and uncounted, so "FIPS uptime" was unfalsifiable and paths that were 100% Tor by construction went unnoticed for months. - fips::telemetry: process-lifetime counters for FIPS successes and the six fallback reasons (no_npub, service_inactive, dns_fail, connect_fail, http_404, http_5xx), exposed as `dial_stats` in fips.status - dial.rs: every fallback branch now counts + logs at info! with a `reason` field (resolve/connect/status branches) - PeerRequest::record_transport(data_dir): opt-in hook that writes the transport actually used to federation storage off the hot path — wired into the dial sites that never recorded (DWN sync ×3, mesh blob fetch, federation deploy notify, onion-rotation notify, node messages via a new send_to_peer data-dir param) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
eb2fc0f37b
commit
e24e0a6473
@@ -465,6 +465,7 @@ impl RpcHandler {
|
||||
signing_key.as_ref().map(|i| i.signing_key()),
|
||||
Some(&peer.pubkey),
|
||||
data.server_info.name.as_deref(),
|
||||
Some(&self.config.data_dir),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -866,7 +866,8 @@ impl RpcHandler {
|
||||
)
|
||||
.service(crate::settings::transport::PeerService::Peers)
|
||||
.timeout(std::time::Duration::from_secs(30))
|
||||
.fips_timeout(std::time::Duration::from_secs(6));
|
||||
.fips_timeout(std::time::Duration::from_secs(6))
|
||||
.record_transport(&self.config.data_dir);
|
||||
|
||||
match req.send_json(&body).await {
|
||||
Ok((resp, transport)) if resp.status().is_success() => {
|
||||
|
||||
@@ -13,7 +13,14 @@ use anyhow::Result;
|
||||
impl RpcHandler {
|
||||
pub(super) async fn handle_fips_status(&self) -> Result<serde_json::Value> {
|
||||
let status = fips::FipsStatus::query(&self.config.data_dir).await;
|
||||
Ok(serde_json::to_value(status)?)
|
||||
let mut v = serde_json::to_value(status)?;
|
||||
// Dial outcome counters (process-lifetime): how often peer dials
|
||||
// used FIPS vs fell back to Tor, broken down by reason. This is
|
||||
// the observability that makes "FIPS uptime" measurable.
|
||||
if let Some(obj) = v.as_object_mut() {
|
||||
obj.insert("dial_stats".to_string(), fips::telemetry::snapshot());
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
/// Everything the companion app needs to join this node's mesh, embedded
|
||||
|
||||
@@ -821,6 +821,7 @@ impl RpcHandler {
|
||||
.service(crate::settings::transport::PeerService::MeshFileSharing)
|
||||
.timeout(std::time::Duration::from_secs(120))
|
||||
.fips_timeout(std::time::Duration::from_secs(8))
|
||||
.record_transport(&self.config.data_dir)
|
||||
.send_get()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Fetch failed: {}", e))?;
|
||||
|
||||
@@ -137,6 +137,7 @@ impl RpcHandler {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(&self.config.data_dir),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -225,6 +226,7 @@ impl RpcHandler {
|
||||
signing_key.as_ref().map(|i| i.signing_key()),
|
||||
Some(&req.from_pubkey),
|
||||
data.server_info.name.as_deref(),
|
||||
Some(&self.config.data_dir),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -133,6 +133,7 @@ impl RpcHandler {
|
||||
Some(node_id.signing_key()),
|
||||
recipient_pubkey.as_deref(),
|
||||
node_name.as_deref(),
|
||||
Some(&self.config.data_dir),
|
||||
)
|
||||
.await?;
|
||||
Ok(serde_json::json!({ "ok": true, "sent_to": onion }))
|
||||
|
||||
@@ -499,7 +499,8 @@ pub(super) async fn notify_federation_peers_address_change(
|
||||
)
|
||||
.service(crate::settings::transport::PeerService::Peers)
|
||||
.timeout(std::time::Duration::from_secs(30))
|
||||
.fips_timeout(std::time::Duration::from_secs(6));
|
||||
.fips_timeout(std::time::Duration::from_secs(6))
|
||||
.record_transport(data_dir);
|
||||
match req.send_json(&payload).await {
|
||||
Ok((_, transport)) => {
|
||||
info!(peer_did = %peer.did, transport = %transport, "Notified peer of address change")
|
||||
|
||||
Reference in New Issue
Block a user