Repository navigation
feat(metrics): metrics autocapture for HTTP, database and runtime metrics - #992
DanielVisca wants to merge 5 commits into
Conversation
… metrics
`metrics={"autocapture": True}` starts the installed OpenTelemetry instrumentors with private meter and tracer providers and exports to `/i/v1/metrics`. The packages come from the new `posthog[metrics]` extra.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generated-By: PostHog Desktop
Task-Id: ef9b57c2-47ff-47e6-a509-8873ffe1fab4
posthog-python Compliance ReportDate: 2026-10-08T16:39:10.734437+00:00 ✅ All Tests Passed!121/121 tests passed Capture_V1 Tests✅ 95/95 tests passed View Details
Capture_Ai Tests✅ 5/5 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
Feature_Flags_Local_Evaluation Tests✅ 4/4 tests passed View Details
|
|
[Medium risk] Adds metrics collection for HTTP, database, and runtime operations. The PR is not yet safe to merge because autocapture remains unusable in workers forked after initialization. Reviews (2) · Last reviewed commit: "Merge branch 'main' into posthog/otel-me..." |
Generated-By: PostHog Desktop Task-Id: c0218209-575c-46f0-a201-d0c831e38096
Generated-By: PostHog Desktop Task-Id: c49250e2-d173-455b-8165-d6d3285f87bb
|
Updated this branch from main with a signed merge. This brings in the MCP public API snapshot entry that was missing from the CI merge result. Observed checks now pass locally: make public_api_check, the snapshot script tests, and all 13 metrics autocapture tests. The PR stays in draft for the SDK API and documentation review. |
|
CI is now green on the updated head, including the Public API snapshot check, Python test jobs, and SDK compliance checks. This remains draft because the new autocapture API and its documentation still need review. |
There was a problem hiding this comment.
Not approved yet — waiting on the conditions below.
Re-add the stamphog label to request another review once you have addressed this.
stamphog can't auto-approve this pull request, and the refusal is final. Two gates refused it. The deny-list gate matched deps_toolchain, because pyproject.toml and uv.lock add a new metrics extra and many OpenTelemetry packages. It also matched public_api, because references/public_api_snapshot.txt changed. The tier gate classified the change as T2-never (1094 lines, 8 files, cross-cutting feature), a class that is never auto-approved.
The size gate passed, so splitting the PR won't clear the deny-list match on its own. The next step is to ask a human reviewer to look at it. If you'd like it reviewed in smaller pieces, you could separate the dependency and public API changes from the rest and ask a human to review each.
- 👍 on the PR from greptile-apps[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✗ | matches: deps_toolchain, public_api |
| size | ✓ | 493L, 3F substantive, 1094L/8F incl. docs/generated/snapshots — within ceiling |
| tier | ✗ | classified as T2-never: T2-never (1094L, 8F, cross-cutting, feat) |
| stamphog 2.3.1 | .stamphog/policy.yml @ unknown · reviewed head 3bfa7e1 |
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 2 · PR risk: 0/10 |
Generated-By: PostHog Desktop Task-Id: 10838116-90e2-4d23-af38-8099d7887d07
- Honour send=False in the autocapture export gate. - Strip trailing slashes from the host before building the metrics endpoint. - Set OTEL_SEMCONV_STABILITY_OPT_IN only while the instrumentors load, then restore the process environment. - Limit each synchronous instrument to 2000 attribute sets; send the rest to an otel.metric.overflow series, so user-supplied hosts cannot grow the SDK cache. - After fork, replace the module lock and point the runtime instrumentor at the child process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 10838116-90e2-4d23-af38-8099d7887d07
💡 Motivation and Context
Metrics needs hand-written
client.metrics.*calls today. We want metrics to be the easiest setup: install the SDK, set one flag, and get HTTP, database and runtime metrics.Why: #967 was closed because a hand-rolled HTTP wrapper duplicates OpenTelemetry instrumentation, and PostHog accepts OTLP directly (#914 took the hand-rolled route for runtime metrics). So this change starts the official OpenTelemetry instrumentors for you instead of writing new ones. Companion to PostHog/posthog-js#5149, with the same config shape.
posthog[metrics]extra.opentelemetry-bootstrap -a installadds the instrumentors for the installed libraries; autocapture finds them through theopentelemetry_instrumentorentry points, asopentelemetry-instrumentdoes.http.server.request.duration, seconds), the same names posthog-node sends. Requests to the PostHog host are excluded.db.client.operation.duration. SQLAlchemy spans are not counted, because they wrap a driver span. Only bounded attributes; never the statement.cpython.gc.*fromsystem_metrics(process-level only, no host-widesystem.*).shutdown()exports the last window and uninstruments.telemetry.distro.name=posthog-pythonso we can measure adoption.AppConfig.ready(); Flask: beforeFlask(...)).💚 How did you test it?
posthog/test/test_metrics_autocapture.py(13 tests).ruff,mypy(baseline) andpython -W error -c "import posthog"clean. Full suite: 4155 passed; 2 failures intest/ai/langchain/test_callbacks.pyalso fail onmainin this sandbox (they need network access).hogliwith themetricsintent): a Flask + SQLAlchemy/psycopg2 + redis + requests app. In ClickHouse I sawhttp.server.request.duration(withhttp.route),http.client.request.duration,db.client.operation.duration(postgresql and redis),process.*andcpython.gc.*. No series for the PostHog host.📝 Checklist
If releasing new changes
sampo addto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Connection.executeshortcut; drivers and SQLAlchemy use cursors, so the tests use cursors.Created with PostHog Desktop
🤖 Generated with Claude Code