feat(journal): federation protocol doc + delivery observability
Task group 4 of federation-hardening.
4.1 — FEDERATION.md at the repo root: actor discovery (WebFinger, actor,
NodeInfo), object/activity types with real JSON examples (Note, Create,
Delete, the narrow follow-graph inbox), addressing, HTTP-Signature
expectations, the two-layer dedup contract, durable delivery/retry
policy, and blocklist moderation semantics — precise enough for another
implementation to interoperate. Linked from README and docs/architecture.
4.2 — three prom-client metrics + a journal dashboard row:
- `federation_delivery_total{outcome}` — incremented in deliver-activity
(delivered/skipped/failed).
- `federation_inbox_dropped_total{reason}` — incremented at every inbox
drop (duplicate | blocked); this is the counter deferred from task 3.2.
- `federation_queue_depth` — gauge sampled at scrape time in
/api/metrics from PgBossMessageQueue.getDepth(); the restart-loss
regression detector.
Grafana journal.json gains a Federation row (delivery rate, queue depth,
inbox drops); the logs panels shift down to make room.
Verified: dashboard JSON valid; journal typecheck + lint clean; unit
suite 357 passing (route-template guard unaffected).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8f7fd15685
commit
881991ca18
9 changed files with 666 additions and 322 deletions
|
|
@ -48,6 +48,42 @@ export const demoBotSyntheticActivitiesTotal = getOrCreate(
|
|||
}),
|
||||
);
|
||||
|
||||
// --- Federation metrics (spec: federation-operations "Federation delivery
|
||||
// observability") ---------------------------------------------------------
|
||||
|
||||
/** Outbound delivery attempts by outcome (delivered | skipped | failed). */
|
||||
export const federationDeliveryTotal = getOrCreate(
|
||||
"federation_delivery_total",
|
||||
() =>
|
||||
new client.Counter({
|
||||
name: "federation_delivery_total",
|
||||
help: "Outbound federation delivery attempts by outcome",
|
||||
labelNames: ["outcome"] as const,
|
||||
}),
|
||||
);
|
||||
|
||||
/** Inbound activities dropped, by reason (duplicate | blocked). */
|
||||
export const federationInboxDroppedTotal = getOrCreate(
|
||||
"federation_inbox_dropped_total",
|
||||
() =>
|
||||
new client.Counter({
|
||||
name: "federation_inbox_dropped_total",
|
||||
help: "Inbound federation activities dropped before side effects, by reason",
|
||||
labelNames: ["reason"] as const,
|
||||
}),
|
||||
);
|
||||
|
||||
/** Messages waiting in the durable Fedify queue. Set at scrape time by the
|
||||
* metrics route (the restart-loss regression detector). */
|
||||
export const federationQueueDepth = getOrCreate(
|
||||
"federation_queue_depth",
|
||||
() =>
|
||||
new client.Gauge({
|
||||
name: "federation_queue_depth",
|
||||
help: "Messages waiting in the durable Fedify (pg-boss) message queue",
|
||||
}),
|
||||
);
|
||||
|
||||
export const registry = client.register;
|
||||
|
||||
// --- Route label normalization -------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue