openadapt-telemetry

March 17, 2026 ยท View on GitHub

License: MIT Python 3.10+

Unified telemetry and error tracking for OpenAdapt packages.

Features

  • Unified Error Tracking: Consistent error reporting across all OpenAdapt packages
  • Usage Counters (PostHog): Lightweight product usage events for adoption metrics
  • Privacy-First Design: Automatic PII scrubbing and path sanitization
  • Configurable Opt-Out: Respects DO_NOT_TRACK and custom environment variables
  • Internal Usage Tagging: Explicit flags + CI detection with optional git heuristic
  • GlitchTip/Sentry Compatible: Uses the Sentry SDK for maximum compatibility

Installation

pip install openadapt-telemetry

Or with development dependencies:

pip install openadapt-telemetry[dev]

Quick Start

Initialize Telemetry

from openadapt_telemetry import get_telemetry

# Initialize once at package startup
get_telemetry().initialize(
    dsn="https://xxx@app.glitchtip.com/XXXX",
    package_name="openadapt-mypackage",
    package_version="0.1.0",
)

Capture Exceptions

from openadapt_telemetry import get_telemetry

try:
    risky_operation()
except Exception as e:
    get_telemetry().capture_exception(e)
    raise

Capture Usage Events (PostHog)

from openadapt_telemetry import capture_usage_event

capture_usage_event(
    "agent_run",
    properties={"entrypoint": "oa evals run", "mode": "live"},
    package_name="openadapt-evals",
)

Using Decorators

from openadapt_telemetry import track_errors, track_performance, track_feature

@track_errors()
def process_data(data):
    """Exceptions are automatically captured."""
    return transform(data)

@track_performance("indexing.build_faiss")
def build_index(vectors):
    """Execution time is automatically tracked."""
    return create_index(vectors)

@track_feature("retrieval.add_demo")
def add_demo(demo_id, task):
    """Feature usage is tracked for analytics."""
    save_demo(demo_id, task)

Span Context Manager

from openadapt_telemetry import TelemetrySpan

with TelemetrySpan("indexing", "build_faiss_index") as span:
    span.set_tag("num_vectors", 1000)
    # ... indexing operations ...

Configuration

Environment Variables

VariableDefaultDescription
DO_NOT_TRACK-Universal opt-out (1 = disabled)
OPENADAPT_TELEMETRY_ENABLEDtrueEnable/disable telemetry
OPENADAPT_INTERNALfalseTag as internal usage
OPENADAPT_DEVfalseDevelopment mode
OPENADAPT_INTERNAL_FROM_GITfalseOptional: tag as internal when running from a git checkout
OPENADAPT_TELEMETRY_DSN-GlitchTip/Sentry DSN
OPENADAPT_POSTHOG_PROJECT_API_KEYembedded defaultPostHog ingestion project token (phc_...)
OPENADAPT_POSTHOG_HOSThttps://us.i.posthog.comPostHog ingestion host
OPENADAPT_TELEMETRY_DISTINCT_IDgenerated UUIDStable anonymous identifier override
OPENADAPT_TELEMETRY_TIMEOUT_SECONDS1.0PostHog network timeout
OPENADAPT_TELEMETRY_IN_CIfalseEnable usage events in CI pipelines
OPENADAPT_TELEMETRY_ENVIRONMENTproductionEnvironment name
OPENADAPT_TELEMETRY_SAMPLE_RATE1.0Error sampling rate (0.0-1.0)
OPENADAPT_TELEMETRY_TRACES_SAMPLE_RATE0.01Performance sampling rate
OPENADAPT_TELEMETRY_ANON_SALTgeneratedOptional anonymization salt override (advanced use only)

Configuration File

Create ~/.config/openadapt/telemetry.json:

{
  "enabled": true,
  "internal": false,
  "dsn": "https://xxx@app.glitchtip.com/XXXX",
  "environment": "production",
  "sample_rate": 1.0,
  "traces_sample_rate": 0.01
}

Priority Order

  1. Environment variables (highest priority)
  2. Configuration file
  3. Package defaults (lowest priority)

Opt-Out

To disable telemetry, set either:

# Universal standard
export DO_NOT_TRACK=1

# Or package-specific
export OPENADAPT_TELEMETRY_ENABLED=false

Privacy

What We Collect

CategoryDataPurpose
ErrorsException type, stack traceBug fixing
PerformanceFunction timingOptimization
Feature UsageFeature names, countsPrioritization
EnvironmentOS, Python versionCompatibility

What We Never Collect

  • Screenshots or images
  • Text content or file contents
  • Personal information (names, emails, IPs)
  • API keys or passwords
  • Full file paths with usernames

Automatic Scrubbing

  • File paths have usernames replaced with <user>
  • Sensitive fields (password, token, api_key, etc.) are redacted
  • Email addresses and phone numbers are scrubbed from messages
  • Top-level event messages/logentry strings are scrubbed
  • Tag keys are validated, sensitive/invalid keys are dropped, and values are scrubbed before upload
  • User IDs are HMAC-anonymized before upload (anon:v2:<hash>)
  • send_default_pii is enforced to false by the client

Internal Usage Tagging

Internal/developer usage is automatically detected via:

  1. OPENADAPT_INTERNAL=true environment variable
  2. OPENADAPT_DEV=true environment variable
  3. CI environment detected (GitHub Actions, GitLab CI, etc.)
  4. Optional git repository heuristic when OPENADAPT_INTERNAL_FROM_GIT=true

Filter in GlitchTip:

tag:internal IS false  # External users only
tag:internal IS true   # Internal users only

Development

# Clone and install
git clone https://github.com/OpenAdaptAI/openadapt-telemetry
cd openadapt-telemetry
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=openadapt_telemetry

License

MIT License - see LICENSE for details.