Building an OpenTelemetry Instrumentation Wizard An engineer has built the OpenTelemetry (OTel) Instrumentation Wizard, a Streamlit and Python tool that automatically injects production-grade OTel traces, metrics, and logs across multiple programming languages while preserving existing business logic. The wizard uses a multi-stage pipeline with language detection, AST/Regex analysis, safety validation, user review, and code injection, targeting official OTel semantic conventions across seven languages. Accelerating observability adoption by automating OpenTelemetry instrumentation across heterogeneous codebases Years ago, I was tasked with building OpenTelemetry metric collection for a client who wanted IBM Instana's capabilities without deploying the Instana agent to their production servers. Achieving that required meticulous, time-consuming effort to instrument their Go and Python applications manually. Recently, I faced almost the exact same challenge - except this time, I had Bob as an AI collaborator. Leveraging Bob, I set out to build an industrialized, universal instrumentation solution to solve the problem at scale. Adding telemetry to existing applications is often tedious, manual, and error-prone. To solve this, we designed the OpenTelemetry OTel Instrumentation Wizard - a tool built with Streamlit and Python that automatically injects production-grade OTel traces, metrics, and logs across multiple programming languages while strictly preserving existing business logic. What follows is the implementation and the components. The wizard operates as a structured multi-stage pipeline. Source files pass from initial language detection through AST/Regex analysis, safety validation, user review, and code injection before returning fully instrumented outputs. OTel-Wizard: injected markers, guaranteeing zero disruption to original runtime logic. otel-wizard/ ├── app.py Streamlit UI 3-step wizard ├── injectors/ │ ├── base injector.py Abstract base + InjectionResult dataclass │ ├── python injector.py AST-aware Python injector │ ├── go injector.py Go import + initTracer injector │ ├── java injector.py Java try-with-resources span injector │ ├── javascript injector.py Node.js SDK setup + span injector │ ├── typescript injector.py ES import syntax + typed Tracer injector │ └── c injector.py C header + otel start/end span injector ├── utils/ │ ├── language detector.py Extension + heuristic language detection │ └── diff viewer.py Unified text diff + colour-coded HTML diff ├── samples/ Six hello-world files pre-injection ├── tests/ pytest suite 8 test files, 128 assertions ├── requirements.txt ├── .env.example └── run tests.sh The wizard targets official OpenTelemetry semantic conventions across 7 key languages, applying tailored injection strategies according to each language's SDK maturity: | Language | Traces | Metrics | Logs | Injection Strategy | | ----------------------- | -------- | -------- | -------- | --------------------------------------------------- | | Python Generic | ✅ Stable | ✅ Stable | ✅ Dev | AST-based ast module | | Python - Flask | ✅ Stable | ✅ Stable | ✅ Dev | AST + FlaskInstrumentor middleware | | Python - FastAPI | ✅ Stable | ✅ Stable | ✅ Dev | AST + FastAPIInstrumentor + ASGI hook | | Python - Django | ✅ Stable | ✅ Stable | ✅ Dev | AST + DjangoInstrumentor + Psycopg2Instrumentor | | JavaScript / TypeScript | ✅ Stable | ✅ Stable | ⚠️ Dev | Regex + template | | Go | ✅ Stable | ✅ Stable | ⚠️ Beta | Regex + template | | Java | ✅ Stable | ✅ Stable | ✅ Stable | Template overlay | | C / .NET | ✅ Stable | ✅ Stable | ✅ Stable | ActivitySource template | | Ruby | ✅ Stable | ⚠️ Dev | ⚠️ Dev | Regex + template | | PHP | ✅ Stable | ✅ Stable | ✅ Stable | Regex + template | Signal status reflects the official OpenTelemetry Language Status https://opentelemetry.io/docs/languages/ as of 2025. Python Supported Frameworks Special Python based frameworks are also implemented in the wizard; | Framework | What Gets Injected | | ----------- | ------------------------------------------------------------ | | Generic | SDK imports, TracerProvider init, span context managers around all functions | | Flask | All of the above + FlaskInstrumentor .instrument app app, excluded urls=... + RequestsInstrumentor .instrument | | FastAPI | All of the above + FastAPIInstrumentor.instrument app app, excluded urls=..., exclude spans= "receive" + HTTPXClientInstrumentor .instrument | | Django | All of the above + DjangoInstrumentor .instrument request hook=..., is sql commentor enabled=True + Psycopg2Instrumentor .instrument - inserted before get wsgi application / get asgi application | Framework-specific requirements.txt entries are also generated automatically. Users retain full control over how telemetry is applied across their services through the wizard's configuration engine: service.name and s ervice.version resource attributes dynamically. otlp-http , otlp-grpc , console , and prometheus endpoints.The architecture behind the OpenTelemetry Instrumentation Wizard follows a clean four-phase pipeline: Detection → Analysis → Injection → Reporting . wizard/core/models.py @dataclass class WizardConfig: service name: str = "my-service" service version: str = "1.0.0" exporter: str = "otlp-http" otlp endpoint: str = "http://localhost:4318" signals: list = field default factory=lambda: "traces", "metrics", "logs" depth: str = "medium" shallow | medium | deep sampling ratio: float = 1.0 @dataclass class InjectionPoint: signal: str "trace" | "metric" | "log" kind: str "span" | "counter" | "provider init" ... location: str "function: