Skip to content

realm-server: thread indexing job_id through prerender for log correlation#4695

Draft
lukemelia wants to merge 1 commit intografana-stack/01-loki-alloy-infrafrom
grafana-stack/02-job-id-correlation
Draft

realm-server: thread indexing job_id through prerender for log correlation#4695
lukemelia wants to merge 1 commit intografana-stack/01-loki-alloy-infrafrom
grafana-stack/02-job-id-correlation

Conversation

@lukemelia
Copy link
Copy Markdown
Contributor

Summary

Threads an x-boxel-job-id HTTP header from the worker through the prerender call chain so all four boxel services tag their log lines with [job: J.R] — the same substring worker error diagnostics already use. After this lands, a single Loki filter

{service=~"realm-server|worker|prerender|prerender-manager"} |= "[job: J.R]"

returns the full multi-service lineage of an indexing job (worker queue events + manager proxy events + prerender HTTP request/response), replacing the realm + time-window correlation that was prone to picking up unrelated concurrent activity on the same realm.

Wiring (worker → prerender-manager → prerender-server)

Layer Change
prerender-constants.ts New PRERENDER_JOB_ID_HEADER constant + sanitizePrerenderJobId() (^[0-9]{1,32}\.[0-9]{1,32}$).
runtime-common/index.ts PrerenderVisitArgs.jobId?: string ("<jobId>.<reservationId>").
runtime-common/index-runner/visit-file.ts Derives jobId from jobInfo and passes it on every prerenderVisit({...}) call.
realm-server/prerender/remote-prerenderer.ts Strips jobId from the JSON:API body (request metadata, not payload schema), attaches it as the header on the outbound fetch.
realm-server/prerender/manager-app.ts Reads inbound header, forwards on upstream fetch, tags proxying/proxied lines + the verbose <--/--> middleware lines.
realm-server/prerender/prerender-app.ts Tags its inline httpLogging middleware.
realm-server/middleware/index.ts Tags the shared httpLogging middleware (also used by realm-server itself).

Notes

  • Header value is sanitized to ^[0-9]{1,32}\.[0-9]{1,32}$ before logging, mirroring the PRERENDER_REQUEST_ID_HEADER pattern.
  • Worker-side prerenderVisit({...}) wrapper explicitly destructures args; future fields added to PrerenderVisitArgs need to be added there too or they'll be silently dropped (this PR adds jobId to the destructure for that reason).

Test plan

  • Restart all four services (realm-server, worker, prerender, prerender-mgr)
  • Trigger an indexing job (e.g., touch a file in a realm to fire an incremental)
  • Verify per-service tagging in /tmp/boxel-logs/:
    for s in worker prerender prerender-manager realm-server; do
      echo "$s.log: $(grep -cE '\[job: [0-9]+\.[0-9]+\]' /tmp/boxel-logs/$s.log) lines tagged"
    done
  • Verify the cross-service Loki filter returns multiple services for one job
  • (Stack: requires observability: fix local Loki ingest stalls and Alloy flush latency #4694 — Loki/Alloy infra fix — for ingest to actually flow)

🤖 Generated with Claude Code

Adds an `x-boxel-job-id` HTTP header that the worker stamps on every
prerender request during indexing, so all four boxel services
(realm-server, worker, prerender, prerender-manager) tag their HTTP
log lines with `[job: J.R]` — the same substring worker error
diagnostics already use. A single Loki filter
`{service=~"realm-server|worker|prerender|prerender-manager"}
|= "[job: J.R]"` then returns the full multi-service lineage of an
indexing job, replacing realm + time-window correlation that was
prone to picking up unrelated concurrent activity on the same realm.

* New constant `PRERENDER_JOB_ID_HEADER = 'x-boxel-job-id'` plus
  `sanitizePrerenderJobId()` mirroring the existing
  `PRERENDER_REQUEST_ID_HEADER` pattern.

* `PrerenderVisitArgs.jobId?: string` (`<jobId>.<reservationId>`).
  `index-runner/visit-file.ts` derives it from `jobInfo` and passes
  it on every `prerenderVisit({...})` call.

* `remote-prerenderer.ts` strips `jobId` out of the JSON:API body
  (it's metadata, not part of the validated payload schema) and
  attaches it as the header on the outbound fetch.

* `manager-app.ts` reads the inbound header, forwards it on the
  upstream fetch to the prerender-server, and tags every
  `proxying`/`proxied` log line plus the (verbose-gated)
  `<--`/`-->` middleware lines with ` [job: J.R]`.

* `prerender-app.ts` and `realm-server/middleware/index.ts` do the
  same for their inline / shared `httpLogging` middleware.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Host Test Results

    1 files      1 suites   1h 45m 58s ⏱️
2 579 tests 2 564 ✅ 15 💤 0 ❌
2 598 runs  2 583 ✅ 15 💤 0 ❌

Results for commit d42ddc7.

Realm Server Test Results

    1 files      1 suites   16m 21s ⏱️
1 261 tests 1 261 ✅ 0 💤 0 ❌
1 339 runs  1 339 ✅ 0 💤 0 ❌

Results for commit d42ddc7.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Threads an indexing jobId correlation identifier through the prerender request chain via an x-boxel-job-id header so realm-server, worker, prerender-manager, and prerender-server can all tag HTTP/proxy log lines with a consistent [job: J.R] substring for cross-service log filtering.

Changes:

  • Extend PrerenderVisitArgs with optional jobId (<jobId>.<reservationId>) and populate it from jobInfo in the index runner.
  • Add PRERENDER_JOB_ID_HEADER + sanitizePrerenderJobId() and propagate the sanitized value through remote-prerenderer → manager → prerender-app.
  • Stamp [job: ...] onto existing request/proxy logging middleware across services when the header is present.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/runtime-common/index.ts Adds jobId?: string to PrerenderVisitArgs to carry indexing correlation metadata.
packages/runtime-common/index-runner/visit-file.ts Derives <jobId>.<reservationId> from jobInfo and passes it into prerenderVisit.
packages/realm-server/prerender/remote-prerenderer.ts Strips jobId from JSON:API body and forwards it as x-boxel-job-id for correlation.
packages/realm-server/prerender/prerender-constants.ts Introduces the job-id header constant and sanitization helper.
packages/realm-server/prerender/prerender-app.ts Reads and sanitizes x-boxel-job-id to tag prerender-server HTTP logs.
packages/realm-server/prerender/manager-app.ts Reads/forwards x-boxel-job-id and tags manager proxy + verbose HTTP logs.
packages/realm-server/middleware/index.ts Tags realm-server shared httpLogging lines when x-boxel-job-id is present.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

export const PRERENDER_JOB_ID_HEADER = 'x-boxel-job-id';

// Sanitize the inbound job-id header. Format is `<digits>.<digits>`
// (job.id + reservation.id, both bigint-shaped); accept up to 64 chars
Comment on lines 74 to +78
let endpoint = new URL(path, prerenderURL);
// jobId is request metadata, not part of the validated body — strip
// it out before sending so the prerender-server's payload schema
// doesn't need to know about it.
let { jobId, ...attributesWithoutJobId } = attributes as Record<
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants