feat: wire up storage latency metrics, uptime gauge, and config timeouts

Instrument DeliveryService (enqueue, fetch) and KeyService
(key_package_upload, key_package_fetch) with storage latency histogram
recording. Add periodic uptime gauge task (every 15s). Log effective
rpc_timeout_secs, storage_timeout_secs, and webtransport_listen at
startup to eliminate dead_code warnings on EffectiveConfig fields.
This commit is contained in:
2026-03-07 20:30:24 +01:00
parent 3708b8df41
commit 077f48f19c
3 changed files with 29 additions and 0 deletions

View File

@@ -80,12 +80,14 @@ impl DeliveryService {
let mut first_seq = 0;
for (i, dk) in device_keys.iter().enumerate() {
let start = std::time::Instant::now();
let seq = self.store.enqueue(
dk,
&req.channel_id,
req.payload.clone(),
ttl,
)?;
crate::metrics::record_storage_latency("enqueue", start.elapsed());
if i == 0 {
first_seq = seq;
}
@@ -106,12 +108,14 @@ impl DeliveryService {
/// The `recipient_key` should be the device-scoped composite key
/// (`identity_key + device_id`) or bare `identity_key` for single-device.
pub fn fetch(&self, req: FetchReq) -> Result<FetchResp, crate::storage::StorageError> {
let start = std::time::Instant::now();
let messages = if req.limit > 0 {
self.store
.fetch_limited(&req.recipient_key, &req.channel_id, req.limit as usize)?
} else {
self.store.fetch(&req.recipient_key, &req.channel_id)?
};
crate::metrics::record_storage_latency("fetch", start.elapsed());
Ok(FetchResp {
payloads: messages

View File

@@ -32,8 +32,10 @@ impl KeyService {
}
let fingerprint: Vec<u8> = Sha256::digest(&req.package).to_vec();
let start = std::time::Instant::now();
self.store
.upload_key_package(&req.identity_key, req.package)?;
crate::metrics::record_storage_latency("key_package_upload", start.elapsed());
Ok(UploadKeyPackageResp { fingerprint })
}
@@ -43,7 +45,9 @@ impl KeyService {
req: FetchKeyPackageReq,
_auth: &CallerAuth,
) -> Result<FetchKeyPackageResp, DomainError> {
let start = std::time::Instant::now();
let package = self.store.fetch_key_package(&req.identity_key)?;
crate::metrics::record_storage_latency("key_package_fetch", start.elapsed());
Ok(FetchKeyPackageResp {
package: package.unwrap_or_default(),
})

View File

@@ -585,6 +585,27 @@ async fn main() -> anyhow::Result<()> {
}
};
// Log effective timeout and listener configuration for operator visibility.
tracing::info!(
rpc_timeout_secs = effective.rpc_timeout_secs,
storage_timeout_secs = effective.storage_timeout_secs,
drain_timeout_secs = effective.drain_timeout_secs,
webtransport_listen = effective.webtransport_listen.as_deref().unwrap_or("disabled"),
"effective timeouts and listeners"
);
// Periodic uptime gauge: record server uptime every 15 seconds.
{
let start = std::time::Instant::now();
tokio::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(15));
loop {
interval.tick().await;
metrics::record_uptime_seconds(start.elapsed().as_secs_f64());
}
});
}
// capnp-rpc is !Send (Rc internals), so all RPC tasks must stay on a LocalSet.
let local = LocalSet::new();
local