Skip to content

fix(api): link bot and worker traces - #95

Merged
rosethornbush merged 4 commits into
mainfrom
fix/otel-tracing
Jul 24, 2026
Merged

fix(api): link bot and worker traces#95
rosethornbush merged 4 commits into
mainfrom
fix/otel-tracing

Conversation

@rosethornbush

@rosethornbush rosethornbush commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • instrument the API Worker with @microlabs/otel-cf-workers and Hono OTEL middleware
  • continue the bot's incoming W3C trace context inside the API
  • write the active OTEL trace and span IDs into API wide-event logs
  • disable duplicate Cloudflare-native API traces while retaining native log export
  • update Wrangler to 4.114.0

Root cause

Cloudflare's native Worker tracing creates a new trace ID instead of accepting trace context propagated from services outside Cloudflare. The bot already injects traceparent, but the API trace was disconnected and Cloudflare's metadata trace ID did not match the application log trace ID.

@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a0d8b65

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown
Contributor Author

@greptile

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 24, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
embedly-docs a0d8b65 Commit Preview URL

Branch Preview URL
Jul 24 2026, 05:43 AM

Copy link
Copy Markdown
Contributor Author

@greptile review

@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR instruments the API Worker with @microlabs/otel-cf-workers and @hono/otel to accept the bot's W3C traceparent header and continue the trace instead of creating a disconnected Cloudflare-native trace. Active span IDs are written into wide-event logs and native CF tracing is disabled while log export is retained.

  • Replaces the manual traceparent header parser with trace.getActiveSpan()?.spanContext(), adding span_id alongside trace_id in structured logs.
  • REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET are no longer passed to p.fetch() and are absent from the regenerated CloudflareBindings type, causing every Reddit scrape to fail at runtime with a 500 error.
  • Wrangler is bumped to 4.114.0 and @microlabs/otel-cf-workers is exact-pinned to 1.0.0-rc.52 (addressing a prior review comment).

Confidence Score: 4/5

Safe to merge after restoring Reddit credential forwarding; the OTEL wiring itself is correct.

The OTEL instrumentation changes are sound — trace context propagation, span ID logging, and the fail-fast OTEL_ENDPOINT guard all work as intended. However, REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET are no longer forwarded to p.fetch(), and the Reddit platform's fetchAccessToken hard-throws when those values are absent, so every Reddit scrape will return a 500 after this lands.

apps/api/src/index.ts — the p.fetch() call and apps/api/worker-configuration.d.ts — the regenerated bindings both need Reddit credentials restored.

Important Files Changed

Filename Overview
apps/api/src/index.ts Adds OTEL instrumentation and propagates active span IDs into logs, but unintentionally drops Reddit credentials from the platform fetch call, breaking Reddit scraping at runtime.
apps/api/worker-configuration.d.ts Regenerated by wrangler types after Wrangler bump; adds OTEL_ENDPOINT and removes REDDIT_CLIENT_ID/REDDIT_CLIENT_SECRET from the bindings interface (deployed secrets are not emitted by typegen, so they must be re-declared manually if still in use).
apps/api/wrangler.jsonc Disables native Cloudflare tracing while keeping log export enabled; clean and intentional.
apps/api/package.json Adds @hono/otel, @microlabs/otel-cf-workers (exact pin), and @opentelemetry/api; bumps wrangler to 4.114.0.

Sequence Diagram

sequenceDiagram
    participant Bot
    participant API as API Worker (instrument wrapper)
    participant Hono as Hono + httpInstrumentationMiddleware
    participant OTLPExporter as OTLP Collector (OTEL_ENDPOINT)
    participant CF as Cloudflare Logs

    Bot->>API: "POST /platforms/scrape traceparent: 00-{traceId}-{spanId}-01"
    Note over API: instrument() reads traceparent,creates child span in same trace
    API->>Hono: next() — span now active
    Hono->>Hono: "spanContext = trace.getActiveSpan().spanContext()"
    Hono->>Hono: "logContext.trace_id = spanContext.traceId logContext.span_id = spanContext.spanId"
    Hono-->>CF: console.info(formatLog(..., logContext))
    API-->>OTLPExporter: export spans (traceId shared with bot)
Loading

Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/api/src/index.ts:109-112
**Reddit credentials silently dropped from platform fetch**

`REDDIT_CLIENT_ID` and `REDDIT_CLIENT_SECRET` were removed from the `p.fetch()` call here. The Reddit platform's `fetchAccessToken` function throws `{ code: 500, message: "Reddit credentials are not configured" }` when either credential is absent (`reddit.ts` lines 13–18), so every Reddit scrape request will fail with a 500 after this change. This removal appears to be a side-effect of regenerating `worker-configuration.d.ts` without the deployed secrets — TypeScript would then flag `c.env.REDDIT_CLIENT_ID` as unknown, prompting their removal. The secrets and their wiring both need to be restored.

Reviews (4): Last reviewed commit: "fix(api): sync worker bindings" | Re-trigger Greptile

Comment thread apps/api/package.json
Comment thread apps/api/src/index.ts Outdated
@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR instruments the API Cloudflare Worker with @microlabs/otel-cf-workers and the Hono OTEL middleware to propagate the bot's W3C trace context (traceparent) through the API, replacing the old manual getTraceId extraction with proper OTEL span context. The wide-event log now carries both trace_id and span_id from the active OTEL span, and Cloudflare's native trace backend is disabled to avoid the conflicting, non-propagated trace ID.

  • instrument(app, config) wraps the default export so the worker picks up the incoming traceparent and initialises the OTEL provider per request using a ResolveConfigFn.
  • httpInstrumentationMiddleware() is added as the first Hono middleware, creating a child HTTP span under the propagated root span; trace.getActiveSpan()?.spanContext() is then used to write the correlated IDs into the wide-event log.
  • Cloudflare's native traces are disabled ("enabled": false) to eliminate the duplicate, disconnected trace ID, while log export is preserved.

Confidence Score: 4/5

Safe to merge — the instrumentation wiring is correct and the API's request-handling logic is unchanged.

The trace propagation approach is sound: instrument() correctly picks up the incoming traceparent and httpInstrumentationMiddleware creates a child HTTP span, so trace.getActiveSpan()?.spanContext() in the route handler reliably returns the correlated IDs. Disabling native CF traces while keeping log export is the right call. The one gap is that OTEL_ENDPOINT is referenced as a non-optional binding but is not wired up in wrangler.jsonc or the generated type file — if the secret is missing in a deployment, span export will fail silently with no compile-time or startup warning.

apps/api/src/index.ts — the manual Bindings type extension for OTEL_ENDPOINT and the absence of that secret from wrangler.jsonc / worker-configuration.d.ts is the only area worth a second look before deploying to a new environment.

Important Files Changed

Filename Overview
apps/api/src/index.ts Core instrumentation change — replaces manual traceparent parsing with proper OTEL span context; OTEL_ENDPOINT binding is typed as non-optional string but has no fallback guard if the secret is absent at runtime
apps/api/wrangler.jsonc Disables native CF traces while keeping log export; correct approach to prevent duplicate disconnected trace IDs
apps/api/package.json Adds @hono/otel, @microlabs/otel-cf-workers, @opentelemetry/api dependencies and bumps wrangler to 4.114.0
pnpm-lock.yaml Lock file updated consistently with package.json changes; workerd and esbuild also bumped as transitive dependencies

Sequence Diagram

sequenceDiagram
    participant Bot
    participant API Worker (instrument wrapper)
    participant Hono httpInstrumentationMiddleware
    participant Route Handler
    participant OTEL Collector

    Bot->>API Worker (instrument wrapper): HTTP request + traceparent header
    Note over API Worker (instrument wrapper): instrument() extracts traceparent,<br/>propagates W3C trace context,<br/>creates root span as child of bot's span
    API Worker (instrument wrapper)->>Hono httpInstrumentationMiddleware: fetch(request, env, ctx)
    Note over Hono httpInstrumentationMiddleware: Creates HTTP child span<br/>under propagated root span
    Hono httpInstrumentationMiddleware->>Route Handler: next()
    Route Handler->>Route Handler: trace.getActiveSpan()?.spanContext()<br/>→ writes trace_id + span_id to log
    Route Handler-->>Hono httpInstrumentationMiddleware: response
    Hono httpInstrumentationMiddleware-->>API Worker (instrument wrapper): response + span end
    API Worker (instrument wrapper)-->>Bot: HTTP response
    API Worker (instrument wrapper)->>OTEL Collector: export spans to env.OTEL_ENDPOINT
Loading

Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/api/src/index.ts:23-28
`OTEL_ENDPOINT` not declared in `wrangler.jsonc` and absent from the generated `CloudflareBindings`

`OTEL_ENDPOINT` is typed as a required `string`, but there is no `vars` or `secrets` entry for it in `wrangler.jsonc`, and `worker-configuration.d.ts` does not include it. If the secret has not been added via `wrangler secret put OTEL_ENDPOINT`, `env.OTEL_ENDPOINT` will be `undefined` at runtime. The `@microlabs/otel-cf-workers` OTLP exporter will then be initialised with `url: undefined`, causing all span exports to fail silently — no traces will reach the collector, but the API itself will continue serving requests. Consider documenting the required `wrangler secret put` step and re-running `cf-typegen` after adding the secret so the binding appears in `CloudflareBindings` rather than needing a manual type extension.

Reviews (2): Last reviewed commit: "fix(api): harden tracing config" | Re-trigger Greptile

Comment thread apps/api/src/index.ts Outdated

Copy link
Copy Markdown
Contributor Author

@greptile

@rosethornbush
rosethornbush marked this pull request as ready for review July 24, 2026 05:48
@rosethornbush
rosethornbush merged commit 475d267 into main Jul 24, 2026
3 checks passed
Comment thread apps/api/src/index.ts
Comment on lines 109 to 112
try {
raw = await p.fetch(id, {
EMBED_USER_AGENT: c.env.EMBED_USER_AGENT,
REDDIT_CLIENT_ID: c.env.REDDIT_CLIENT_ID,
REDDIT_CLIENT_SECRET: c.env.REDDIT_CLIENT_SECRET,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Reddit credentials silently dropped from platform fetch

REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET were removed from the p.fetch() call here. The Reddit platform's fetchAccessToken function throws { code: 500, message: "Reddit credentials are not configured" } when either credential is absent (reddit.ts lines 13–18), so every Reddit scrape request will fail with a 500 after this change. This removal appears to be a side-effect of regenerating worker-configuration.d.ts without the deployed secrets — TypeScript would then flag c.env.REDDIT_CLIENT_ID as unknown, prompting their removal. The secrets and their wiring both need to be restored.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/api/src/index.ts
Line: 109-112

Comment:
**Reddit credentials silently dropped from platform fetch**

`REDDIT_CLIENT_ID` and `REDDIT_CLIENT_SECRET` were removed from the `p.fetch()` call here. The Reddit platform's `fetchAccessToken` function throws `{ code: 500, message: "Reddit credentials are not configured" }` when either credential is absent (`reddit.ts` lines 13–18), so every Reddit scrape request will fail with a 500 after this change. This removal appears to be a side-effect of regenerating `worker-configuration.d.ts` without the deployed secrets — TypeScript would then flag `c.env.REDDIT_CLIENT_ID` as unknown, prompting their removal. The secrets and their wiring both need to be restored.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

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.

1 participant