Skip to content

Commit 3973e73

Browse files
skill-temporal-developer-updater[bot]skill-sync[bot]donald-pinckneyclaude
authored
Implement planned topic: 0022-opentelemetry-plugins (#243)
* Finalize draft for 0022-opentelemetry-plugins * Remove legacy TracingInterceptor content from OpenTelemetry docs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Remove Nexus content from OpenTelemetry docs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Tie OpenTelemetry tracing into the observability references Both observability.md files advertised "tracing" but had no tracing section and never linked to the OTel integration docs. Add a concise Distributed Tracing (OpenTelemetry) section to each, surface the trace/log/metric correlation, and cross-link so the OTel <-> observability relationship is bidirectional. Deep API stays canonical in integrations/opentelemetry.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Trim TypeScript OpenTelemetry doc to lean style Mirror the lean, example-driven style now used in the Python OTel doc: fold the Public API / Constructor options / Span names tables into inline comments and prose, compress propagator customization to a one-liner, and keep the log/metric correlation tie-in. Update the observability.md pointer so it no longer promises tables that were removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Finalize Python file * Simplify OpenTelemetry rows in integrations catalog Reduce both OTel rows to a purpose-only description, dropping mechanism detail (plugin names, interceptors, sinks, propagation specifics). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Finalize observability files other than code snippets * finalize python observaibility file * Finalize TS observability file * cut correlation * Move TypeScript OpenTelemetry docs to a separate PR The TypeScript material needs more work, so split it out (now on branch feat/ts-otel). This leaves PR #243 scoped to the Python OpenTelemetry integration only: removes the TS integration reference, reverts the TS observability tracing section, and drops the TS row from the catalog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Apply suggestions from code review Co-authored-by: Donald Pinckney <donald_pinckney@icloud.com> * Apply suggestion from @donald-pinckney * Apply suggestion from @donald-pinckney * Consolidate Python OpenTelemetry docs into observability Remove the standalone references/python/integrations/opentelemetry.md file and fold its unique content (Common mistakes, workflow custom-span example) into the Distributed Tracing section of observability.md. Repoint the integrations catalog row at the observability section. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: skill-sync[bot] <skill-sync[bot]@users.noreply.github.com> Co-authored-by: Donald Pinckney <donald.pinckney@temporal.io> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Donald Pinckney <donald_pinckney@icloud.com>
1 parent 8cf8a5e commit 3973e73

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

references/integrations.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ Temporal ships and supports a growing set of integrations with third-party frame
1919
| LangSmith tracing (`temporalio.contrib.langsmith`) | Python | Experimental Temporal Plugin that propagates LangSmith trace context across Worker boundaries; lets `@traceable` run inside Workflows and Activities | `references/python/integrations/langsmith.md` | `references/python/ai-patterns.md`, `references/core/ai-patterns.md` |
2020
| LangGraph (`temporalio.contrib.langgraph`, Pre-release) | Python | Runs LangGraph Graph-API and Functional-API code as Temporal Workflows - nodes/tasks can execute as either in-workflow or as Activities | `references/python/integrations/langgraph.md` | `references/python/ai-patterns.md`, `references/core/ai-patterns.md` |
2121
| Google ADK (`temporalio[google-adk]`) | Python | Durable Google ADK agents: model calls run through `TemporalModel`-wrapped Activities, tools via `activity_tool`, MCP toolsets via `TemporalMcpToolSet` | `references/python/integrations/google-adk.md` | `references/python/ai-patterns.md`, `references/core/ai-patterns.md` |
22+
| OpenTelemetry (`temporalio[opentelemetry]`) | Python | Distributed tracing for Temporal apps with OpenTelemetry | `references/python/observability.md` (Distributed Tracing section) | |

references/python/observability.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
## Overview
44

5-
The Python SDK provides comprehensive observability through logging, metrics, tracing, and visibility (Search Attributes).
5+
The Python SDK provides comprehensive observability through logging, metrics, tracing (OpenTelemetry), and visibility (Search Attributes).
6+
7+
These pillars are complementary: **logging** (below) captures discrete events, **metrics** capture aggregate health, **tracing** stitches a single request across Client/Workflow/Activity boundaries, and **Search Attributes** make executions queryable.
68

79
## Logging
810

@@ -94,6 +96,51 @@ Runtime.set_default(runtime, error_if_already_set=True)
9496
- `temporal_activity_execution_latency` - Activity execution time
9597
- `temporal_workflow_task_replay_latency` - Replay duration
9698

99+
## Distributed Tracing (OpenTelemetry)
100+
101+
> [!NOTE]
102+
> This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
103+
104+
OpenTelemetry is the supported way to add distributed tracing to Temporal applications. The `OpenTelemetryPlugin` (from `temporalio.contrib.opentelemetry`, installed via the `temporalio[opentelemetry]` extra) propagates W3C TraceContext + Baggage through Temporal headers across Client, Workflow, Activity (including Standalone), and Child Workflow boundaries, so one trace follows a request through your whole execution — with replay-safe, accurate span durations.
105+
106+
```python
107+
import opentelemetry.trace
108+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
109+
from temporalio.client import Client
110+
from temporalio.contrib.opentelemetry import OpenTelemetryPlugin, create_tracer_provider
111+
112+
provider = create_tracer_provider()
113+
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter())) # attach your span processors as normal for OTel
114+
opentelemetry.trace.set_tracer_provider(provider)
115+
116+
client = await Client.connect("localhost:7233", plugins=[OpenTelemetryPlugin()])
117+
```
118+
119+
Workers created from this Client inherit the plugin automatically. Inside a Workflow you then use standard OpenTelemetry APIs (`get_tracer(...).start_as_current_span(...)`); pass `OpenTelemetryPlugin(add_temporal_spans=True)` to also emit `StartWorkflow` / `RunWorkflow` / `StartActivity` / `RunActivity` spans automatically alongside the SDK metrics above.
120+
121+
```python
122+
from datetime import timedelta
123+
from opentelemetry.trace import get_tracer
124+
from temporalio import workflow
125+
126+
@workflow.defn
127+
class MyWorkflow:
128+
@workflow.run
129+
async def run(self) -> None:
130+
tracer = get_tracer(__name__)
131+
with tracer.start_as_current_span("workflow-operation"):
132+
await workflow.execute_activity(
133+
my_activity,
134+
start_to_close_timeout=timedelta(seconds=30),
135+
)
136+
```
137+
138+
**Common mistakes:**
139+
140+
- **Registering the same plugin on both Client and Worker.** Register on the Client only; Workers inherit.
141+
- **Calling `Client.connect` before `opentelemetry.trace.set_tracer_provider(provider)`.** `OpenTelemetryPlugin` raises an exception unless the global tracer provider is already set.
142+
- **Building a plain `opentelemetry.sdk.trace.TracerProvider` and passing it to `set_tracer_provider`.** `OpenTelemetryPlugin` requires a `ReplaySafeTracerProvider` — build it via `create_tracer_provider(...)`.
143+
97144
## Search Attributes (Visibility)
98145

99146
See the Search Attributes section of `references/python/data-handling.md`
@@ -104,3 +151,4 @@ See the Search Attributes section of `references/python/data-handling.md`
104151
2. Don't use print() in workflows - it will produce duplicate output on replay
105152
3. Configure metrics for production monitoring
106153
4. Use Search Attributes for business-level visibility
154+
5. Use the `OpenTelemetryPlugin` for distributed tracing across Client/Workflow/Activity boundaries.

0 commit comments

Comments
 (0)