From 8c5759a75c84a3d579f836fa3ef270bacf873078 Mon Sep 17 00:00:00 2001 From: Daniel Visca Date: Mon, 20 Jul 2026 12:57:29 -0700 Subject: [PATCH 1/3] feat(skills): add instrument-metrics skill family Adds the metrics sibling of the logs skill family: per-platform variants (Web JavaScript, Node.js, Python, Other Languages) plus an aggregated omnibus/instrument-metrics skill, and a posthog-metrics plugin mapping in marketplace.yaml. The skill teaches agents to add posthog.metrics capture alongside existing Prometheus/StatsD/OTel instrumentation and to add new metrics where they belong, with cardinality and metric-type guidance. Generated-By: PostHog Code Task-Id: 470062dd-05c0-40bf-bfa3-bc89b194121e --- context/marketplace.yaml | 6 ++ context/skills/metrics/config.yaml | 32 ++++++++++ context/skills/metrics/description.md | 16 +++++ .../omnibus/instrument-metrics/config.yaml | 18 ++++++ .../omnibus/instrument-metrics/description.md | 59 +++++++++++++++++++ 5 files changed, 131 insertions(+) create mode 100644 context/skills/metrics/config.yaml create mode 100644 context/skills/metrics/description.md create mode 100644 context/skills/omnibus/instrument-metrics/config.yaml create mode 100644 context/skills/omnibus/instrument-metrics/description.md diff --git a/context/marketplace.yaml b/context/marketplace.yaml index 5c55fd6f..9aa00bce 100644 --- a/context/marketplace.yaml +++ b/context/marketplace.yaml @@ -36,6 +36,12 @@ plugins: destination: skills/posthog/logs keywords: [posthog, logs, logging, observability] + metrics: + name: posthog-metrics + description: Skills for setting up PostHog metric capture + destination: skills/posthog/metrics + keywords: [posthog, metrics, observability, opentelemetry] + error-tracking: name: posthog-error-tracking description: Skills for setting up PostHog error tracking across frameworks diff --git a/context/skills/metrics/config.yaml b/context/skills/metrics/config.yaml new file mode 100644 index 00000000..e502adc0 --- /dev/null +++ b/context/skills/metrics/config.yaml @@ -0,0 +1,32 @@ +# Metrics skills - docs-only (no example projects) +type: skill +template: description.md +description: PostHog metrics for {display_name} +tags: [metrics] +shared_docs: + - https://posthog.com/docs/metrics/start-here.md + - https://posthog.com/docs/metrics/basics.md +variants: + - id: javascript + display_name: Web (JavaScript) + tags: [javascript_web, javascript] + docs_urls: + - https://posthog.com/docs/metrics/installation/javascript.md + + - id: nodejs + display_name: Node.js + tags: [javascript] + docs_urls: + - https://posthog.com/docs/metrics/installation/nodejs.md + + - id: python + display_name: Python + tags: [python] + docs_urls: + - https://posthog.com/docs/metrics/installation/python.md + + - id: other + display_name: Other Languages + tags: [] + docs_urls: + - https://posthog.com/docs/metrics/installation/other.md diff --git a/context/skills/metrics/description.md b/context/skills/metrics/description.md new file mode 100644 index 00000000..e56d0a0e --- /dev/null +++ b/context/skills/metrics/description.md @@ -0,0 +1,16 @@ +# PostHog metrics for {display_name} + +This skill helps you add PostHog metric capture (counters, gauges, and histograms) to {display_name} applications. + +## Reference files + +{references} + +Consult the documentation for API details and platform-specific patterns. + +## Key principles + +- **Environment variables**: Always use environment variables for PostHog keys and OpenTelemetry endpoints. Never hardcode them. +- **Minimal changes**: If the codebase already records metrics (Prometheus, StatsD, Datadog, OpenTelemetry), add the PostHog call alongside the existing one, reusing the same metric name and attributes. Don't replace or restructure existing instrumentation. +- **Metric types**: Counters for things that only go up, gauges for values that go up and down, histograms for distributions like durations. Pick the type that matches what's measured. +- **Low cardinality**: Attributes like `route`, `status`, or `plan` are good; user IDs, session IDs, request IDs, and timestamps are not. Every unique attribute combination creates a new series. diff --git a/context/skills/omnibus/instrument-metrics/config.yaml b/context/skills/omnibus/instrument-metrics/config.yaml new file mode 100644 index 00000000..4f474e00 --- /dev/null +++ b/context/skills/omnibus/instrument-metrics/config.yaml @@ -0,0 +1,18 @@ +# Aggregated metrics skill - all platforms in one skill +type: skill +template: description.md +category: metrics +description: Add PostHog metric capture to track counters, gauges, and histograms. Use after implementing features or reviewing PRs to ensure key operations are measured, or when asked to add metrics, counters, or track a value over time. Also handles mirroring existing Prometheus/StatsD/OpenTelemetry metrics into PostHog and initial OTLP exporter setup. +tags: [metrics] +shared_docs: + - https://posthog.com/docs/metrics/start-here.md + - https://posthog.com/docs/metrics/basics.md +variants: + - id: all + display_name: all supported platforms + tags: [] + docs_urls: + - https://posthog.com/docs/metrics/installation/javascript.md + - https://posthog.com/docs/metrics/installation/nodejs.md + - https://posthog.com/docs/metrics/installation/python.md + - https://posthog.com/docs/metrics/installation/other.md diff --git a/context/skills/omnibus/instrument-metrics/description.md b/context/skills/omnibus/instrument-metrics/description.md new file mode 100644 index 00000000..5e8c4a1c --- /dev/null +++ b/context/skills/omnibus/instrument-metrics/description.md @@ -0,0 +1,59 @@ +# Add PostHog metric capture + +Use this skill to add PostHog metric capture (counters, gauges, and histograms) for new or changed code. Use it after implementing features or reviewing PRs to ensure key operations are measured, when the user asks to add metrics or counters, or to mirror existing metrics instrumentation into PostHog. Supports any platform or language. + +Supported platforms: Web (JavaScript), Node.js, Python via the `posthog.metrics` SDK API, and any language via OpenTelemetry (OTLP). + +## Instructions + +Follow these steps IN ORDER: + +STEP 1: Analyze the codebase and detect the platform. + - Detect the language, framework, and existing metrics setup. + - Look for dependency files and project files (package.json, requirements.txt, pyproject.toml, go.mod, pom.xml, etc.). + - Look for existing metrics instrumentation: Prometheus clients (prom-client, prometheus_client), StatsD/Datadog clients, OpenTelemetry meters, or an OpenTelemetry Collector config. + - Check whether a PostHog SDK (posthog-js, posthog-node, posthog-python) is already installed. + +STEP 2: Choose the capture path. + - If a PostHog SDK is installed (or the platform supports one), use the `posthog.metrics` API — no OpenTelemetry packages needed. Read the matching platform reference now. + - If the codebase already exports OpenTelemetry metrics, point the existing OTLP metrics exporter (or Collector) at PostHog instead — read the "Other Languages" reference. No application code changes needed beyond exporter config. + - If neither applies, use the "Other Languages" reference as a fallback — it covers the generic OpenTelemetry approach. + +STEP 3: Instrument alongside existing metrics. + - Where the codebase already records a metric (a Prometheus counter, a StatsD call, an OTel instrument), add the PostHog call next to the existing one, reusing the same metric name and attributes. Do NOT remove or restructure the existing instrumentation. + - Do not alter the fundamental architecture of existing files. Make additions minimal and targeted. + - You must read a file immediately before attempting to write it. + +STEP 4: Add new metrics where they belong. + - Where the user asked for new metrics, or key operations have no coverage, add PostHog metric calls at the sites they belong: count successes and failures of critical flows, time external calls and jobs with histograms, gauge queue depths and pool sizes. + - Pick the right type: counters for things that only go up, gauges for values that go up and down, histograms for distributions like durations. Set an explicit unit on histograms (`ms`, `bytes`). + - Use stable, descriptive, dot-separated names (`jobs.processed`, `api.request.duration`) and set a service name so systems stay easy to tell apart. + +STEP 5: Keep cardinality low. + - Attributes like `route`, `status`, `plan`, or `queue` are good; user IDs, session IDs, request IDs, and timestamps are not. Every unique attribute combination creates a new series. + - If something needs per-user or per-request detail, that's a job for PostHog logs or traces, not metrics. + +STEP 6: Set up environment variables. (Skip if the PostHog SDK is already configured — `posthog.metrics` reuses the SDK's existing project token.) + - Check if the project already has PostHog environment variables configured (e.g. in `.env`, `.env.local`, or framework-specific env files). If valid values already exist, skip this step. + - If the PostHog project token is missing, use the PostHog MCP server's `projects-get` tool to retrieve the project's `api_token`. If multiple projects are returned, ask the user which project to use. If the MCP server is not connected or not authenticated, ask the user for their PostHog project token instead. + - For the PostHog host URL: check the `projects-get` MCP response for a `region` field — `US` maps to `https://us.i.posthog.com`, `EU` maps to `https://eu.i.posthog.com`. If the region is not available from the MCP response or from existing project configuration, ask the user: "Are you on PostHog US Cloud or EU Cloud?" Do not assume US Cloud. + - For the OTLP metrics endpoint, use `https://us.i.posthog.com/i/v1/metrics` (US) or `https://eu.i.posthog.com/i/v1/metrics` (EU), matching the region determined above, with the project token as an `Authorization: Bearer` header. + - Write these values to the appropriate env file using the framework's naming convention. + - Reference these environment variables in code instead of hardcoding them. + +STEP 7: Verify metrics arrive. + - For short-lived processes (scripts, cron jobs, serverless), flush before exit (`posthog.metrics.flush()`, or the OTel provider's `forceFlush()`/`shutdown()`). + - Open Metrics in the PostHog sidebar and pick the metric from the name picker; data points should appear within a minute of sending. + +## Reference files + +{references} + +Each platform reference contains specific SDK setup, OTLP configuration, and integration patterns. Find the one matching the user's stack. + +## Key principles + +- **Environment variables**: Always use environment variables for PostHog keys and OpenTelemetry endpoints. Never hardcode them. +- **Minimal changes**: Add PostHog metric capture alongside existing metrics. Don't replace or restructure existing instrumentation. +- **Prefer the SDK**: When a PostHog SDK is present, `posthog.metrics` needs no new packages and no extra authentication. Reserve OTLP setup for codebases already invested in OpenTelemetry or languages without SDK support. +- **Low cardinality**: Every unique attribute combination creates a new series. Attach bounded dimensions like route, status, or plan — never user IDs, session IDs, or request IDs. From 20fa9fbe61db6f69173cbbce8573a61f632722cb Mon Sep 17 00:00:00 2001 From: Daniel Visca Date: Thu, 27 Aug 2026 08:02:39 -0700 Subject: [PATCH 2/3] chore(skills): defer to the metrics skill family that landed on main This branch added context/skills/metrics/ before an equivalent family landed on main, so the two collided. Main's version is the newer one - it gained a Kubernetes variant and the architecture reference - so adopt it verbatim here. That leaves the omnibus skill and the marketplace mapping as this branch's only remaining contribution, and lets main merge in cleanly. Generated-By: PostHog Desktop Task-Id: 8147d9e4-7db5-46a3-a349-6b859021cca7 --- context/skills/metrics/config.yaml | 7 +++++++ context/skills/metrics/description.md | 29 ++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/context/skills/metrics/config.yaml b/context/skills/metrics/config.yaml index e502adc0..ab304f53 100644 --- a/context/skills/metrics/config.yaml +++ b/context/skills/metrics/config.yaml @@ -6,6 +6,7 @@ tags: [metrics] shared_docs: - https://posthog.com/docs/metrics/start-here.md - https://posthog.com/docs/metrics/basics.md + - https://posthog.com/docs/metrics/architecture.md variants: - id: javascript display_name: Web (JavaScript) @@ -25,6 +26,12 @@ variants: docs_urls: - https://posthog.com/docs/metrics/installation/python.md + - id: kubernetes + display_name: Kubernetes + tags: [kubernetes] + docs_urls: + - https://posthog.com/docs/metrics/installation/kubernetes.md + - id: other display_name: Other Languages tags: [] diff --git a/context/skills/metrics/description.md b/context/skills/metrics/description.md index e56d0a0e..5121b9ad 100644 --- a/context/skills/metrics/description.md +++ b/context/skills/metrics/description.md @@ -1,6 +1,6 @@ # PostHog metrics for {display_name} -This skill helps you add PostHog metric capture (counters, gauges, and histograms) to {display_name} applications. +This skill helps you add PostHog application metrics (`posthog.metrics`) to {display_name} applications. Metrics are pre-aggregated, service-level telemetry — counters, gauges, and histograms — distinct from product analytics events. ## Reference files @@ -8,9 +8,28 @@ This skill helps you add PostHog metric capture (counters, gauges, and histogram Consult the documentation for API details and platform-specific patterns. +## Where to instrument + +Metrics measure **operational work**, not user actions. Instrument the places where the service does work, in this priority order: + +1. **Request/response layer**: a `count` per handled request and a `histogram` of request duration, added in middleware or an equivalent single choke point — never per-route by hand. +2. **Background work**: job/queue/task handlers — jobs processed (`count`), job duration (`histogram`), queue depth (`gauge`). +3. **External dependencies**: outbound API calls, database queries, cache lookups — call counts with an outcome attribute, latency histograms. +4. **Business throughput counters**: domain operations completing (orders placed, invoices processed, emails sent) — add the `count` at the single place the operation is committed, next to any existing `capture()` call for the same action. + +If the user asks for specific metrics, instrument those instead. Prefer a few well-placed metrics at choke points (middleware, base handlers, shared clients) over scattering calls through every route or function. + ## Key principles -- **Environment variables**: Always use environment variables for PostHog keys and OpenTelemetry endpoints. Never hardcode them. -- **Minimal changes**: If the codebase already records metrics (Prometheus, StatsD, Datadog, OpenTelemetry), add the PostHog call alongside the existing one, reusing the same metric name and attributes. Don't replace or restructure existing instrumentation. -- **Metric types**: Counters for things that only go up, gauges for values that go up and down, histograms for distributions like durations. Pick the type that matches what's measured. -- **Low cardinality**: Attributes like `route`, `status`, or `plan` are good; user IDs, session IDs, request IDs, and timestamps are not. Every unique attribute combination creates a new series. +- **Environment variables**: Always use environment variables for the PostHog API key and host. Never hardcode them. +- **Minimal changes**: Add metrics alongside existing code. Don't replace existing telemetry (StatsD, Prometheus, OTel) — and if the project already has one of these, ask before adding a parallel system. +- **Configure the client**: Set `service_name` (and environment/version if known) in the metrics config at client init, so series are attributable to this service. +- **Metric types**: `count` for monotonic totals (value defaults to 1, negatives are dropped), `gauge` for point-in-time levels (last value wins), `histogram` for distributions (durations, sizes — pass `unit`, e.g. `"ms"`). +- **Naming**: lowercase dot-namespaced names like `http.requests`, `job.duration`, `orders.placed`. Treat metric names as a contract — define each name in one place, don't scatter variants. +- **Low cardinality only**: attributes must be bounded sets (route pattern, plan, region, outcome). Never user IDs, emails, session IDs, raw URLs, or other unbounded/PII values — each distinct attribute combination is a new series, and there is a per-flush series cap. +- **No per-user context**: metrics carry no `distinct_id`. If the question is "which user did X", that's an event (`capture()`), not a metric. +- **Flushing**: metrics flush on an interval and on client shutdown. For short-lived processes (scripts, serverless), call `flush()`/`shutdown()` before exit or nothing is sent. + +## Framework guidelines + +{commandments} From c47432c4f0c976d0ee7dd9bbcb721f2d05ededf2 Mon Sep 17 00:00:00 2001 From: Daniel Visca Date: Thu, 27 Aug 2026 08:05:21 -0700 Subject: [PATCH 3/3] feat(skills): give the omnibus skill the full metrics doc set The omnibus skill listed the docs that existed when it was written. The metrics family has since gained a Kubernetes installation guide and an architecture reference, so add both - the omnibus skill is meant to cover every platform, and it was silently missing one. Generated-By: PostHog Desktop Task-Id: 8147d9e4-7db5-46a3-a349-6b859021cca7 --- context/skills/omnibus/instrument-metrics/config.yaml | 2 ++ context/skills/omnibus/instrument-metrics/description.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/context/skills/omnibus/instrument-metrics/config.yaml b/context/skills/omnibus/instrument-metrics/config.yaml index 4f474e00..0560e33b 100644 --- a/context/skills/omnibus/instrument-metrics/config.yaml +++ b/context/skills/omnibus/instrument-metrics/config.yaml @@ -7,6 +7,7 @@ tags: [metrics] shared_docs: - https://posthog.com/docs/metrics/start-here.md - https://posthog.com/docs/metrics/basics.md + - https://posthog.com/docs/metrics/architecture.md variants: - id: all display_name: all supported platforms @@ -15,4 +16,5 @@ variants: - https://posthog.com/docs/metrics/installation/javascript.md - https://posthog.com/docs/metrics/installation/nodejs.md - https://posthog.com/docs/metrics/installation/python.md + - https://posthog.com/docs/metrics/installation/kubernetes.md - https://posthog.com/docs/metrics/installation/other.md diff --git a/context/skills/omnibus/instrument-metrics/description.md b/context/skills/omnibus/instrument-metrics/description.md index 5e8c4a1c..0d1f7f3c 100644 --- a/context/skills/omnibus/instrument-metrics/description.md +++ b/context/skills/omnibus/instrument-metrics/description.md @@ -2,7 +2,7 @@ Use this skill to add PostHog metric capture (counters, gauges, and histograms) for new or changed code. Use it after implementing features or reviewing PRs to ensure key operations are measured, when the user asks to add metrics or counters, or to mirror existing metrics instrumentation into PostHog. Supports any platform or language. -Supported platforms: Web (JavaScript), Node.js, Python via the `posthog.metrics` SDK API, and any language via OpenTelemetry (OTLP). +Supported platforms: Web (JavaScript), Node.js, Python via the `posthog.metrics` SDK API, Kubernetes via the metrics agent, and any language via OpenTelemetry (OTLP). ## Instructions