Python: Remove duplicated workflow observability sample (#2357)

* Remove duplicated workflow observability sample

* Fix link
This commit is contained in:
Tao Chen
2025-11-20 13:06:12 -08:00
committed by GitHub
Unverified
parent e5b63a1041
commit 02af2bc0ef
4 changed files with 16 additions and 72 deletions
-6
View File
@@ -320,12 +320,6 @@ This directory contains samples demonstrating the capabilities of Microsoft Agen
| [`getting_started/workflows/human-in-the-loop/guessing_game_with_human_input.py`](./getting_started/workflows/human-in-the-loop/guessing_game_with_human_input.py) | Sample: Human in the loop guessing game |
| [`getting_started/workflows/human-in-the-loop/agents_with_approval_requests.py`](./getting_started/workflows/human-in-the-loop/agents_with_approval_requests.py) | Sample: Agents with Approval Requests in Workflows |
### Observability
| File | Description |
|------|-------------|
| [`getting_started/workflows/observability/tracing_basics.py`](./getting_started/workflows/observability/tracing_basics.py) | Basic tracing workflow sample |
### Orchestration
| File | Description |
@@ -17,10 +17,25 @@ from typing_extensions import Never
"""
This sample shows the telemetry collected when running a Agent Framework workflow.
This simple workflow consists of two executors arranged sequentially:
1. An executor that converts input text to uppercase.
2. An executor that reverses the uppercase text.
The workflow receives an initial string message, processes it through the two executors,
and yields the final result.
Telemetry data that the workflow system emits includes:
- Overall workflow build & execution spans
- workflow.build (events: build.started, build.validation_completed, build.completed, edge_group.process)
- workflow.run (events: workflow.started, workflow.completed or workflow.error)
- Individual executor processing spans
- executor.process (for each executor invocation)
- Message publishing between executors
- message.send (for each outbound message)
Prerequisites:
- Basic understanding of workflow executors, edges, and messages.
- Basic understanding of OpenTelemetry concepts like spans and traces.
"""
@@ -82,9 +82,7 @@ Once comfortable with these, explore the rest of the samples below.
### observability
| Sample | File | Concepts |
|---|---|---|
| Tracing (Basics) | [observability/tracing_basics.py](./observability/tracing_basics.py) | Use basic tracing for workflow telemetry. Refer to this [directory](../observability/) to learn more about observability concepts. |
For observability samples in Agent Framework, see the [observability getting started samples](../observability/README.md). The [sample](../observability/workflow_observability.py) demonstrates integrating observability into workflows.
### orchestration
@@ -1,63 +0,0 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import Executor, WorkflowBuilder, WorkflowContext, get_logger, handler
from agent_framework.observability import setup_observability
"""Basic tracing workflow sample.
Sample: Workflow Tracing basics
A minimal two executor workflow demonstrates built in OpenTelemetry spans when diagnostics are enabled.
The sample raises an error if tracing is not configured.
Purpose:
- Require diagnostics by checking ENABLE_OTEL and wiring a console exporter.
- Show the span categories produced by a simple graph:
- workflow.build (events: build.started, build.validation_completed, build.completed, edge_group.process)
- workflow.run (events: workflow.started, workflow.completed or workflow.error)
- executor.process (for each executor invocation)
- message.send (for each outbound message)
- Provide a tiny flow that is easy to run and reason about: uppercase then print.
Prerequisites:
- No external services required for the workflow itself.
"""
logger = get_logger()
class StartExecutor(Executor):
@handler # type: ignore[misc]
async def handle_input(self, message: str, ctx: WorkflowContext[str]) -> None:
# Transform and forward downstream. This produces executor.process and message.send spans.
await ctx.send_message(message.upper())
class EndExecutor(Executor):
@handler # type: ignore[misc]
async def handle_final(self, message: str, ctx: WorkflowContext) -> None:
# Sink executor. The workflow completes when idle with no pending work.
print(f"Final result: {message}")
async def main() -> None:
# This will enable tracing and create the necessary tracing, logging and metrics providers
# based on environment variables.
setup_observability()
# Build a two node graph: StartExecutor -> EndExecutor. The builder emits a workflow.build span.
workflow = (
WorkflowBuilder()
.add_edge(StartExecutor(id="start"), EndExecutor(id="end"))
.set_start_executor("start") # set_start_executor accepts an executor id string or the instance
.build()
) # workflow.build span emitted here
# Run once with a simple payload. You should see workflow.run plus executor and message spans.
await workflow.run("hello tracing") # workflow.run + executor.process and message.send spans
if __name__ == "__main__": # pragma: no cover
asyncio.run(main())