Python: Fix observability samples (#5016)

* Fix observability samples

* Update python/samples/02-agents/observability/configure_otel_providers_with_parameters.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/samples/02-agents/observability/agent_observability.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/samples/02-agents/observability/agent_observability.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Tao Chen
2026-04-01 10:12:03 -07:00
committed by GitHub
Unverified
parent b065a4ce51
commit 86f8efc8ff
5 changed files with 55 additions and 18 deletions
@@ -8,11 +8,12 @@ from typing import Annotated
from agent_framework import Message, tool
from agent_framework.foundry import FoundryChatClient
from agent_framework.observability import enable_instrumentation
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
from opentelemetry._logs import set_logger_provider
from opentelemetry.metrics import set_meter_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogExporter
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogRecordExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader
from opentelemetry.sdk.resources import Resource
@@ -37,7 +38,7 @@ def setup_logging():
# Create and set a global logger provider for the application.
logger_provider = LoggerProvider(resource=resource)
# Log processors are initialized with an exporter which is responsible
logger_provider.add_log_record_processor(BatchLogRecordProcessor(ConsoleLogExporter()))
logger_provider.add_log_record_processor(BatchLogRecordProcessor(ConsoleLogRecordExporter()))
# Sets the global default logger provider
set_logger_provider(logger_provider)
# Create a logging handler to write logging records, in OTLP format, to the exporter.
@@ -115,11 +116,15 @@ async def run_chat_client() -> None:
2 spans with gen_ai.operation.name=execute_tool
"""
client = FoundryChatClient()
client = FoundryChatClient(credential=AzureCliCredential())
message = "What's the weather in Amsterdam and in Paris?"
print(f"User: {message}")
print("Assistant: ", end="")
async for chunk in client.get_response([Message(role="user", text=message)], tools=get_weather, stream=True):
async for chunk in client.get_response(
[Message(role="user", text=message)],
stream=True,
options={"tools": [get_weather]},
):
if chunk.text:
print(chunk.text, end="")
print("")
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Annotated
from agent_framework import Message, 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 opentelemetry.trace import SpanKind
from opentelemetry.trace.span import format_trace_id
@@ -90,12 +91,19 @@ async def run_chat_client(client: "SupportsChatGetResponse", stream: bool = Fals
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_response([Message(role="user", text=message)], tools=get_weather, stream=True):
async for chunk in client.get_response(
[Message(role="user", text=message)],
stream=True,
options={"tools": [get_weather]},
):
if chunk.text:
print(chunk.text, end="")
print("")
else:
response = await client.get_response([Message(role="user", text=message)], tools=get_weather)
response = await client.get_response(
[Message(role="user", text=message)],
options={"tools": [get_weather]},
)
print(f"Assistant: {response}")
@@ -103,7 +111,7 @@ async def main() -> None:
with get_tracer().start_as_current_span("Zero Code", kind=SpanKind.CLIENT) as current_span:
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
client = FoundryChatClient()
client = FoundryChatClient(credential=AzureCliCredential())
await run_chat_client(client, stream=True)
await run_chat_client(client, stream=False)
@@ -7,6 +7,7 @@ from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.foundry import FoundryChatClient
from agent_framework.observability import configure_otel_providers, get_tracer
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
from opentelemetry.trace import SpanKind
from opentelemetry.trace.span import format_trace_id
@@ -18,6 +19,12 @@ load_dotenv()
"""
This sample shows how you can observe an agent in Agent Framework by using the
same observability setup function.
Pre-requisites:
- A Foundry project
- An observability backend to receive traces and metrics (for example, a local or remote
OpenTelemetry Collector, another OTLP-compatible backend, or console exporters enabled
via environment variables).
"""
@@ -47,7 +54,7 @@ async def main():
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
agent = Agent(
client=FoundryChatClient(),
client=FoundryChatClient(credential=AzureCliCredential()),
tools=get_weather,
name="WeatherAgent",
instructions="You are a weather assistant.",
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Annotated, Literal
from agent_framework import Message, tool
from agent_framework.foundry import FoundryChatClient
from agent_framework.observability import configure_otel_providers, get_tracer
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
from opentelemetry import trace
from opentelemetry.trace.span import format_trace_id
@@ -24,8 +25,9 @@ This sample shows how you can configure observability of an application via the
When you run this sample with an OTLP endpoint or an Application Insights connection string,
you should see traces, logs, and metrics in the configured backend.
If no OTLP endpoint or Application Insights connection string is configured, the sample will
output traces, logs, and metrics to the console.
Pre-requisites:
- A Foundry project
- A local OpenTelemetry Collector instance to receive the traces and metrics.
"""
# Load environment variables from .env file
@@ -78,13 +80,18 @@ async def run_chat_client(client: "SupportsChatGetResponse", stream: bool = Fals
if stream:
print("Assistant: ", end="")
async for chunk in client.get_response(
[Message(role="user", text=message)], tools=get_weather, stream=True
[Message(role="user", text=message)],
stream=True,
options={"tools": [get_weather]},
):
if chunk.text:
print(chunk.text, end="")
print("")
else:
response = await client.get_response([Message(role="user", text=message)], tools=get_weather)
response = await client.get_response(
[Message(role="user", text=message)],
options={"tools": [get_weather]},
)
print(f"Assistant: {response}")
@@ -101,7 +108,7 @@ async def run_tool() -> None:
with get_tracer().start_as_current_span("Scenario: AI Function", kind=trace.SpanKind.CLIENT):
print("Running scenario: AI Function")
weather = await get_weather.invoke(location="Amsterdam")
print(f"Weather in Amsterdam:\n{weather}")
print(f"Weather in Amsterdam:\n{weather[-1]}")
async def main(scenario: Literal["client", "client_stream", "tool", "all"] = "all"):
@@ -114,7 +121,7 @@ async def main(scenario: Literal["client", "client_stream", "tool", "all"] = "al
with get_tracer().start_as_current_span("Sample Scenarios", kind=trace.SpanKind.CLIENT) as current_span:
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
client = FoundryChatClient()
client = FoundryChatClient(credential=AzureCliCredential())
# Scenarios where telemetry is collected in the SDK, from the most basic to the most complex.
if scenario == "tool" or scenario == "all":
@@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Annotated, Literal
from agent_framework import Message, tool
from agent_framework.foundry import FoundryChatClient
from agent_framework.observability import configure_otel_providers, get_tracer
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
from opentelemetry import trace
from opentelemetry.trace.span import format_trace_id
@@ -27,6 +28,10 @@ and allows you to add multiple exporters programmatically.
For standard OTLP setup, it's recommended to use environment variables (see configure_otel_providers_with_env_var.py).
Use this approach when you need custom exporter configuration beyond what environment variables provide.
Pre-requisites:
- A Foundry project
- A local OpenTelemetry Collector instance to receive the traces and metrics.
"""
# Load environment variables from .env file
@@ -79,13 +84,18 @@ async def run_chat_client(client: "SupportsChatGetResponse", stream: bool = Fals
if stream:
print("Assistant: ", end="")
async for chunk in client.get_response(
[Message(role="user", text=message)], stream=True, tools=get_weather
[Message(role="user", text=message)],
stream=True,
options={"tools": [get_weather]},
):
if chunk.text:
print(chunk.text, end="")
print("")
else:
response = await client.get_response([Message(role="user", text=message)], tools=get_weather)
response = await client.get_response(
[Message(role="user", text=message)],
options={"tools": [get_weather]},
)
print(f"Assistant: {response}")
@@ -102,7 +112,7 @@ async def run_tool() -> None:
with get_tracer().start_as_current_span("Scenario: AI Function", kind=trace.SpanKind.CLIENT):
print("Running scenario: AI Function")
weather = await get_weather.invoke(location="Amsterdam")
print(f"Weather in Amsterdam:\n{weather}")
print(f"Weather in Amsterdam:\n{weather[-1]}")
async def main(scenario: Literal["client", "client_stream", "tool", "all"] = "all"):
@@ -153,7 +163,7 @@ async def main(scenario: Literal["client", "client_stream", "tool", "all"] = "al
with get_tracer().start_as_current_span("Sample Scenarios", kind=trace.SpanKind.CLIENT) as current_span:
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
client = FoundryChatClient()
client = FoundryChatClient(credential=AzureCliCredential())
# Scenarios where telemetry is collected in the SDK, from the most basic to the most complex.
if scenario == "tool" or scenario == "all":