From 39223b2451e3d4685d6df7e29db31bc87b7bfb66 Mon Sep 17 00:00:00 2001 From: Anna Garcia Date: Fri, 11 Sep 2026 13:44:02 -0400 Subject: [PATCH] feat(skills): add tracing skill family Adds a docs-driven tracing skill group (nodejs, nextjs, python, go, java, dotnet, php, ruby, other/OTLP) mirroring the logs and metrics families, and a posthog-tracing marketplace plugin. posthog-node 5.52.0 exports spans natively, so agents get a PostHog-specific route on Node and the OpenTelemetry route everywhere else. Claude-Session: https://claude.ai/code/session_01QPLdjqTgK93WtVxnhx6aVr --- context/marketplace.yaml | 6 +++ context/skills/tracing/config.yaml | 62 ++++++++++++++++++++++++ context/skills/tracing/description.md | 39 +++++++++++++++ scripts/lib/tests/tracing-skills.test.js | 35 +++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 context/skills/tracing/config.yaml create mode 100644 context/skills/tracing/description.md create mode 100644 scripts/lib/tests/tracing-skills.test.js diff --git a/context/marketplace.yaml b/context/marketplace.yaml index a2d3556c..c06cbfaa 100644 --- a/context/marketplace.yaml +++ b/context/marketplace.yaml @@ -48,6 +48,12 @@ plugins: destination: skills/posthog/metrics keywords: [posthog, metrics, observability, opentelemetry] + tracing: + name: posthog-tracing + description: Skills for setting up PostHog distributed tracing + destination: skills/posthog/tracing + keywords: [posthog, tracing, observability, opentelemetry] + error-tracking: name: posthog-error-tracking description: Skills for setting up PostHog error tracking across frameworks diff --git a/context/skills/tracing/config.yaml b/context/skills/tracing/config.yaml new file mode 100644 index 00000000..c15af0f2 --- /dev/null +++ b/context/skills/tracing/config.yaml @@ -0,0 +1,62 @@ +# Tracing skills - docs-only (no example projects) +type: skill +template: description.md +description: PostHog distributed tracing for {display_name} +tags: [tracing] +shared_docs: + - https://posthog.com/docs/distributed-tracing/start-here.md + - https://posthog.com/docs/distributed-tracing/basics.md +variants: + - id: nodejs + display_name: Node.js + tags: [javascript] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/nodejs.md + + - id: nextjs + display_name: Next.js + tags: [nextjs, javascript] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/nextjs.md + + - id: python + display_name: Python + tags: [python] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/python.md + + - id: go + display_name: Go + tags: [go] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/go.md + + - id: java + display_name: Java + tags: [java] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/java.md + + - id: dotnet + display_name: .NET + tags: [dotnet, csharp] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/dotnet.md + + - id: php + display_name: PHP + tags: [php] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/php.md + + - id: ruby + display_name: Ruby + tags: [ruby] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation/ruby.md + + - id: other + display_name: Other Languages + tags: [] + docs_urls: + - https://posthog.com/docs/distributed-tracing/installation.md diff --git a/context/skills/tracing/description.md b/context/skills/tracing/description.md new file mode 100644 index 00000000..a200ae90 --- /dev/null +++ b/context/skills/tracing/description.md @@ -0,0 +1,39 @@ +# PostHog distributed tracing for {display_name} + +This skill helps you send distributed traces from {display_name} applications to PostHog. A trace is a tree of spans that follows one request across services, queues, and external calls, so you can see where the time went and which step failed. + +## Reference files + +{references} + +Consult the documentation for API details and platform-specific patterns. + +## Choose the capture path + +- **Node.js with `posthog-node` >= 5.52.0**: `posthog-node` creates and exports spans itself, with no OpenTelemetry dependency. Set the `traces` option on the existing client and wrap operations in `withSpan` (or `startSpan` for work that can't wrap a callback). +- **OpenTelemetry already in the project**: point its OTLP trace exporter at `/i/v1/traces` on the PostHog host, with the project token as an `Authorization: Bearer` header. Don't add `posthog-node` spans alongside it. +- **Everything else**: use the OpenTelemetry SDK for the language, as the platform reference describes. It is also the only route to auto-instrumentation of HTTP servers, frameworks, and database drivers. + +## Where to instrument + +1. **Request entry**: one server span per handled request, created in middleware or an equivalent single choke point, never per route by hand. +2. **Outbound calls**: HTTP clients, database queries, cache lookups, and queue publishes, so the trace shows which dependency was slow. +3. **Background work**: job and queue handlers, as the root span of their own trace or continuing the trace that enqueued them. + +If the user asks for specific spans, instrument those instead. A few spans at choke points beat a span around every function. + +## Key principles + +- **Environment variables**: Always use environment variables for the PostHog project token, host, and OTLP endpoint. Never hardcode them. +- **Region**: Take the host from the project's existing PostHog configuration. If there is none, ask whether the project is on US Cloud (`https://us.i.posthog.com`) or EU Cloud (`https://eu.i.posthog.com`). Do not assume US Cloud. +- **Minimal changes**: Add spans alongside existing code. Don't replace existing tracing, and if the project already exports to another tracing backend, ask before adding PostHog as a second destination. +- **Service name**: Set a service name at setup (`traces.serviceName` in `posthog-node`, `service.name` in OpenTelemetry) so spans are attributable in the Tracing UI. +- **Span names**: Low-cardinality operation names, like `GET /users/:id` rather than `GET /users/123`. Variable values belong in attributes. +- **Attributes**: Never put secrets, tokens, or passwords in attributes. In `posthog-node`, `beforeSpanSend` can scrub or drop spans before export. +- **Context propagation**: Pass the W3C `traceparent` header on outbound requests between services, so their spans join one trace instead of starting new ones. +- **People and sessions**: A span joins a person or a Session Replay recording through `posthogDistinctId` and `sessionId` attributes. `posthog-node` sets them for spans created inside a PostHog request context (`withContext`, or the Express middleware). With OpenTelemetry, set them yourself from the `X-POSTHOG-DISTINCT-ID` and `X-POSTHOG-SESSION-ID` headers the browser SDK sends when `tracing_headers` is configured. +- **Flushing**: Spans export on an interval. In short-lived processes and serverless handlers, call `flush()` (or the OpenTelemetry provider's `forceFlush()`) before returning, and `shutdown()` only when the process is exiting. + +## Framework guidelines + +{commandments} diff --git a/scripts/lib/tests/tracing-skills.test.js b/scripts/lib/tests/tracing-skills.test.js new file mode 100644 index 00000000..071a96c8 --- /dev/null +++ b/scripts/lib/tests/tracing-skills.test.js @@ -0,0 +1,35 @@ +import { describe, expect, it } from 'vitest'; +import { join } from 'path'; + +import { expandSkillGroups, loadSkillsConfig } from '../skill-generator.js'; + +const CONFIG_DIR = join(process.cwd(), 'context'); + +const SHARED_DOCS = [ + 'https://posthog.com/docs/distributed-tracing/start-here.md', + 'https://posthog.com/docs/distributed-tracing/basics.md', +]; + +describe('tracing skill family', () => { + it('ships one variant per platform, each carrying its installation doc', () => { + const config = loadSkillsConfig(CONFIG_DIR); + const skills = expandSkillGroups(config, CONFIG_DIR).filter((s) => s._group === 'tracing'); + + expect(skills.map((s) => s.id).sort()).toEqual([ + 'tracing-dotnet', + 'tracing-go', + 'tracing-java', + 'tracing-nextjs', + 'tracing-nodejs', + 'tracing-other', + 'tracing-php', + 'tracing-python', + 'tracing-ruby', + ]); + for (const s of skills) { + expect(s._sharedDocs).toEqual(SHARED_DOCS); + } + const nodejs = skills.find((s) => s.id === 'tracing-nodejs'); + expect(nodejs.docs_urls).toEqual(['https://posthog.com/docs/distributed-tracing/installation/nodejs.md']); + }); +});