feat(monitoring): single-source PostHog Error Tracking + CLI User-Agent middleware#3640
feat(monitoring): single-source PostHog Error Tracking + CLI User-Agent middleware#3640PierreBrisorgueil merged 3 commits intomasterfrom
Conversation
…eware - Remove @sentry/node dep + delete lib/services/sentry.js + sentry tests - Simplify errorTracker.js: PostHog-only fan-out, drop Sentry references - Drop sentryService.init() from app.js bootstrap and shutdown - Drop sentry config from development.config.js + production.config.js - Flip posthog.errorTracking default to true - Replace monitoring/Sentry readiness row with errorTracking/PostHog row - NEW posthog-context.middleware.js: parse @trawlme/cli/<ver> UA header - Wire posthogContextMiddleware in express.js after CORS, before routes - analytics.capture() accepts optional req to merge req.posthogContext - NEW posthog-context.middleware.unit.tests.js (7 cases) - NEW home.service.unit.tests.js (readiness unit tests) - Update errorTracker.unit.tests.js and home.integration.tests.js
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (18)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3640 +/- ##
==========================================
+ Coverage 88.92% 89.14% +0.21%
==========================================
Files 135 135
Lines 4661 4641 -20
Branches 1441 1433 -8
==========================================
- Hits 4145 4137 -8
+ Misses 403 392 -11
+ Partials 113 112 -1
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR consolidates error tracking onto PostHog by removing the Sentry integration, updates readiness reporting accordingly, and adds a middleware to enrich analytics with CLI-vs-web request source context derived from the User-Agent.
Changes:
- Removed Sentry dependency/service wiring and simplified
errorTrackerto PostHog-only exception capture. - Added
posthog-contextmiddleware to attach{ source, cli_version }ontoreq, and extendedAnalyticsService.capture()to merge that context into event properties. - Updated readiness checks and tests to replace the old
monitoring/Sentryreadiness row witherrorTracking/PostHog.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Removes direct @sentry/node dependency. |
| package-lock.json | Updates lockfile to reflect Sentry removal and dependency graph changes. |
| modules/home/tests/home.service.unit.tests.js | Adds unit coverage for new readiness categories/rows. |
| modules/home/tests/home.integration.tests.js | Updates integration expectations to use errorTracking readiness category. |
| modules/home/services/home.service.js | Replaces Sentry readiness row with PostHog errorTracking row. |
| lib/services/tests/sentry.unit.tests.js | Deletes Sentry service unit tests. |
| lib/services/tests/errorTracker.unit.tests.js | Updates errorTracker tests for PostHog-only behavior. |
| lib/services/sentry.js | Deletes Sentry service implementation. |
| lib/services/express.js | Wires posthogContextMiddleware into the Express app init sequence. |
| lib/services/errorTracker.js | Simplifies exception capture/setup to PostHog-only. |
| lib/services/analytics.js | Extends capture() to optionally merge req.posthogContext into event properties. |
| lib/middlewares/tests/posthog-context.middleware.unit.tests.js | Adds unit tests for CLI vs web UA parsing and context attachment. |
| lib/middlewares/posthog-context.middleware.js | Introduces middleware that derives PostHog context from User-Agent. |
| lib/app.js | Removes Sentry init/shutdown from bootstrap lifecycle. |
| config/defaults/production.config.js | Removes Sentry config defaults. |
| config/defaults/development.config.js | Removes Sentry config defaults; flips PostHog errorTracking default. |
Comments suppressed due to low confidence (1)
lib/services/errorTracker.js:25
errorTracker.captureException()gates onposthog.apiKey+posthog.errorTracking===true, but the underlying PostHog client is only created whenconfig.posthog.enabled===true(lib/services/analytics.js:init). To avoid reporting errors as "enabled" when the client can never be initialized, consider includingposthog.enabled===truein this condition (or alternatively update analytics init semantics so error tracking can work whenenabledis false).
const captureException = (err, ctx = {}) => {
const posthogConfig = config?.posthog ?? {};
if (posthogConfig.apiKey && posthogConfig.errorTracking === true) {
analyticsService.captureException(err, ctx);
}
| // errorTracking — PostHog | ||
| const errorTrackingEnabled = posthogConfigured && config.posthog?.errorTracking === true; | ||
| checks.push({ | ||
| category: 'monitoring', | ||
| status: sentryConfigured ? 'ok' : 'warning', | ||
| message: sentryConfigured ? 'Sentry configured' : 'Sentry not configured', | ||
| category: 'errorTracking', | ||
| status: errorTrackingEnabled ? 'ok' : 'warning', | ||
| message: errorTrackingEnabled ? 'PostHog $exception capture enabled' : 'PostHog Error Tracking not enabled (set posthog.errorTracking=true)', |
| * When `req` is supplied and `req.posthogContext` is set (by posthogContextMiddleware), | ||
| * its properties (source, cli_version) are merged into event properties so that | ||
| * CLI-originated requests are attributed correctly. | ||
| * | ||
| * @param {Object} params - Event parameters | ||
| * @param {string} params.distinctId - User or anonymous identifier | ||
| * @param {string} params.event - Event name | ||
| * @param {Object} [params.properties] - Additional event properties (win over defaults) | ||
| * @param {import('express').Request} [params.req] - Optional Express request for context injection | ||
| * @returns {void} | ||
| */ | ||
| const capture = ({ distinctId, event, properties = {} } = {}) => { | ||
| const capture = ({ distinctId, event, properties = {}, req } = {}) => { | ||
| if (!client) return; | ||
| if (!distinctId || !event) return; | ||
| const defaults = { | ||
| env: process.env.NODE_ENV || 'development', | ||
| ...(_appTag ? { app: _appTag } : {}), | ||
| ...(req?.posthogContext ?? {}), | ||
| }; |
| * 2. CLI UA without explicit version segment → source:'cli' fallback | ||
| * 3. Web browser UA → source:'web' | ||
| * 4. Missing UA → source:'web' |
| flushAt: 20, | ||
| flushInterval: 10000, | ||
| errorTracking: false, // opt-in: capture exceptions to PostHog (default: off) | ||
| errorTracking: true, // PostHog Error Tracking — active when posthog.apiKey is set |
DeepSeek pre-merge audit P1 finding: development.config.js + production.config.js Sentry blocks were dropped, but test.config.js was missed. No functional break (nothing reads it post-removal), but stale config invites confusion.
DeepSeek pre-merge audit P2 findings: - MIGRATIONS.md: add v10 "Sentry removed" section so /update-project sub-agents understand the propagation expectations (env var drops, @sentry/* dep cleanup, config override removal, posthog.errorTracking opt-in semantics). - analytics.capture.unit.tests.js: add 3 tests covering the new req.posthogContext injection path (merges into defaults, user properties win on conflict, absent req is backward-compat — no source/cli_version leak).
Summary
Sentry removal rationale: PostHog Error Tracking GA now covers 100k exceptions/mo on the free tier (vs Sentry free: 5k/mo), has native session replay linkage, and shares the same SDK/config as product analytics — eliminating a second SaaS account, wrapper, K8s secret, and CI step. Decision documented in
docs/superpowers/plans/2026-05-10-posthog-observability-followups.md.Changes:
lib/services/sentry.js+ remove@sentry/nodefrompackage.jsonerrorTracker.jsto PostHog-only fan-out; collapsecaptureExceptionPostHogOnlyintocaptureException(no double-reporting risk anymore)sentryService.init()fromlib/app.jsbootstrap + shutdownsentry: {}config fromdevelopment.config.js+production.config.js; flipposthog.errorTrackingdefault totrueanalytics(PostHog API key configured) +errorTracking(PostHog key ANDerrorTracking===true); replacesmonitoring/Sentryrowposthog-context.middleware.js: parses@trawlme/cli/<version>inUser-Agent, attachesreq.posthogContext = { source: 'cli'|'web', cli_version? }— enables CLI source attribution in PostHog analytics without sending credentialsexpress.jsafter CORS, before routesanalytics.capture()accepts optionalreqparam; mergesreq.posthogContextinto event props when present (backward-compat:requndefined = no-op)Tests:
posthog-context.middleware.unit.tests.js(7 cases: CLI w/ version, pre-release version, web UA, missing UA, empty UA, curl UA, always calls next)home.service.unit.tests.js(unit-level readiness checks, no Mongoose dep)errorTracker.unit.tests.js(drop Sentry fan-out cases)home.integration.tests.js(replacemonitoringwitherrorTrackingin expected categories)Test plan
errorTrackingrow instead ofmonitoring)