In order to make a system observable, it must be instrumented: That is, code from the systemβs components must emit traces, metrics, and logs.
βInstrumentationβ referring to the act of collecting trace data. 2 ways to instrument the code
If you are using Kubernetes, you can use the OpenTelemetry Operator for Kubernetes to inject auto-instrumentation libraries for .NET, Java, Node.js, Python, Go into your application
If applicable a language specific implementation of OpenTelemetry will provide a way to instrument your application without touching your source code.
Configuration is available via environment variables and possibly language specific means such as system properties in Java. At a minimum, a service name must be configured to identify the service being instrumented. A variety of other configuration options are available and may include:
These provide a hybrid solution where developers can use prebuilt libraries to instrument their code while still having the flexibility to customize when needed. These are specific to a programming language or framework and are integrated by importing them into the code. Often used in conjunction with Auto instrumentation which dynamically injects Observability into applications without code changes.
Instrumentation libraries provide integration for the framework that lacking native integration.
OpenTelemetry Registry allows you to search for instrumentation libraries - Registry
Note: Libraries might be testing phase or limited support.
Examples:
To facilitate the instrumentation of applications even more, you can manually instrument your applications by coding against the OpenTelemetry APIs.
Steps:
@opentelemetry/api
in JS, opentelemetry.trace
in Python)TraceProvider
or directly via get_tracer
method (Ex: trace.get_tracer('my-service')
).tracer.start_span()
or tracer.start_active_span()
depending on context propagation.Steps to configure as per above diagram
π Step 1: Install OpenTelemetry core SDK, exporters, and instrumentation libraries.
π Step 2: Configure the OpenTelemetry Provider. Create and set the TracerProvider, MeterProvider, or LoggerProvider. This is where you configure resources (e.g., service name).
π Step 3: Create Exporter (Ex: SpanExporter) for sending telemetry to backend like Jaguar, Grafana etc. Also Buffer, process and export telemetry (Ex: SpanProcessor). Then attach processors/exporters to Provider.
π Step 4: Enable Automatic or Library Instrumentation (Optional but Recommended). Initialize instrumentation for common libraries like HTTP clients, DBs, etc.
π Step 5: Acquire a Tracer / Meter / Logger. Use the OTel API to get an object for emitting telemetry.
π Step 6: Create Spans or Record Metrics / Logs Around Business Logic. Use start_span() or start_as_current_span() to create spans in your app logic.
π Step 7: Add Attributes, Events, and Exceptions. Enrich spans with key-value attributes or events for debugging and filtering.
π Step 8: Ensure Context Propagation Across Threads / Services. Use OTel context API or ensure your frameworkβs context is patched. In web frameworks or async code, context must be preserved manually or via instrumentation.
Note: If you do not propagate the context, a new trace will be created for every service. So it is important to pass the context through propagation.
π Step 9: Run the Application and Observe Telemetry in the Backend. Start your application, generate some activity, and verify data reaches your backend (e.g., Jaeger, Grafana, etc.).
Note:
π‘ Enrich spans with Resources and Attributes. Resources are metadata about the application and environment like ServiceName & Attributes are metadata about a specific span, Metric or log like DB Query, user ID etc.
π‘ Follow Semantic Conventions which is OpenTelemetry specifications which helps to improve consistency etc. Ref: Semantic Conventions.
π‘ Trace Context Propagation for distributed tracing. Trace Context Propagation is a mechanism which OTel carries traces and span context across system boundaries such as HTTP Request, threads, services or queues so that all operations involved in a single request are linked together into single distributed trace. OpenTelemetry SpanContext boundary could be in-process or a network. SDK automatically generates SpanContext for us.
π‘ Baggage is custom key-value metadata that travels across services with the trace context.
Check Step by Step Guide
β Next Chapter: Sampling
β Main Page: Click Here