Learn how to integrate the LangWatch Python SDK with your existing OpenTelemetry setup.
langwatch.span.type
, langwatch.inputs
, langwatch.outputs
, langwatch.metadata
) to these standard spans to power its observability features.
This foundation provides several benefits:
TracerProvider
and instrumentation.opentelemetry-instrumentation-celery
, traces initiated by LangWatch for an LLM task can automatically include spans generated within your Celery workers, giving you a complete end-to-end view of the request, including background processing, without any extra configuration.
opentelemetry-instrumentation-fastapi
, an incoming HTTP request automatically starts a trace. When your request handler calls a function instrumented with @langwatch.trace
or @langwatch.span
, those LangWatch spans become children of the incoming request span. You see the full request lifecycle, from web server entry to LLM processing and response generation.
opentelemetry-instrumentation-requests
or similar, these HTTP request spans will automatically appear within your LangWatch trace, showing the latency and success/failure of these external dependencies.
opentelemetry-instrumentation-celery
, the trace context is automatically propagated. The spans generated by the Celery worker processing that job will be linked to the original LangWatch trace, giving you visibility into asynchronous operations triggered by your LLM pipeline.
opentelemetry-instrumentation-sqlalchemy
, any database queries executed during your LLM processing (e.g., for RAG retrieval, user data lookup, logging results) will appear as spans within the relevant LangWatch trace, pinpointing database interaction time and specific queries.
pip install opentelemetry-instrumentation-<library>
) and sometimes an initialization step (like CeleryInstrumentor().instrument()
). As long as they use the same (or the global) TracerProvider
that LangWatch is configured with, the integration is automatic.
handle_request
function is the main trace.retrieve_documents
is a child span created by LangWatch.autotrack_openai_calls
).process_result_background.delay
creates a span indicating the task was enqueued.CeleryInstrumentor
automatically propagates the trace context, so when the Celery worker picks up the process_result_background
task, its execution is linked as a child span (or spans, if the task itself creates more) under the original handle_request
trace.langwatch.setup()
langwatch.setup()
, it intelligently interacts with your existing OpenTelemetry environment:
TracerProvider
:
TracerProvider
instance via the tracer_provider
argument in langwatch.setup()
, LangWatch will use that specific provider.TracerProvider
has already been set (e.g., by another library or your own OTel setup code).TracerProvider
.TracerProvider
(either provided via the argument or detected globally), it will add its own OTLP Span Exporter to that provider’s list of Span Processors. It does not remove existing processors or exporters.TracerProvider
, it configures it with the LangWatch OTLP Span Exporter.langwatch.setup()
runs and attaches its exporter to a TracerProvider
, all spans managed by that provider will be exported to the LangWatch backend by default. This includes:
@langwatch.trace
and @langwatch.span
.langwatch.trace()
or langwatch.span()
as context managers or via span.end()
.opentelemetry-instrumentation-requests
, opentelemetry-instrumentation-fastapi
) if they are configured to use the same TracerProvider
.tracer.start_as_current_span(...)
).span_exclude_rules
span_exclude_rules
argument during langwatch.setup()
. This allows you to define rules to filter spans before they are exported to LangWatch, without affecting other exporters attached to the same TracerProvider
.
Rules are defined using SpanProcessingExcludeRule
objects.
SpanProcessingExcludeRule
definition for all available fields (span_name
, attribute
, library_name
) and operations (exact_match
, contains
, starts_with
, ends_with
, regex
).
ConsoleSpanExporter
for this purpose.
You can add it to your TracerProvider
like this:
LangWatchSpan
object (returned by langwatch.span()
or accessed via langwatch.get_current_span()
) directly exposes the standard OpenTelemetry trace.Span
API methods. This allows you to interact with the span using familiar OTel functions when needed for advanced use cases or compatibility.
You don’t need to access a separate underlying object; just call the standard OTel methods directly on the LangWatchSpan
instance:
update
, etc.) and the standard OpenTelemetry span manipulation methods on the same object.
ignore_global_tracer_provider_override_warning
langwatch.setup()
detects an existing global TracerProvider
(one set via opentelemetry.trace.set_tracer_provider()
) and you haven’t explicitly passed a tracer_provider
argument, LangWatch will log a warning by default. The warning states that it found a global provider and will attach its exporter to it rather than replacing it.
This warning exists because replacing a globally configured provider can sometimes break assumptions made by other parts of your application or libraries. However, in many cases, attaching the LangWatch exporter to the existing global provider is exactly the desired behavior.
If you are intentionally running LangWatch alongside an existing global OpenTelemetry setup and want LangWatch to simply add its exporter to that setup, you can silence this warning by setting: