Skip to content

OpenTelemetry: ActivityPub federation metrics#755

Open
dahlia wants to merge 12 commits intofedify-dev:mainfrom
dahlia:feature/otel-meter
Open

OpenTelemetry: ActivityPub federation metrics#755
dahlia wants to merge 12 commits intofedify-dev:mainfrom
dahlia:feature/otel-meter

Conversation

@dahlia
Copy link
Copy Markdown
Member

@dahlia dahlia commented May 5, 2026

This adds OpenTelemetry metrics for core ActivityPub federation paths, covering outbound delivery attempts, permanent delivery failures, HTTP Signature verification failures, and inbox listener processing duration.

Closes #619.

Changes

  • Added federation metric instruments in @fedify/fedify for delivery attempts, delivery duration, permanent delivery failures, signature verification failures, and inbox processing duration.
  • Threaded meterProvider through federation options, contexts, send handling, inbox routing, and queued federation work.
  • Added a queued delivery failure span event so failed outbox jobs expose structured failure attributes before retry or permanent failure handling.
  • Added createTestMeterProvider() and TestMetricRecorder to @fedify/fixture for runtime-agnostic metric assertions.
  • Updated @fedify/testing mock contexts and federation helpers so tests can pass a meter provider explicitly.
  • Documented the new meter provider option and emitted metrics in docs/manual/federation.md, docs/manual/opentelemetry.md, and docs/why.md.
  • Updated CHANGES.md for @fedify/fedify, @fedify/fixture, and @fedify/testing.

Notes

@opentelemetry/sdk-metrics is only used by tests, so it is listed as a development dependency for @fedify/fedify. Runtime code only depends on @opentelemetry/api.

All newly exported APIs added by this PR include @since 2.3.0.

Verification

  • mise check && mise test:deno && mise test:node
  • mise docs:build

dahlia added 4 commits May 5, 2026 20:00
Record OpenTelemetry metrics for delivery attempts, permanent delivery
failures, signature verification failures, and inbox listener processing.
Thread the meter provider through federation contexts so applications and
tests can choose a provider explicitly.

Refs: fedify-dev#619

Assisted-by: gpt-5.5
Describe the new meter provider option, emitted federation metrics, and the
queued delivery failure span event.  Update the changelog and overview copy so
Fedify's OpenTelemetry support covers metrics as well as tracing.

Refs: fedify-dev#619

Assisted-by: gpt-5.5
Add release notes and API documentation for the mock federation meter provider
option exposed by @fedify/testing.

Refs: fedify-dev#619

Assisted-by: gpt-5.5
@dahlia dahlia added this to the Fedify 2.3 milestone May 5, 2026
@dahlia dahlia self-assigned this May 5, 2026
@dahlia dahlia added component/federation Federation object related component/inbox Inbox related component/outbox Outbox related component/otel OpenTelemetry integration labels May 5, 2026
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

@codex review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OpenTelemetry metrics support and wiring: new FederationMetrics, meter-provider option threaded through federation/context/send/inbox/handler/middleware, delivery-failure span-event emission, test meter utilities and noop providers, package/config updates, docs and changelog entries.

Changes

OpenTelemetry metrics and wiring

Layer / File(s) Summary
Configuration & Types
deno.json, pnpm-workspace.yaml, packages/fedify/package.json, packages/fedify/src/federation/federation.ts, packages/fedify/src/federation/context.ts
Add @opentelemetry/sdk-metrics to imports/catalog/devDependencies; introduce meterProvider?: MeterProvider on FederationOptions and Context types.
Core Metrics Engine
packages/fedify/src/federation/metrics.ts
New FederationMetrics builds OpenTelemetry instruments (counters/histograms) and methods: recordDelivery, recordPermanentFailure, recordSignatureVerificationFailure, recordInboxProcessingDuration; exports getFederationMetrics with per-MeterProvider WeakMap cache, plus getRemoteHost and getDurationMs.
Federation wiring / middleware
packages/fedify/src/federation/middleware.ts
FederationImpl stores/exposes meterProvider (falls back to global provider), threads it into send/forward/inbox paths, and exposes ContextImpl.meterProvider.
Send path (implementation & tests)
packages/fedify/src/federation/send.ts, packages/fedify/src/federation/send.test.ts
SendActivityParameters accepts meterProvider; send flow times attempts, tracks final deliverySuccess, records delivery metrics in finally, adjusts span-event attributes (removes activity JSON payload), and tests assert counters/histograms and metric export behavior.
Outbox failure instrumentation
packages/fedify/src/federation/middleware.ts, packages/fedify/src/federation/middleware.test.ts
On send errors, add activitypub.delivery.failed span event with remote host/attempt/permanent-failure/status and record recordPermanentFailure for permanent failures; tests added/updated to assert metrics and span events (including malformed-URL case).
Inbox routing & handler
packages/fedify/src/federation/inbox.ts, packages/fedify/src/federation/handler.ts, packages/fedify/src/federation/handler.test.ts
Add meterProvider to route/handler parameters; wrap listener dispatch with timing and always record activitypub.inbox.processing_duration; signature verification failure paths record activitypub.signature.verification_failure with failure reason and optional remote-host; tests validate metric emissions.
Testing fixtures & utilities
packages/fixture/src/otel.ts, packages/testing/src/context.ts, packages/testing/src/mock.ts
Add createTestMeterProvider() and TestMetricRecorder for metric assertions; provide noopMeterProvider for mocks; thread meterProvider through test/mock contexts and createFederation mocks.
Documentation & Changelog
CHANGES.md, docs/manual/federation.md, docs/manual/opentelemetry.md, docs/why.md
Document meterProvider option, instrumented metric names/attributes, new activitypub.delivery.failed span event, and update changelog/observability wording.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Fed as Federation.sendActivity
    participant HTTP as Remote Inbox (HTTP)
    participant Metrics as FederationMetrics
    participant Meter as MeterProvider

    App->>Fed: sendActivity(activity, meterProvider)
    Fed->>Fed: start timer
    Fed->>Metrics: getFederationMetrics(meterProvider)
    Fed->>HTTP: POST activity to inbox
    alt HTTP OK
        HTTP-->>Fed: 2xx
        Fed->>Metrics: recordDelivery(success=true, duration)
        Metrics->>Meter: record counter/histogram
    else HTTP Error
        HTTP-->>Fed: error status
        Fed->>Metrics: recordDelivery(success=false, duration)
        Metrics->>Meter: record counter/histogram
        alt Permanent failure
            Fed->>Metrics: recordPermanentFailure(status)
            Metrics->>Meter: record permanent_failure counter
        end
        Fed->>Fed: add activitypub.delivery.failed span event
    end
Loading
sequenceDiagram
    participant Queue as Activity Queue
    participant Inbox as routeActivity()
    participant Handler as Registered Listener
    participant Metrics as FederationMetrics
    participant Meter as MeterProvider

    Queue->>Inbox: dispatch activity
    Inbox->>Inbox: start timer
    Inbox->>Handler: listener(context, activity)
    Handler-->>Inbox: completes / throws
    Inbox->>Inbox: compute duration
    Inbox->>Metrics: recordInboxProcessingDuration(type, duration)
    Metrics->>Meter: record histogram
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • fedify-dev/fedify#710 — Modifies send/middleware pipeline; may overlap with outbound instrumentation introduced here.

Suggested labels

dependencies, type/feature

Suggested reviewers

  • 2chanhaeng
  • sij411
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'OpenTelemetry: ActivityPub federation metrics' accurately and concisely summarizes the main change of adding OpenTelemetry metrics instrumentation to ActivityPub federation paths.
Description check ✅ Passed The pull request description is directly related to the changeset, detailing the addition of OpenTelemetry metrics for federation health, meterProvider threading, test utilities, and documentation updates.
Linked Issues check ✅ Passed The PR successfully implements all core objectives from issue #619: adds meterProvider option to createFederation(), instruments required counters and histograms with specified attributes, emits delivery failure span events, threads meterProvider through federation code, adds test utilities, and updates documentation.
Out of Scope Changes check ✅ Passed All changes are in scope: metric instruments and meterProvider threading in @fedify/fedify, test utilities in @fedify/fixture, mock updates in @fedify/testing, and documentation updates align with the stated objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/fedify/src/federation/context.ts`:
- Around line 73-77: The Context interface was changed to require meterProvider
which is a source-breaking minor release; make meterProvider optional on the
Context interface (e.g., change readonly meterProvider: MeterProvider to
readonly meterProvider?: MeterProvider) and ensure any internal creation path
(notably Federation.createContext()) and tests still supply a default
MeterProvider when absent, mirroring how tracerProvider was handled previously
so existing external implementations remain source-compatible.

In `@packages/fedify/src/federation/handler.ts`:
- Around line 998-1002: The signature verification failure metric is only
incremented in the verifyRequestDetailed() failure path; update the code to also
call
getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure(reasonType,
remoteHost) in the other rejection paths that treat the request as a signature
verification failure—specifically in the doesActorOwnKey() mismatch branch and
in the deferred nonce-replay rejection branch—using the same shape of reason
data (type and keyId?.hostname) so all 401 signature-verification rejections are
counted consistently.

In `@packages/fedify/src/federation/metrics.ts`:
- Around line 30-36: Update the counter description for
signatureVerificationFailure to reflect both HTTP Signature and Object Integrity
Proof failures so it isn't misleading: locate the createCounter call that
defines signatureVerificationFailure in metrics.ts and change the description
from "ActivityPub HTTP Signature verification failures." to something like
"Signature verification failures (HTTP Signature and Object Integrity
Proof/OIP)." Ensure any references such as recordSignatureVerificationFailure
(called from handler.ts) remain consistent with the broader description.

In `@packages/fedify/src/federation/middleware.ts`:
- Around line 690-699: The span-event host extraction can throw inside the error
handler because new URL(message.inbox) is unguarded; update the catch-path
around span.addEvent in the code that logs "activitypub.delivery.failed" to
safely compute the host (use a small try/catch or validate message.inbox before
calling new URL) and pass either the host or undefined/fallback into
getRemoteHost so the span logging never throws. Locate the span.addEvent call
and the surrounding error handling (references: span.addEvent, getRemoteHost,
message.inbox, SendActivityError, permanentFailureStatusCodes) and ensure the
extraction is protected so retry and permanent-failure logic always run even if
message.inbox is malformed.

In `@packages/fedify/src/federation/send.test.ts`:
- Around line 515-657: Add assertions that the
"activitypub.delivery.permanent_failure" metric is recorded for
permanent-failure HTTP responses: locate the tests that call sendActivity (e.g.,
the steps labeled for failed responses and the 404/410 paths) and after the
sendActivity/assertRejects call use
recorder.getMeasurements("activitypub.delivery.permanent_failure") to assert
length === 1 (or expected count), value === 1, and attributes like
"activitypub.remote.host" and "activitypub.activity.type" match the test
activity; ensure you clear recorder/hardReset as done for other delivery
metrics.

In `@packages/fedify/src/federation/send.ts`:
- Around line 342-347: Remove the full serialized activity from span events to
avoid leaking user content and double-serialization: in the span.addEvent call
in send.ts (the "activitypub.activity.sent" event that currently references
JSON.stringify(activity)), stop adding "activitypub.activity.json"; keep only
"activitypub.inbox.url" and "activitypub.activity.id" for correlation, and if
you need the serialized body reuse the existing variable that was created
earlier when building the request body (the one at ~Line 263) rather than
calling JSON.stringify(activity) again; if you want payload details for
troubleshooting, only serialize and attach them on delivery failures (e.g., in
the error/failure span event) rather than on successful sends.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d3951be5-d3cf-4393-964b-30336222058a

📥 Commits

Reviewing files that changed from the base of the PR and between ab2fa4a and 33f5f91.

⛔ Files ignored due to path filters (2)
  • deno.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • CHANGES.md
  • deno.json
  • docs/manual/federation.md
  • docs/manual/opentelemetry.md
  • docs/why.md
  • packages/fedify/package.json
  • packages/fedify/src/federation/context.ts
  • packages/fedify/src/federation/federation.ts
  • packages/fedify/src/federation/handler.test.ts
  • packages/fedify/src/federation/handler.ts
  • packages/fedify/src/federation/inbox.ts
  • packages/fedify/src/federation/metrics.ts
  • packages/fedify/src/federation/middleware.test.ts
  • packages/fedify/src/federation/middleware.ts
  • packages/fedify/src/federation/send.test.ts
  • packages/fedify/src/federation/send.ts
  • packages/fedify/src/testing/context.ts
  • packages/fixture/src/otel.ts
  • packages/testing/src/context.ts
  • packages/testing/src/mock.ts
  • pnpm-workspace.yaml

Comment thread packages/fedify/src/federation/context.ts Outdated
Comment thread packages/fedify/src/federation/handler.ts Outdated
Comment thread packages/fedify/src/federation/metrics.ts
Comment thread packages/fedify/src/federation/middleware.ts
Comment thread packages/fedify/src/federation/send.test.ts
Comment thread packages/fedify/src/federation/send.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

Codecov Report

❌ Patch coverage is 77.03016% with 99 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/fixture/src/otel.ts 61.06% 49 Missing and 2 partials ⚠️
packages/testing/src/mock.ts 22.22% 21 Missing ⚠️
packages/testing/src/context.ts 16.66% 20 Missing ⚠️
packages/fedify/src/federation/send.ts 93.61% 2 Missing and 1 partial ⚠️
packages/fedify/src/federation/handler.ts 86.66% 0 Missing and 2 partials ⚠️
packages/fedify/src/federation/metrics.ts 98.09% 0 Missing and 2 partials ⚠️
Files with missing lines Coverage Δ
packages/fedify/src/federation/inbox.ts 75.78% <100.00%> (+1.34%) ⬆️
packages/fedify/src/federation/middleware.ts 96.07% <100.00%> (+0.25%) ⬆️
packages/fedify/src/testing/context.ts 74.66% <100.00%> (+0.34%) ⬆️
packages/fedify/src/federation/handler.ts 79.20% <86.66%> (+0.08%) ⬆️
packages/fedify/src/federation/metrics.ts 98.09% <98.09%> (ø)
packages/fedify/src/federation/send.ts 98.66% <93.61%> (+0.12%) ⬆️
packages/testing/src/context.ts 53.00% <16.66%> (-5.49%) ⬇️
packages/testing/src/mock.ts 74.21% <22.22%> (-1.76%) ⬇️
packages/fixture/src/otel.ts 65.90% <61.06%> (-14.10%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces OpenTelemetry metrics support to Fedify, enabling the tracking of ActivityPub delivery attempts, permanent failures, inbox processing durations, and HTTP signature verification failures. It adds a new meterProvider option to createFederation() and exposes it via the Context object, while also providing new testing utilities like createTestMeterProvider and TestMetricRecorder in the fixture package. A critical issue was identified in packages/fedify/src/federation/send.ts where the activityType property is missing from the SendActivityParameters interface, which will result in a TypeScript compilation error since the property is already being destructured and used in the implementation.

Comment thread packages/fedify/src/federation/send.ts
Make the context meter provider source-compatible for external Context
implementations, count all 401 signature rejection paths, and avoid adding
full activity payloads to successful delivery span events.  Guard queued
failure span attributes so malformed inbox payloads do not break retry logic.

fedify-dev#755 (comment)
fedify-dev#755 (comment)
fedify-dev#755 (comment)
fedify-dev#755 (comment)
fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements OpenTelemetry metrics for ActivityPub delivery, inbox processing, and signature verification. It introduces the meterProvider configuration to createFederation() and the Context interface, supported by a new FederationMetrics utility. Testing infrastructure in @fedify/fixture and @fedify/testing has been expanded with TestMetricRecorder to facilitate metric assertions. Review feedback suggests updating the documentation to reflect the removal of the activity JSON from span events and the addition of new signature verification failure reasons. Additionally, it is recommended to use the getDurationMs helper consistently within the middleware for duration calculations.

Comment thread docs/manual/opentelemetry.md Outdated
Comment thread docs/manual/opentelemetry.md Outdated
Comment thread packages/fedify/src/federation/middleware.ts Outdated
Comment thread packages/fedify/src/federation/middleware.ts Outdated
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

@codex review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/manual/opentelemetry.md (1)

233-237: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

activitypub.activity.sent docs still reference a removed payload attribute.

activitypub.activity.sent no longer includes activitypub.activity.json, but this page still documents it as present.

📝 Suggested docs update
-| `activitypub.activity.sent`     | `activitypub.send_activity` | Records full activity JSON and delivery details when an activity is sent.        |
+| `activitypub.activity.sent`     | `activitypub.send_activity` | Records delivery details when an activity is sent.                                |
...
 **`activitypub.activity.sent` event attributes:**
 
- -  `activitypub.activity.json`: The complete activity JSON being sent
  -  `activitypub.inbox.url`: The inbox URL where the activity was delivered
  -  `activitypub.activity.id`: The activity ID

As per coding guidelines "docs/**/*.md: Update documentation when changing public APIs".

Also applies to: 264-267

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manual/opentelemetry.md` around lines 233 - 237, The docs claim the
event activitypub.activity.sent contains the payload attribute
activitypub.activity.json, but that attribute was removed; update the table rows
for activitypub.activity.sent (and the related lines noted around the second
instance) to remove any reference to activitypub.activity.json and instead
document the current payload contents and recorded span name
activitypub.send_activity (e.g., list the actual fields now emitted and any
verification/delivery details). Ensure the two places referencing
activitypub.activity.json (the table row for activitypub.activity.sent and the
duplicate at lines ~264-267) are edited to reflect the new public API.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/fedify/src/federation/send.test.ts`:
- Around line 589-605: The failure-path metrics assertions in send.test.ts are
missing checks for the "activitypub.remote.host" attribute; update the failure
step (after reading recorder.getMeasurements("activitypub.delivery.sent") into
sent and recorder.getMeasurements("activitypub.delivery.duration") into
durations) to assert that sent[0].attributes["activitypub.remote.host"] and
durations[0].attributes["activitypub.remote.host"] exist and equal the expected
remote host string (the same host used in the success assertions), so host
extraction is validated on the error path as well.
- Around line 589-605: The failure-step assertions in the test are missing
checks for the required attribute "activitypub.remote.host": after retrieving
sent via recorder.getMeasurements("activitypub.delivery.sent") and durations via
recorder.getMeasurements("activitypub.delivery.duration"), add assertions that
sent[0].attributes["activitypub.remote.host"] equals the expected host string
and that durations[0].attributes["activitypub.remote.host"] equals the same
host; update the block that follows fetchMock.hardReset() to include these two
checks so the error path validates host extraction the same way the success step
does.

---

Outside diff comments:
In `@docs/manual/opentelemetry.md`:
- Around line 233-237: The docs claim the event activitypub.activity.sent
contains the payload attribute activitypub.activity.json, but that attribute was
removed; update the table rows for activitypub.activity.sent (and the related
lines noted around the second instance) to remove any reference to
activitypub.activity.json and instead document the current payload contents and
recorded span name activitypub.send_activity (e.g., list the actual fields now
emitted and any verification/delivery details). Ensure the two places
referencing activitypub.activity.json (the table row for
activitypub.activity.sent and the duplicate at lines ~264-267) are edited to
reflect the new public API.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: dd61bfae-d73b-4437-af81-9b0c39524e97

📥 Commits

Reviewing files that changed from the base of the PR and between 33f5f91 and 031172d.

📒 Files selected for processing (9)
  • docs/manual/opentelemetry.md
  • packages/fedify/src/federation/context.ts
  • packages/fedify/src/federation/handler.test.ts
  • packages/fedify/src/federation/handler.ts
  • packages/fedify/src/federation/metrics.ts
  • packages/fedify/src/federation/middleware.test.ts
  • packages/fedify/src/federation/middleware.ts
  • packages/fedify/src/federation/send.test.ts
  • packages/fedify/src/federation/send.ts

Comment thread packages/fedify/src/federation/send.test.ts
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Use the shared duration helper for queued inbox processing metrics and
cover remote host attributes on failed delivery metric assertions.

fedify-dev#755 (comment)
fedify-dev#755 (comment)
fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

/gemini review

Update the ActivityPub send event description now that sent activity
JSON is no longer recorded, and list the new verification failure
reasons in the semantic attribute table.

fedify-dev#755 (comment)
fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces OpenTelemetry metrics support to Fedify, enabling the monitoring of ActivityPub delivery attempts, permanent failures, and inbox processing durations. A new meterProvider option has been added to createFederation(), and the Context interface now exposes this provider to request, inbox, and outbox code. The implementation includes a new FederationMetrics utility for recording counters and histograms, along with testing helpers like createTestMeterProvider() and TestMetricRecorder to facilitate metric verification in runtime-agnostic tests. Documentation and dependency configurations have also been updated to support these observability enhancements. I have no feedback to provide.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/manual/opentelemetry.md`:
- Around line 236-237: The docs for the event activitypub.activity.sent are
inconsistent: update the event-attributes table under the "event-attributes"
section to match the summary that this event records delivery details (or vice
versa); specifically, replace or augment the activitypub.activity.json attribute
listed for activitypub.activity.sent with the delivery-related attributes used
by activitypub.send_activity (e.g., delivery details, recipient, status) so the
attributes listed under activitypub.activity.sent align with the description and
the activitypub.send_activity semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 36e43949-8ef8-4a6e-a2cb-9107e4a6732b

📥 Commits

Reviewing files that changed from the base of the PR and between 8a645d2 and 166150d.

📒 Files selected for processing (1)
  • docs/manual/opentelemetry.md

Comment thread docs/manual/opentelemetry.md
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces OpenTelemetry metrics support to Fedify, enabling the monitoring of ActivityPub delivery attempts, permanent failures, inbox processing durations, and HTTP signature verification failures. It adds a meterProvider option to createFederation() and updates the Context interface to expose this provider. The changes also include documentation updates and new testing utilities, such as TestMetricRecorder, for verifying metric measurements. Feedback suggests including the delivery success status as an attribute in the delivery duration histogram to allow for more granular analysis of performance profiles between successful and failed attempts.

Comment thread packages/fedify/src/federation/metrics.ts
Record delivery success on delivery duration metrics so successful and
failed attempts can be separated in histograms, and remove the stale sent
activity JSON attribute from the OpenTelemetry docs.

fedify-dev#755 (comment)
fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements OpenTelemetry metrics for ActivityPub delivery, inbox processing, and signature verification, introducing a new meterProvider option to the Federation and Context APIs. It also enhances the testing framework with TestMetricRecorder for verifying metric measurements. The review feedback points out a critical missing property, activityType, in the SendActivityParameters interface which will lead to TypeScript compilation errors. Furthermore, the reviewer suggests refactoring the OTel meter initialization to avoid a dependency on deno.json metadata, ensuring better cross-runtime compatibility as per the project's style guidelines.

Comment thread packages/fedify/src/federation/send.ts
Comment thread packages/fedify/src/federation/metrics.ts Outdated
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

@codex review

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/manual/opentelemetry.md (1)

441-455: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stale debug dashboard example — references the now-removed activitypub.activity.json attribute.

This PR removes activitypub.activity.json from the activitypub.activity.sent event (confirmed in send.test.ts line 501 and the updated attribute list at lines 264–268). The outbound branch in the example code still reads that attribute and passes it to JSON.parse():

activity: JSON.parse(
  event.attributes["activitypub.activity.json"] as string
),

At runtime event.attributes["activitypub.activity.json"] is undefined, so JSON.parse(undefined) throws SyntaxError. The activity field in ActivityRecord also can't be populated from the span event any more since the JSON is no longer recorded there — only activitypub.inbox.url and activitypub.activity.id are available.

📝 Proposed fix
       if (event && event.attributes) {
         this.activities.push({
           direction: "outbound",
-          activity: JSON.parse(
-            event.attributes["activitypub.activity.json"] as string
-          ),
           timestamp: new Date(span.startTime[0] * 1000),
+          activityId: event.attributes["activitypub.activity.id"] as string,
+          inboxUrl: event.attributes["activitypub.inbox.url"] as string,
         });
       }

You'll also need to update the ActivityRecord interface (and the activity: unknown field) to match the attributes that are actually available on the activitypub.activity.sent event.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manual/opentelemetry.md` around lines 441 - 455, The example reads and
JSON.parses the removed event attribute "activitypub.activity.json" causing a
runtime SyntaxError; update the outbound branch that checks span.name ===
"activitypub.send_activity" (and the handling of event = span.events.find(...))
to stop accessing event.attributes["activitypub.activity.json"] and instead
populate the ActivityRecord using the actual attributes available on the event
(e.g. event.attributes["activitypub.inbox.url"] and
event.attributes["activitypub.activity.id"]), remove the JSON.parse call, and
update the ActivityRecord interface (and any usage of the activity field) to
reflect the new shape (e.g. inboxUrl: string | undefined, activityId: string |
undefined or activity: { id?: string; inboxUrl?: string } | undefined) so the
code no longer expects the removed JSON attribute.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/fedify/src/federation/send.test.ts`:
- Around line 624-666: The test "sendActivity() exports delivery metrics through
OpenTelemetry SDK" must wrap the cleanup steps in a try/finally so background
timers and global fetch mocks are always cleared; specifically, after creating
PeriodicExportingMetricReader and MeterProvider and calling sendActivity and
meterProvider.forceFlush(), move meterProvider.shutdown() and
fetchMock.hardReset() into a finally block (paired with a try that surrounds the
assertions) so the MeterProvider.shutdown() and fetchMock.hardReset() always run
even if assertions fail.

---

Outside diff comments:
In `@docs/manual/opentelemetry.md`:
- Around line 441-455: The example reads and JSON.parses the removed event
attribute "activitypub.activity.json" causing a runtime SyntaxError; update the
outbound branch that checks span.name === "activitypub.send_activity" (and the
handling of event = span.events.find(...)) to stop accessing
event.attributes["activitypub.activity.json"] and instead populate the
ActivityRecord using the actual attributes available on the event (e.g.
event.attributes["activitypub.inbox.url"] and
event.attributes["activitypub.activity.id"]), remove the JSON.parse call, and
update the ActivityRecord interface (and any usage of the activity field) to
reflect the new shape (e.g. inboxUrl: string | undefined, activityId: string |
undefined or activity: { id?: string; inboxUrl?: string } | undefined) so the
code no longer expects the removed JSON attribute.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d38778b9-4411-4a35-a729-aceb17897792

📥 Commits

Reviewing files that changed from the base of the PR and between 166150d and bb03d95.

📒 Files selected for processing (3)
  • docs/manual/opentelemetry.md
  • packages/fedify/src/federation/metrics.ts
  • packages/fedify/src/federation/send.test.ts

Comment thread packages/fedify/src/federation/send.test.ts
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

dahlia added 2 commits May 6, 2026 01:15
The debug exporter example now records the outbound activity ID and inbox
URL from the sent activity event attributes instead of parsing the removed
activity JSON event attribute.

Assisted-by: gpt-5.5
Add fallback metadata for the federation meter and make the SDK metrics
test always release its meter provider and fetch mock, even when assertions
fail.

fedify-dev#755 (comment)
fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces OpenTelemetry metrics support to Fedify, enabling the monitoring of ActivityPub delivery attempts, permanent failures, inbox processing durations, and HTTP signature verification failures. It adds a meterProvider option to createFederation(), updates the Context interface, and provides new testing utilities like TestMetricRecorder. The reviewer feedback focuses on improving maintainability and consistency by using the centralized getRemoteHost() helper function for hostname extraction in telemetry payloads within handler.ts.

Comment thread packages/fedify/src/federation/handler.ts Outdated
Comment thread packages/fedify/src/federation/handler.ts
Comment thread packages/fedify/src/federation/handler.ts
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 5, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Route signature verification failure metrics through the shared remote host
helper so inbox rejection paths use the same host extraction as delivery
metrics.

fedify-dev#755 (comment)
fedify-dev#755 (comment)
fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 6, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements OpenTelemetry metrics for ActivityPub delivery, inbox processing, and signature verification, while introducing a meterProvider configuration option and exposing it via the Context. It also adds the activitypub.delivery.failed span event and provides new testing helpers in @fedify/fixture for metric assertions. Review feedback suggests maintaining consistency by keeping activity JSON in span events, ensuring cross-runtime compatibility for JSON imports, and adding warning logs for malformed inbox URLs during error handling.

Comment thread packages/fedify/src/federation/send.ts
Comment thread packages/fedify/src/federation/metrics.ts
Comment thread packages/fedify/src/federation/middleware.ts
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 6, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Queue messages with invalid inbox URLs already keep failure telemetry
from crashing.  Log the malformed inbox too, so operators can identify
corrupted outbox messages.

fedify-dev#755 (comment)

Assisted-by: gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 6, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces OpenTelemetry metrics support to Fedify, enabling monitoring of ActivityPub delivery attempts, permanent failures, inbox processing duration, and signature verification errors. It adds a meterProvider option to createFederation() and exposes it through the Context interface. Additionally, new testing helpers like createTestMeterProvider() and TestMetricRecorder are added to @fedify/fixture. Feedback identifies a cross-runtime compatibility issue when importing deno.json in metrics.ts and notes that the removal of the activitypub.activity.json attribute from span events should be documented as a breaking change.

type MeterProvider,
metrics,
} from "@opentelemetry/api";
import metadata from "../../deno.json" with { type: "json" };
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Importing deno.json directly into source code can cause runtime errors in Node.js or Bun environments if the file is not included in the published npm package or if the environment does not support JSON modules with the with syntax (e.g., older versions of Node.js). This violates the project's goal of being framework-agnostic and working across Deno, Node.js, and Bun. Consider hardcoding the package name or using a different mechanism to provide the version that is compatible with all target runtimes.

References
  1. For code intended to run in both Deno and Node.js environments, prefer Node.js APIs over Deno-specific APIs to ensure cross-runtime compatibility.

Comment on lines +343 to +346
span.addEvent("activitypub.activity.sent", {
"activitypub.inbox.url": inbox.href,
"activitypub.activity.id": activityId ?? "",
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The activitypub.activity.json attribute has been removed from the activitypub.activity.sent span event. This is a breaking change for users who rely on this attribute for debugging or auditing sent activities. While removing it may improve performance and reduce trace size, this change is not mentioned in the PR description or CHANGES.md. If this removal is intentional, it should be documented as a breaking change.

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 6, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/federation Federation object related component/inbox Inbox related component/otel OpenTelemetry integration component/outbox Outbox related

Development

Successfully merging this pull request may close these issues.

OpenTelemetry metrics and span events for federation health

1 participant