/ Documentation by XplurData ← Back to home

OTel Studio

Generate realistic OpenTelemetry data for any observability stack

OTel Studio is a Docker-deployable telemetry data generator that produces correlated traces, logs and metrics using realistic service topologies. Point it at any OTel-compatible backend and get production-like data flowing in 60 seconds.

Quick Start

docker run -d --name otel-studio -p 3002:3002 \
  -e OTEL_ENDPOINT="http://your-collector:4317" \
  -e OTEL_PROTOCOL="grpc" \
  -e ADMIN_PASS="your-password" \
  otel-studio:latest

Open http://localhost:3002, log in with admin / your password, enable a scenario and click Start.

OTel Studio uses a slim icon rail on the left to switch between five pages. Each gets the full window width — nothing is squeezed into a sidebar.

The top control bar (Real System Data / Simulation toggles, signal switches, quota timer, Inject Anomaly, global rate multiplier, Start/Stop/Reset) stays visible on every page — these are global controls, not scoped to any one page.

Architecture

OTel Studio
OTLP gRPC / HTTP
OTel Collector
Your Backend

Traces, logs and metrics are sent via standard OTLP protocol — works with any OTel-compatible backend

OTel Studio uses the official OpenTelemetry JS SDK. Each scenario creates a BasicTracerProvider per service name, with one BatchSpanProcessor per active endpoint. Logs use LoggerProvider with one BatchLogRecordProcessor per active endpoint. Metrics use a shared MeterProvider with one PeriodicExportingMetricReader per active endpoint — this is what makes multi-endpoint fanout work for all three signal types, not just traces.

All three signals are correlated — logs emitted during a trace span inherit the span's trace ID and span ID via OpenTelemetry context propagation. This means you can search for a trace ID in your backend and see the matching logs and metrics.

Docker Configuration

docker run -d --name otel-studio -p 3002:3002 \
  -e OTEL_ENDPOINT="http://otelcol:4317" \
  -e OTEL_PROTOCOL="grpc" \
  -e SERVICE_NAME="otel-agent" \
  -e ENVIRONMENT="production" \
  -e ADMIN_PASS="secure-password" \
  -e MODE_REAL="true" \
  -e MODE_SIM="true" \
  -v /var/log:/var/log:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v otel-data:/data \
  --memory=256m \
  otel-studio:latest
JWT_SECRET is optional — if omitted, OTel Studio generates a random one on first boot and persists it in the mounted /data volume, so it stays stable across restarts without needing to be set manually. Pass -e JWT_SECRET="..." explicitly only if you're running multiple replicas that need to share one signing secret.

25 Scenarios

Each scenario simulates a realistic service topology with parent-child span relationships, correlated log records per service, and matching metric instrument recordings.

Web App

ScenarioServicesDescription
E-Commercefrontend → cart → inventory → payment → search → recommendationsFull shopping flow with checkout, search and product recommendations
SaaS Platformapi-gateway → auth → user → billing → feature-flags → payment-gatewayMulti-tenant SaaS with auth, billing, subscription management
Media Streamingcdn-edge → origin → transcoder → queue-worker → storageVideo streaming with CDN cache, transcoding pipeline
Banking / FinTechweb-portal → fraud-detection → risk-engine → payment → ledger → auditFinancial transactions with fraud scoring and audit trail
Social Networkfeed → graph → ranking → media → notification-fanout → cacheSocial feed generation with friend graph traversal

Infrastructure

ScenarioServicesDescription
Linux Syslogkernel, sshd, systemd, cron, nginx, postgresql, dockerdSystem-level log generation (OOM kills, SSH, service failures)
Kuberneteskube-apiserver → scheduler → kubelet → containerd → coredns → etcdK8s control plane operations (pod scheduling, image pulls, OOM)
Database Clusterquery-router → primary-db → replica-db → wal-archiver → read-cacheDatabase with replication, slow queries, deadlocks
Message Queueproducer → kafka-broker → consumer-group → processor → dead-letterKafka pipeline with consumer lag and DLQ routing
CI/CD Pipelinewebhook-trigger → build-agent → test-runner → deploy-agent → health-checkerBuild/test/deploy with rollback triggers

APM

ScenarioServicesDescription
Java / JVMjava-backend → node-api → python-worker → go-proxy → ruby-appPolyglot APM with GC pauses, heap pressure
Node.js Servicesexpress-gateway → auth-middleware → product → mongoose → redis → elasticExpress.js stack with MongoDB, Redis, Elasticsearch
Python ML Pipelineapi-server → feature-store → model-server → vector-db → result-cacheML inference with CUDA OOM, feature lag
Go Serviceshttp-proxy → grpc-service → worker-pool → object-storeGo microservices with goroutine monitoring
.NET Platformaspnet-gateway → identity → order → data-service → token-store → cacheASP.NET with SQL Server connection pooling

Cloud Native

ScenarioServicesDescription
IoT / Edgesensor-hub → edge-gateway → stream-processor → timeseries-db → anomaly-detectorIoT telemetry with edge buffering, anomaly detection
Serverless / FaaSapi-gateway → lambda-auth → lambda-process → dynamodb → s3 → snsLambda functions with cold starts, timeouts
Service Meshistio-ingressgateway → envoy-sidecar → service-a → service-bIstio/Envoy with circuit breakers, mTLS errors
Security / SIEMfirewall → ids-engine → siem → alert-manager → notificationSecurity event pipeline with CVE detection, SOC alerts
Mobile Backendmobile-api → auth → feed-aggregator → content → analytics → event-storeMobile app backend with biometric auth, push notifications

Chaos / Stress

ScenarioServicesDescription
Error Stormfrontend → cart → payment → inventory80% forced error rate — tests error alerting
Cardinality Burstapi-gateway → data-serviceRandom user IDs per request — tests high cardinality handling
Latency Spikefrontend → product → payment → slow-db30% of spans get 2-8 second latency injection
Traffic Surgegateway → order → inventory → billing → shipping10× batch multiplier — tests ingestion throughput
Cascading Failuregateway → order → billing → cache75% errors with circuit breaker fallback patterns

Signal Types & Ratios

Per the OpenTelemetry specification, the three signal types have different volume characteristics:

SignalVolumeHow OTel Studio generates it
LogsHighestOne log record per service visited in each trace chain. A 5-service chain produces 5 logs per trace.
TracesMiddleOne trace chain per batch item, containing 10-15 spans with parent-child relationships.
MetricsLowestAggregated per export cycle (10s interval). Each cycle exports one data point per unique instrument, regardless of request volume.

Each of Traces, Logs, and Metrics can be toggled independently in the top control bar — turning a signal off stops it from being generated across every active scenario at once.

Advanced Scenario Controls

Every scenario card has an Advanced Settings panel with telemetrygen-style controls for testing specific pipeline behaviors:

Geo / IP Simulation

Tags the root span and logs of each generated request with a client.address and GeoIP-resolvable attributes (geo.country.iso_code, geo.city.name, geo.location.lat/lon, cloud.region), so requests appear to originate from realistic global locations. Two modes, set globally on the Endpoints page:

ModeBehavior
RealisticReal regional cloud IP ranges — resolves to an actual city/country in your backend's GeoIP lookup
Safe / TEST-NETRFC 5737 non-routable ranges (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) — guaranteed to never collide with real infrastructure, at the cost of not resolving to a real location

Synthetic PII

Tags the root span and logs with a synthetic user.id, user.name, and user.email, generated from a fixed name pool and RFC 2606-reserved domains (example.com/.org/.net) — never real people's data. Every synthetic record is marked with pii.synthetic: true so a downstream redaction/DLP pipeline being tested can positively identify it. Recommended for scenarios like Banking, Social Network, and E-Commerce where testing PII handling is relevant.

Custom Attributes

Arbitrary key=value pairs, comma-separated, added to the root span and logs of every request in that scenario — useful for tagging generated data with a team name, region, or any attribute your dashboards filter on.

Span Duration Override

Set a min/max range in milliseconds to override the scenario's natural randomized timing. Leave blank to use built-in realistic chain timing.

Status Code Weights

code:weight pairs, comma-separated (e.g. 200:90,404:5,500:5) — controls the distribution of HTTP status codes on generated spans. When set, this overrides the scenario's plain error-rate slider.

Anomaly Injection

Click ⚡ Inject Anomaly to trigger a burst across all active scenarios. For 30 seconds (or until you click Stop Anomaly):

Traffic10× normal batch count
Error rateForced to 80% regardless of slider
Latency30% of spans get 2-8 second duration spikes

Anomaly state is tracked server-side and stays in sync with the main Start/Stop control — stopping the simulation (manually or via quota expiry) also clears an in-progress anomaly, and the button/timer reflect this on any connected browser tab, not just the one that triggered it.

Sequential Mode

Enable Sequential Mode in the Scenarios panel to run one scenario at a time, rotating through all enabled scenarios on a configurable timer (default 30 seconds each). Useful for sequential load testing — each scenario runs in isolation before rotating to the next.

Time Limit / Quota

Set a time limit (1m / 5m / 10m / 30m / 1h / no limit) before clicking Start. The top bar shows a live countdown; when it reaches zero, sending stops automatically across all signals — including metrics, which export on their own periodic schedule independent of the trace/log generation loop.

Multi-Endpoint Fanout

OTel Studio can send telemetry to multiple collectors simultaneously. On the Endpoints page, each endpoint has its own toggle — check any combination to activate them together; at least one must stay active. The SDK creates one BatchSpanProcessor, one BatchLogRecordProcessor, and one metric reader per active endpoint, so traces, logs, and metrics all fan out identically. Use this to compare two o11y backends side-by-side or to send to both production and staging collectors at once.

TLS / mTLS

Each endpoint supports an optional TLS/mTLS configuration, expandable in the Add/Edit Endpoint form: a CA certificate, a client certificate, a client private key (all PEM format), and an "insecure" toggle to skip certificate verification for testing against self-signed backends.

Stack Presets

One-click endpoint configuration for 12 popular observability backends:

BackendProtocolDefault URL
Grafana AlloygRPC / HTTPhttp://alloy:4317 or :4318
OpenTelemetry CollectorgRPChttp://otelcol:4317
Elastic APMHTTPhttp://apm-server:8200
HoneycombHTTPhttps://api.honeycomb.io
JaegergRPChttp://jaeger:4317
SigNozgRPChttp://otel-collector:4317
OpenObserveHTTPhttp://openobserve:5080
Datadog AgentHTTPhttp://datadog-agent:4318
New RelicHTTPhttps://otlp.nr-data.net
DynatraceHTTPhttps://ENV.live.dynatrace.com/api/v2/otlp
Lightstep / ServiceNowHTTPhttps://ingest.lightstep.com

Webhook on Quota Expire

Set an HTTP endpoint (Slack incoming webhook or any URL) on the Endpoints page. When the time-limit quota expires and sending stops automatically, OTel Studio fires a POST with {event: "quota_expired", ts: "<ISO timestamp>"} — useful for notifying a team channel when an automated test run finishes.

Real System Data

Alongside simulated scenarios, OTel Studio can collect real telemetry from the host it's running on, on the Real Data page:

Log file tailingTail any log files on disk (mount them via -v /var/log:/var/log:ro) and stream new lines as real OTel log records
Docker container logsPoll logs from other containers on the host (requires mounting /var/run/docker.sock)
Docker container metricsCPU/memory usage per container
System metricsHost CPU, memory, load average, and network interface stats

Real System Data and Simulation are independent toggles — run either alone or both together.

Import / Export

Export your scenario configuration as JSON to share setups with your team. Import a config file to restore a saved setup. Export the activity stream as CSV for offline analysis.

Environment Variables

VariableDefaultDescription
PORT3002HTTP server port
OTEL_ENDPOINThttp://localhost:4318Default OTel collector endpoint
OTEL_PROTOCOLhttpProtocol: grpc or http
SERVICE_NAMEotel-agentService name in telemetry resource attributes
ENVIRONMENTproductionDeployment environment attribute
ADMIN_USERadminInitial admin username
ADMIN_PASSadmin123Initial admin password — change this for any deployment reachable outside your own machine
JWT_SECRET(auto-generated)Secret for signing auth tokens. If not set, a random one is generated on first boot and persisted in the /data volume — stable across restarts, unique per deployment
DB_PATH/data/otel-simulator.dbSQLite database path
MODE_REALfalseEnable real system data collection
MODE_SIMtrueEnable simulated telemetry
SCENARIOecommerceLegacy single-scenario default — the app now primarily uses per-scenario config set from the UI (see Advanced Scenario Controls); this only affects the very first boot before any config is saved
RATE_MS1000Legacy default rate for SCENARIO on first boot
BATCH_SIZE1Legacy default batch size for SCENARIO on first boot
ERROR_RATE0.05Legacy default error rate for SCENARIO on first boot
LOG_FILES(empty)Comma-separated paths to tail for real logs
DOCKER_LOGStrueTail Docker container logs
DOCKER_METRICStrueCollect Docker container metrics
METRICS_INTERVAL5000System metrics collection interval (ms)

OTel Studio v2.0 — Built by XplurData