From 093ada29f17352cb5552f7848580aa1d36ac5a9a Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Mon, 4 May 2026 15:25:04 -0700 Subject: [PATCH 1/4] Add Microsoft OpenTelemetry Distro sample --- .../microsoft_opentelemetry_distro.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 python/samples/02-agents/observability/microsoft_opentelemetry_distro.py diff --git a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py new file mode 100644 index 00000000000..578f82af597 --- /dev/null +++ b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py @@ -0,0 +1,60 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio +from random import randint +from typing import Annotated + +from agent_framework import Agent, tool +from agent_framework.foundry import FoundryChatClient +from agent_framework.observability import get_tracer +from azure.identity import AzureCliCredential +from dotenv import load_dotenv +from microsoft.opentelemetry import use_microsoft_opentelemetry +from opentelemetry.trace import SpanKind +from opentelemetry.trace.span import format_trace_id +from pydantic import Field + +# Load environment variables from .env file +load_dotenv() + + +@tool(approval_mode="never_require") +async def get_weather( + location: Annotated[str, Field(description="The location to get the weather for.")], +) -> str: + """Get the weather for a given location.""" + await asyncio.sleep(randint(0, 10) / 10.0) # Simulate a network call + conditions = ["sunny", "cloudy", "rainy", "stormy"] + return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C." + + +async def main(): + # Set up Azure monitor exporters for telemetry + # This will automatically enable instrumentation for Agent Framework + # Install the Microsoft OpenTelemetry Distro package to enable this functionality: + # pip install microsoft-opentelemetry + use_microsoft_opentelemetry(enable_azure_monitor=True) + + questions = ["What's the weather in Amsterdam?", "and in Paris, and which is better?", "Why is the sky blue?"] + + with get_tracer().start_as_current_span("Scenario: Agent Chat", kind=SpanKind.CLIENT) as current_span: + print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}") + + agent = Agent( + client=FoundryChatClient(credential=AzureCliCredential()), + tools=get_weather, + name="WeatherAgent", + instructions="You are a weather assistant.", + id="weather-agent", + ) + session = agent.create_session() + for question in questions: + print(f"\nUser: {question}") + print(f"{agent.name}: ", end="") + async for update in agent.run(question, session=session, stream=True): + if update.text: + print(update.text, end="") + + +if __name__ == "__main__": + asyncio.run(main()) From f8f3d41c4e77471eb1f618d4bd3c037689fad915 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Thu, 9 Jul 2026 11:38:28 -0700 Subject: [PATCH 2/4] Verify and add README --- python/samples/02-agents/observability/README.md | 11 +++++++++++ .../observability/microsoft_opentelemetry_distro.py | 13 +++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/python/samples/02-agents/observability/README.md b/python/samples/02-agents/observability/README.md index a94a199a535..4ed36c0c4b6 100644 --- a/python/samples/02-agents/observability/README.md +++ b/python/samples/02-agents/observability/README.md @@ -78,6 +78,16 @@ configure_otel_providers(exporters=exporters) Many third-party OTel packages ship their own setup helpers (for example, Azure Monitor's `configure_azure_monitor()`). You can use those directly — Agent Framework instrumentation is on by default, so no extra wiring is needed. To also capture sensitive data, call `enable_sensitive_telemetry()` from `agent_framework.observability`. +The [Microsoft OpenTelemetry Distro](https://pypi.org/project/microsoft-opentelemetry/) bundles this pattern into a single call. Install it with `pip install microsoft-opentelemetry`, then call `use_microsoft_opentelemetry()`, which wires up the OpenTelemetry providers/exporters (optionally including Azure Monitor) and enables Agent Framework instrumentation: + +```python +from microsoft.opentelemetry import use_microsoft_opentelemetry + +# Sets up OpenTelemetry providers/exporters and enables Agent Framework instrumentation. +# Pass enable_azure_monitor=True to also configure the Azure Monitor exporter. +use_microsoft_opentelemetry(enable_azure_monitor=True) +``` + ```python from azure.monitor.opentelemetry import configure_azure_monitor from agent_framework.observability import create_resource, enable_sensitive_telemetry @@ -334,6 +344,7 @@ This folder contains different samples demonstrating how to use telemetry in var | [configure_otel_providers_with_parameters.py](./configure_otel_providers_with_parameters.py) | Create custom exporters with specific configuration and pass them to `configure_otel_providers()`. | | [agent_observability.py](./agent_observability.py) | Telemetry collection for an agentic application with tool calls. | | [foundry_tracing.py](./foundry_tracing.py) | Azure Monitor integration with Microsoft Foundry. | +| [microsoft_opentelemetry_distro.py](./microsoft_opentelemetry_distro.py) | One-call setup with the Microsoft OpenTelemetry Distro (`use_microsoft_opentelemetry()`), optionally enabling Azure Monitor. | | [workflow_observability.py](./workflow_observability.py) | Telemetry collection for a workflow with multiple executors and message passing. | | [advanced_manual_setup_console_output.py](./advanced_manual_setup_console_output.py) | Advanced: manual setup of exporters and providers with console output — useful for understanding how observability works under the hood. | | [advanced_zero_code.py](./advanced_zero_code.py) | Advanced: zero-code provider/exporter setup using the `opentelemetry-instrument` CLI wrapper. | diff --git a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py index 578f82af597..8825abcf87b 100644 --- a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py +++ b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py @@ -33,11 +33,20 @@ async def main(): # This will automatically enable instrumentation for Agent Framework # Install the Microsoft OpenTelemetry Distro package to enable this functionality: # pip install microsoft-opentelemetry + # Requires the following environment variables to be set: + # OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 + # APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey... use_microsoft_opentelemetry(enable_azure_monitor=True) - questions = ["What's the weather in Amsterdam?", "and in Paris, and which is better?", "Why is the sky blue?"] + questions = [ + "What's the weather in Amsterdam?", + "and in Paris, and which is better?", + "Why is the sky blue?", + ] - with get_tracer().start_as_current_span("Scenario: Agent Chat", kind=SpanKind.CLIENT) as current_span: + with get_tracer().start_as_current_span( + "Scenario: Agent Chat", kind=SpanKind.CLIENT + ) as current_span: print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}") agent = Agent( From 40ccbafa5f2bf8544826ed5da554a9b811adf1ba Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Thu, 9 Jul 2026 11:43:00 -0700 Subject: [PATCH 3/4] Add dependency header --- .../claw_step03_scaling_capabilities.py | 3 +-- .../observability/microsoft_opentelemetry_distro.py | 9 +++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/python/samples/02-agents/harness/build_your_own_claw/claw_step03_scaling_capabilities.py b/python/samples/02-agents/harness/build_your_own_claw/claw_step03_scaling_capabilities.py index 9c2d31254f2..dbab85a8b55 100644 --- a/python/samples/02-agents/harness/build_your_own_claw/claw_step03_scaling_capabilities.py +++ b/python/samples/02-agents/harness/build_your_own_claw/claw_step03_scaling_capabilities.py @@ -58,9 +58,9 @@ import httpx from agent_framework import ( - AggregatingSkillsSource, Agent, AgentModeProvider, + AggregatingSkillsSource, DeduplicatingSkillsSource, FileAccessProvider, FileSkillsSource, @@ -84,7 +84,6 @@ # subprocess script runner used to execute file-based skill scripts. sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from console import build_observers_with_planning, run_agent_async # noqa: E402 - from subprocess_script_runner import subprocess_script_runner # noqa: E402 _SAMPLE_DIR = Path(__file__).resolve().parent diff --git a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py index 8825abcf87b..c2dd4cc5d10 100644 --- a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py +++ b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py @@ -1,3 +1,12 @@ +# /// script +# requires-python = ">=3.10" +# dependencies = [ +# "microsoft-opentelemetry", +# ] +# /// +# Run with any PEP 723 compatible runner, e.g.: +# uv run python/samples/02-agents/observability/microsoft_opentelemetry_distro.py + # Copyright (c) Microsoft. All rights reserved. import asyncio From abfaa8ab184cf6fd663ee40d5fd9c01606977051 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Fri, 10 Jul 2026 12:05:38 -0700 Subject: [PATCH 4/4] Add maf dependency in PEP 723 block --- .../02-agents/observability/microsoft_opentelemetry_distro.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py index c2dd4cc5d10..7eb3ea61d15 100644 --- a/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py +++ b/python/samples/02-agents/observability/microsoft_opentelemetry_distro.py @@ -1,6 +1,7 @@ # /// script # requires-python = ">=3.10" # dependencies = [ +# "agent-framework-foundry", # "microsoft-opentelemetry", # ] # ///