Skip to content

PostHog observability + product analytics

Problem

.cursor/rules/090-error-handling.mdc previously named Sentry (@sentry/nextjs) as the canonical error-tracking surface, but Sentry was never implemented (no SDK, no sentry.*.config.ts). Meanwhile the platform had no product analytics and no single surface for production errors, server logs, and user-behavior insight.

Both apps ship canonical redacting loggers at src/lib/log.ts (contract in .cursor/rules/091-structured-logging.mdc), but their output only reached console.*.

Proposal

Adopt PostHog (US Cloud) as the single observability platform, delivered through a config-injected shared package @open-learning-hub/observability:

  1. Package exposes ./client, ./server, ./otel, ./log-sink, and ./config (source-first, reads no process.env).
  2. Product analytics via posthog-js (browser) and posthog-node (server), gated by a consent banner with privacy-safe defaults (memory persistence until opt-in, autocapture/session-recording off, DNT respected, identified_only).
  3. Error tracking via error.tsx / global-error.tsx (client) and a captureException seam (server, e.g. reportCmsError).
  4. Server logs forwarded to PostHog via an OpenTelemetry log-sink seam wired in instrumentation.ts (Node runtime only), preserving log.ts Edge-safety and redaction.
  5. Flush batched server data with after() + flushObservability().
  6. Canonical policy in .cursor/rules/092-analytics-observability.mdc; rollout docs in apps/{cms,lms}/docs/admin/observability.md.

Acceptance criteria

  • Shared @open-learning-hub/observability package with client/server/otel/log-sink/config entries.
  • Consent gate + privacy defaults shipped in both apps.
  • Client + server error capture wired.
  • Server logs forwarded via OpenTelemetry log-sink seam (Node runtime only).
  • PII redaction preserved (logger output reused).
  • Rules 090/091 updated, rule 092 added; admin observability docs added.
  • npm run check + npm run test:coverage pass.

Out of scope (follow-ups)

  • Session replay, dashboards/funnels config, feature flags, and A/B testing.
  • Migrating CLI/seed/migrate script logging.
  • Extracting the logger into @open-learning-hub/server (stays with T-006).

Notes / decisions log

  • 2026-05-24: Ticket created (Sentry rollout). Deferred per product priorities.
  • 2026-07-18: Re-scoped to PostHog observability + product analytics; moved to active. Confirmed decisions: docs + implementation, OpenTelemetry server-log forwarding, US Cloud, shared package, consent gate now.