How to Configure OpenTelemetry and PostHog Telemetry for Strix
Strix supports both OpenTelemetry (OTEL) span export to Traceloop and anonymized PostHog usage analytics, with each subsystem independently toggleable via environment variables or the ~/.strix/cli-config.json file.
The usestrix/strix repository ships with a built-in telemetry stack that captures execution traces and high-level usage metrics. You can configure OpenTelemetry for distributed tracing and PostHog for product analytics without modifying source code, using only runtime configuration flags.
Understanding Strix Telemetry Flags
Strix evaluates three hierarchical flags defined in strix/config/config.py to determine whether telemetry flows are active. According to the source code, these boolean-ish values are parsed from environment variables or the CLI config file:
- Master switch:
STRIX_TELEMETRY(config key:strix_telemetry) defaults to"1"(enabled) - OpenTelemetry:
STRIX_OTEL_TELEMETRY(config key:strix_otel_telemetry) defaults toNone, falling back to the master switch - PostHog:
STRIX_POSTHOG_TELEMETRY(config key:strix_posthog_telemetry) defaults toNone, falling back to the master switch
In strix/telemetry/flags.py, the helper functions is_otel_enabled() and is_posthog_enabled() check these variables. If any flag resolves to a disabled value (0, false, no, or off), that telemetry path is silently skipped.
Configuring OpenTelemetry (Traceloop)
When the Tracer class initializes in strix/telemetry/tracer.py (lines 48-82), it inspects the OTEL flag and conditionally invokes _setup_telemetry() (lines 114-121). This method performs two distinct export configurations based on your environment.
Local-Only JSONL Export
By default, Strix writes spans to a local JSON Lines file. The bootstrap_otel() function in strix/telemetry/utils.py (lines 337-445) creates a simple exporter that appends each span to events.jsonl inside the current run directory.
Remote Export via Traceloop
To forward spans to a remote collector, provide both a base URL and API key. The tracer reads traceloop_base_url and traceloop_api_key from the global Config object (lines 124-126 in tracer.py). If present, bootstrap_otel() adds an OTLP HTTP exporter and sets the internal _remote_export_enabled flag to True.
Enable remote OpenTelemetry export with these variables:
export STRIX_OTEL_TELEMETRY=1
export STRIX_TRACELOOP_BASE_URL="https://otlp.traceloop.com"
export STRIX_TRACELOOP_API_KEY="your-api-key-here"
If either URL or key is missing, Strix falls back to local-only JSONL output.
Configuring PostHog Analytics
PostHog telemetry lives in strix/telemetry/posthog.py (lines 9-31 and 78-107). When enabled, the library emits anonymized usage events containing no target URLs, source code, or vulnerability details.
Event lifecycle:
- Start:
posthog.start()fires ascan_startedevent capturing model type, scan mode (white-box vs. black-box), interactivity flags, and first-run detection - End: At the conclusion of
main()instrix/interface/main.py(lines 47-53), ascan_endedevent transmits aggregated counts, token usage, and total duration
Disable PostHog while keeping OTEL active:
export STRIX_POSTHOG_TELEMETRY=0
Complete Configuration Example
The following shell script demonstrates a fully enabled telemetry stack with remote OTEL export:
#!/usr/bin/env bash
# Enable all telemetry channels
export STRIX_TELEMETRY=1
export STRIX_OTEL_TELEMETRY=1
export STRIX_POSTHOG_TELEMETRY=1
# Configure remote Traceloop endpoint (omit for local-only)
export STRIX_TRACELOOP_BASE_URL="https://otlp.traceloop.com"
export STRIX_TRACELOOP_API_KEY="my-secret-key"
# Execute scan
strix --target https://example.com --scan-mode quick
After execution, verify that ./strix_runs/<run-name>/events.jsonl contains OTEL spans, and check your Traceloop dashboard for remote traces.
Verifying Your Telemetry Configuration
You can inspect the active configuration at runtime using the public API from strix/telemetry/flags.py:
from strix.telemetry.flags import is_otel_enabled, is_posthog_enabled
print("OTEL enabled:", is_otel_enabled()) # Checks STRIX_OTEL_TELEMETRY
print("PostHog enabled:", is_posthog_enabled()) # Checks STRIX_POSTHOG_TELEMETRY
To confirm whether remote export is active for the current tracer instance:
from strix.telemetry.tracer import get_global_tracer
tracer = get_global_tracer()
if tracer:
print("Remote OTEL export:", tracer._remote_export_enabled)
Summary
- Three-tier controls: The master
STRIX_TELEMETRYflag governs both subsystems, whileSTRIX_OTEL_TELEMETRYandSTRIX_POSTHOG_TELEMETRYallow fine-grained overrides. - Dual OTEL modes: OpenTelemetry spans write locally to
events.jsonlby default; supplySTRIX_TRACELOOP_BASE_URLandSTRIX_TRACELOOP_API_KEYto enable remote OTLP export. - Privacy-first analytics: PostHog captures only high-level metadata (
scan_started,scan_ended) with zero code or vulnerability payload transmission. - Runtime verification: Use
is_otel_enabled(),is_posthog_enabled(), and the tracer's_remote_export_enabledattribute to audit active exporters programmatically.
Frequently Asked Questions
How do I completely disable all telemetry in Strix?
Set the master switch to 0, false, no, or off:
export STRIX_TELEMETRY=0
This disables both OpenTelemetry and PostHog regardless of their individual flag values, as implemented in strix/telemetry/flags.py.
Can I use OpenTelemetry without sending data to a remote collector?
Yes. Simply omit STRIX_TRACELOOP_BASE_URL and STRIX_TRACELOOP_API_KEY. The bootstrap_otel() function in strix/telemetry/utils.py will initialize only the local JSONL exporter, writing spans to events.jsonl in your run directory without network transmission.
What data does PostHog receive during a scan?
PostHog receives anonymized aggregate metrics only. According to strix/telemetry/posthog.py and strix/interface/main.py, events include the LLM model name, scan mode classification, token counts, and duration—but never the target URL, source code under review, or identified vulnerabilities.
Where does Strix store the local OTEL span data?
Spans are written to events.jsonl inside the specific run directory (typically ./strix_runs/<run-name>/). This path is determined during Tracer initialization in strix/telemetry/tracer.py, where the JSONL exporter is configured alongside any remote OTLP endpoints.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →