Skip to content
PraxisSign in
Knowledge sections

Sentry and PostHog

Env-gated error monitoring and product analytics.

sentryposthogobservability
On this page

Sentry and PostHog activate when configured. Without their variables, neither exports data.

Telemetry export does not depend on either of them: OTEL_EXPORTER_OTLP_ENDPOINT ships traces, metrics, and the canonical log records to any OTLP collector, which remains the supported path for wide-event telemetry. Sentry and PostHog add vendor-native error inboxes and product analytics on top.

Sentry

VariableWhere it works
SENTRY_DSNall three workers (web, api, background)

Server-side, each worker entry is wrapped with the official @sentry/cloudflare SDK (Sentry.withSentry). Without a DSN the SDK initializes disabled: no transport is configured, so nothing leaves the worker.

Every failed wide event becomes one Sentry exception, tagged with service, event, errorKind, and the error's _tag when it has one, and joined back to the request's OTel trace id. The glue lives in packages/logger/src/providers.ts: the same observability seam that owns OTLP export (see packages/logger/AGENTS.md and ADR 0050 for the invocation-scoping rules).

In the browser, the web app lazily loads @sentry/react only when the root route's loader passes a DSN through (DSNs are public ingest identifiers by design). Client-side errors then report to the same project.

Releases are derived from SERVICE_VERSION / GIT_COMMIT_SHA; source-map upload is an explicit non-goal for now.

PostHog

VariableWhere it works
POSTHOG_KEYweb browser analytics + server-side capture
POSTHOG_HOSTOptional; .env.example defaults to https://us.i.posthog.com

Server-side follows PostHog's documented Cloudflare Workers pattern: the official posthog-node client with flushAt: 1 / flushInterval: 0, created per invocation and shut down before the invocation ends: the same invocation-scoped I/O rule ADR 0050 applies to OTLP export. One event per wide-event scope is captured, keyed by the trace id, with service, status, and durationMs properties.

In the browser, posthog-js initializes from the same root-route loader data, with history-based page-view capture suited to the SPA router.