Skip to content

feat(monitoring): single-source PostHog Error Tracking + CLI User-Agent middleware#3640

Merged
PierreBrisorgueil merged 3 commits intomasterfrom
posthog-single-source
May 10, 2026
Merged

feat(monitoring): single-source PostHog Error Tracking + CLI User-Agent middleware#3640
PierreBrisorgueil merged 3 commits intomasterfrom
posthog-single-source

Conversation

@PierreBrisorgueil
Copy link
Copy Markdown
Contributor

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:

  • Delete lib/services/sentry.js + remove @sentry/node from package.json
  • Simplify errorTracker.js to PostHog-only fan-out; collapse captureExceptionPostHogOnly into captureException (no double-reporting risk anymore)
  • Drop sentryService.init() from lib/app.js bootstrap + shutdown
  • Drop sentry: {} config from development.config.js + production.config.js; flip posthog.errorTracking default to true
  • 2 readiness rows: analytics (PostHog API key configured) + errorTracking (PostHog key AND errorTracking===true); replaces monitoring/Sentry row
  • NEW posthog-context.middleware.js: parses @trawlme/cli/<version> in User-Agent, attaches req.posthogContext = { source: 'cli'|'web', cli_version? } — enables CLI source attribution in PostHog analytics without sending credentials
  • Wire middleware in express.js after CORS, before routes
  • analytics.capture() accepts optional req param; merges req.posthogContext into event props when present (backward-compat: req undefined = no-op)

Tests:

  • NEW 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)
  • NEW home.service.unit.tests.js (unit-level readiness checks, no Mongoose dep)
  • Updated errorTracker.unit.tests.js (drop Sentry fan-out cases)
  • Updated home.integration.tests.js (replace monitoring with errorTracking in expected categories)
  • All 1355 unit tests green, lint clean

Test plan

  • CI unit tests green
  • CI integration tests green (readiness endpoint returns errorTracking row instead of monitoring)
  • CodeRabbit review resolved

…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
Copilot AI review requested due to automatic review settings May 10, 2026 12:38
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 10, 2026

Warning

Rate limit exceeded

@PierreBrisorgueil has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 16 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0276f9b2-42d5-4ab0-83c8-1f8a559ef68e

📥 Commits

Reviewing files that changed from the base of the PR and between 3eee971 and 7c9ca41.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (18)
  • MIGRATIONS.md
  • config/defaults/development.config.js
  • config/defaults/production.config.js
  • config/defaults/test.config.js
  • lib/app.js
  • lib/middlewares/posthog-context.middleware.js
  • lib/middlewares/tests/posthog-context.middleware.unit.tests.js
  • lib/services/analytics.js
  • lib/services/errorTracker.js
  • lib/services/express.js
  • lib/services/sentry.js
  • lib/services/tests/analytics.capture.unit.tests.js
  • lib/services/tests/errorTracker.unit.tests.js
  • lib/services/tests/sentry.unit.tests.js
  • modules/home/services/home.service.js
  • modules/home/tests/home.integration.tests.js
  • modules/home/tests/home.service.unit.tests.js
  • package.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch posthog-single-source

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.14%. Comparing base (8db3757) to head (7c9ca41).
⚠️ Report is 2 commits behind head on master.

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     
Flag Coverage Δ
integration 59.14% <81.25%> (+0.21%) ⬆️
unit 64.14% <93.75%> (+0.94%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3eee971...7c9ca41. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

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

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 errorTracker to PostHog-only exception capture.
  • Added posthog-context middleware to attach { source, cli_version } onto req, and extended AnalyticsService.capture() to merge that context into event properties.
  • Updated readiness checks and tests to replace the old monitoring/Sentry readiness row with errorTracking/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 on posthog.apiKey + posthog.errorTracking===true, but the underlying PostHog client is only created when config.posthog.enabled===true (lib/services/analytics.js:init). To avoid reporting errors as "enabled" when the client can never be initialized, consider including posthog.enabled===true in this condition (or alternatively update analytics init semantics so error tracking can work when enabled is false).
const captureException = (err, ctx = {}) => {
  const posthogConfig = config?.posthog ?? {};
  if (posthogConfig.apiKey && posthogConfig.errorTracking === true) {
    analyticsService.captureException(err, ctx);
  }

Comment on lines +173 to +178
// errorTrackingPostHog
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)',
Comment thread lib/services/analytics.js
Comment on lines +64 to 82
* 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 ?? {}),
};
Comment on lines +11 to +13
* 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).
@PierreBrisorgueil PierreBrisorgueil merged commit 131eddf into master May 10, 2026
7 checks passed
@PierreBrisorgueil PierreBrisorgueil deleted the posthog-single-source branch May 10, 2026 13:18
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