observability/posthog/README.md
PostHog AI Observability exporter for Mastra applications.
npm install @mastra/posthog
The exporter automatically reads credentials from environment variables:
# Required
POSTHOG_API_KEY=phc_...
# Optional
POSTHOG_HOST=https://us.i.posthog.com # or eu.i.posthog.com
import { PosthogExporter } from '@mastra/posthog';
const mastra = new Mastra({
...,
observability: {
configs: {
posthog: {
serviceName: 'my-service',
exporters: [new PosthogExporter()],
},
},
},
});
You can also pass credentials directly:
import { PosthogExporter } from '@mastra/posthog';
const mastra = new Mastra({
...,
observability: {
configs: {
posthog: {
serviceName: 'my-service',
exporters: [
new PosthogExporter({
apiKey: 'phc_...',
host: 'https://us.i.posthog.com', // optional, defaults to US region
}),
],
},
},
},
});
$ai_generation: LLM model calls (MODEL_GENERATION, MODEL_STEP)$ai_span: Operations like tool calls, workflows, and streaming chunks$ai_parent_id$ai_session_idnew PosthogExporter({
apiKey: process.env.POSTHOG_API_KEY,
});
new PosthogExporter({
// Required
apiKey: process.env.POSTHOG_API_KEY,
// Optional: Region/Host
host: 'https://eu.i.posthog.com', // EU region
// or
host: 'https://your-instance.com', // Self-hosted
// Optional: Batching (defaults: flushAt=20, flushInterval=10000)
flushAt: 20, // Batch size before auto-flush
flushInterval: 10000, // Flush interval in milliseconds
// Optional: Serverless mode (auto-configures smaller batches)
serverless: true, // Sets flushAt=10, flushInterval=2000
// Optional: User identification
defaultDistinctId: 'anonymous', // Fallback if no userId in metadata
// Optional: Privacy
enablePrivacyMode: false, // Set to true to exclude input/output from LLM events
});
When deploying to serverless environments (Lambda, Vercel Functions, etc.), enable serverless mode:
new PosthogExporter({
apiKey: process.env.POSTHOG_API_KEY,
serverless: true, // Auto-configures for serverless
});
Important: Always call await mastra.shutdown() before your serverless function exits to flush remaining events.
To exclude sensitive input/output data while still tracking token usage and latency:
new PosthogExporter({
apiKey: process.env.POSTHOG_API_KEY,
enablePrivacyMode: true, // Excludes $ai_input and $ai_output_choices
});
Note: Privacy mode only applies to $ai_generation events. Span events (tool calls, etc.) still include input/output state.
Include metadata in your Mastra spans to enrich PostHog events:
// User identification
{
metadata: {
userId: 'user-123', // → distinctId in PostHog
sessionId: 'session-abc', // → $ai_session_id for grouping
// Custom properties (passed through to PostHog)
environment: 'production',
version: '1.0.0',
}
}
PostHog automatically calculates costs from:
$ai_$ai_trace_id: Group all events in a trace$ai_session_id: Group traces in a session$ai_model: Filter by model (e.g., "gpt-4o")$ai_provider: Filter by provider (e.g., "openai")# Required
POSTHOG_API_KEY=phc_...
# Optional
POSTHOG_HOST=https://us.i.posthog.com # or eu.i.posthog.com