Self-hosted telemetry platform for capturing metrics and crash logs from CLIs, SDKs, and websites
382
A self-hosted telemetry and analytics platform for capturing metrics and crash logs from CLI tools, SDKs, websites, and Docker containers. Features Sankey funnel visualization for tracking user conversion funnels.
The ProductTelemetry SDKs have been extracted into independent packages for easier distribution and maintenance:
@ainvirion/ptelemetrynpm install @ainvirion/ptelemetryptelemetrypip install ptelemetrySee the individual SDK repositories for documentation and examples.
| Layer | Technologies |
|---|---|
| Backend | Python 3.11+, FastAPI, SQLAlchemy 2.0 (async), Alembic, PostgreSQL 16 |
| Frontend | React 19, TypeScript, Vite, Tailwind CSS v4, shadcn/ui, @nivo/sankey |
| Infra | Docker, DigitalOcean App Platform, GitHub Actions CI/CD |
git clone https://github.com/AInvirion/Product-Telemetry.git
cd Product-Telemetry
cp backend/.env.example backend/.env
# Edit backend/.env — set DATABASE_URL, SECRET_KEY, OPS_IP_SALT_SECRET
docker-compose up -d db
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
alembic upgrade head
python scripts/seed_plans.py
python scripts/seed_demo_users.py
uvicorn app.main:app --reload
# API available at http://localhost:8000
cd frontend
npm install
cp .env.example .env
npm run dev
# App available at http://localhost:5173
curl -X POST https://your-instance.com/api/auth/register-org \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "SecurePass123!",
"name": "Your Name",
"org_name": "Your Company",
"project_name": "My App"
}'
Response includes your write_key for event ingestion:
{
"project": {
"write_key": "wk_abc123...",
"read_key": "rk_xyz789..."
}
}
Use the write_key to send events — no JWT required:
curl -X POST https://your-instance.com/api/ingest \
-H "X-Write-Key: wk_abc123..." \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"event_name": "app_started",
"event_type": "lifecycle",
"client_id": "device-uuid-123",
"timestamp": "2026-04-08T12:00:00Z",
"properties": {"version": "1.0.0", "platform": "macos"}
}
]
}'
| Field | Type | Required | Description |
|---|---|---|---|
event_name | string | Yes | Event identifier (e.g., cli_started, export_completed) |
event_type | enum | Yes | One of: lifecycle, usage, error |
client_id | string | Yes | Anonymous device/session identifier |
timestamp | ISO 8601 | Yes | When the event occurred |
properties | object | No | Custom key-value pairs |
| Type | Use Case | Examples |
|---|---|---|
lifecycle | App start/stop, sessions | app_started, app_closed, session_begin |
usage | Feature usage, commands | command_run, export_clicked, file_opened |
error | Errors and exceptions | crash, api_error, validation_failed |
Send up to 100 events per request:
curl -X POST https://your-instance.com/api/ingest \
-H "X-Write-Key: wk_abc123..." \
-H "Content-Type: application/json" \
-d '{
"events": [
{"event_name": "cli_started", "event_type": "lifecycle", "client_id": "user-123", "timestamp": "2026-04-08T12:00:00Z", "properties": {}},
{"event_name": "command_build", "event_type": "usage", "client_id": "user-123", "timestamp": "2026-04-08T12:00:05Z", "properties": {"duration_ms": 1234}},
{"event_name": "cli_finished", "event_type": "lifecycle", "client_id": "user-123", "timestamp": "2026-04-08T12:00:10Z", "properties": {"exit_code": 0}}
]
}'
Response:
{"accepted": 3, "rejected": 0, "errors": []}
Link anonymous client_id to a known user (e.g., after login):
curl -X POST https://your-instance.com/api/identify \
-H "X-Write-Key: wk_abc123..." \
-H "Content-Type: application/json" \
-d '{
"client_id": "device-uuid-123",
"user_id": "[email protected]",
"traits": {"plan": "pro", "company": "Acme Inc"}
}'
# pip install producttelemetry
from producttelemetry import Telemetry
t = Telemetry(write_key="proj_wk_xxx")
t.track("cli.started", event_type="lifecycle")
t.track("command.export", {"format": "csv"})
t.identify(user_id="usr_123")
// npm install @producttelemetry/sdk
import { Telemetry } from '@producttelemetry/sdk';
const t = new Telemetry({ writeKey: 'proj_wk_xxx' });
t.track('sdk.initialized', { type: 'lifecycle' });
t.identify('usr_123');
Users can disable telemetry via:
DO_NOT_TRACK=1--no-telemetry{"telemetry": false}.
├── backend/
│ ├── app/
│ │ ├── api/ # API routes (ingest, analytics, funnels, gdpr)
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ ├── services/ # Business logic
│ │ └── workers/ # Background jobs (APScheduler)
│ └── tests/
├── frontend/
│ └── src/
│ ├── components/ # React components
│ ├── pages/ # Dashboard, funnels, settings
│ └── api/ # API client
├── docs/
│ └── superpowers/specs/ # Design specifications
├── .do/ # DigitalOcean App Platform spec
└── .github/ # CI/CD workflows
# Backend
cd backend
ruff check app/ tests/ # Lint
pytest tests/ -v --cov=app # Test
alembic revision --autogenerate -m "description" # Migration
# Frontend
cd frontend
npm run lint # Lint
npm test # Test
npm run build # Build
Run the complete stack with a single command using our Docker Hub image:
# Quick start (ephemeral secrets - for testing only)
docker-compose -f docker-compose.prod.yml up -d
# Production (with persistent secrets)
cp .env.prod.example .env.prod
# Edit .env.prod - set SECRET_KEY, ENCRYPTION_KEY, etc.
docker-compose -f docker-compose.prod.yml --env-file .env.prod up -d
Default login: [email protected] / Demo1234!
The Docker image includes:
Designed for DigitalOcean App Platform:
main triggers GitHub Actions CI/health verifies deploymentConfigure optional features via environment variables:
| Variable | Default | Description |
|---|---|---|
ENABLE_BILLING | false | Show billing UI (plans, packages, credits, analytics) |
ENABLE_REDIS | false | Use Redis for distributed rate limiting |
ENABLE_AGENTS | false | Enable AI agent features |
ENABLE_SCHEDULER | false | Run background jobs (retention cleanup, etc.) |
Example with billing enabled:
ENABLE_BILLING=true docker-compose -f docker-compose.prod.yml up -d
Copyright (c) 2025-2026 AInvirion LLC. All Rights Reserved.
Content type
Image
Digest
sha256:f0dc6b0b1…
Size
267 MB
Last updated
5 months ago
docker pull ainvirion/ptelemetry-server