feat(analytics): emit PostHog product-analytics events#797
Draft
EDsCODE wants to merge 1 commit into
Draft
Conversation
Add per-org product-analytics event tracking to PostHog, gated on the existing POSTHOG_API_KEY (separate from the OTLP log export). Events use PostHog group analytics keyed on the "organization" group type. Events: - warehouse_provisioned / warehouse_deprovisioned / warehouse_password_reset (admin provisioning API success paths) - query_initiated (logQueryStarted) and query_failed (logQueryError), the latter carrying SQLSTATE + a user/system/conflict error category New internal/analytics package wraps posthog-go behind a Tracker interface with a no-op default; cliboot.InitAnalytics installs the real tracker when POSTHOG_API_KEY is set and is wired into the standalone and control-plane entrypoints. Capture is async/batched so it stays off the query latency path. No SQL text or secrets are ever sent — only metadata. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds per-org product-analytics event tracking to PostHog, gated on the existing
POSTHOG_API_KEY. This is separate from the OTLP log export (which ships slog records to PostHog Logs) — these are discrete product events you can build insights and dashboards on. WhenPOSTHOG_API_KEYis unset, nothing is sent.Events are attributed to an org via PostHog group analytics:
distinct_id = org, group typeorganization. Standalone (no org) →distinct_id = "standalone", no group. No SQL text, credentials, or secret values are ever sent — only metadata.Events
warehouse_provisioneddatabase_name,metadata_store,ducklake_enabled,iceberg_enabledwarehouse_deprovisionedwarehouse_password_resetusernamequery_initiateduser,trace_idquery_faileduser,trace_id,error_code(SQLSTATE),error_category(user/system/conflict/metadata_connection_lost)Changes
internal/analyticspackage:Trackerinterface (Capture/Close) overposthog-go, with a no-op default and a global installed viaSetDefault(mirrors theslog.SetDefaultpattern so call sites are unconditional). Capture is async/batched, so it never blocks the query path.cliboot.InitAnalytics: reads the samePOSTHOG_API_KEY/POSTHOG_HOSTas log export; installs the real tracker when the key is set, returns a flush-on-shutdown. Wired intomain.go(standalone + process control-plane) andcmd/duckgres-controlplane/main.go(remote/k8s). The child-worker path is intentionally left untouched (no client connections / admin API there).controlplane/provisioning/api.go, emitted only on the success path of each handler.server/conn.go:query_initiatedinlogQueryStarted,query_failedinlogQueryError(reusing the existing severity classification forerror_category).tests/e2e-mw-dev/README.mddocuments why PostHog ingestion can't be asserted in-Job and points at the unit coverage.Design notes
query_initiatedvolume scales 1:1 with query throughput. Async batched capture keeps it off the latency path; if volume bites later, theTrackerinterface makes sampling a localized change.POSTHOG_API_KEYlives.Testing
internal/analytics/analytics_test.go— group-analytics mapping, no-org fallback, default/no-op behavior.controlplane/provisioning/analytics_events_test.go— each admin event with properties, and no event emitted on handler failure.server/conn_analytics_test.go— query events + error-category classification.kubernetestags.Rollback
POSTHOG_API_KEYunset the tracker is a no-op, so there is no runtime impact when the key is absent.🤖 Generated with Claude Code