Task 1 — Trace your agent
Part of the Observe, evaluate, and secure your agents lab. New here? Start with Getting started.
Set up (start here): This task needs a Foundry project, an Application Insights resource connected to it, a grounded agent to trace, and the starter code. If you haven’t already, complete Getting started to create your project, clone the code, set
PROJECT_ENDPOINTandAGENT_NAMEinPython/.env(point it at your Lab B agent, or create one withpython ../setup/bootstrap_agent.py), and connect Application Insights. Then, from thePythonfolder you opened in VS Code, verify you’re ready:
python ../setup/check_env.py --task 1
Continuing from a previous task? If you just finished another task in the same
Pythonfolder, your project, virtual environment, and.envare already set — go straight to Instrument the agent below.
It’s Monday morning at Caldova’s Ashford site. Planners are firing questions at the assistant between meetings, and the planning lead says some answers “take ages”. You have no idea which ones, or why: the terminal shows you an answer, and nothing about how it got there.
Tracing fixes that. Your code emits spans — timed, named, nested records of work — and ships them to Application Insights, where the Foundry portal renders them as a waterfall you can step through.
What is OpenTelemetry?
OpenTelemetry is a vendor-neutral standard for emitting traces, metrics and logs. A span is one unit of work with a start, an end, and attributes; spans nest to form a trace of a whole operation. Because it’s a standard, the Azure SDKs, the OpenAI client and your own code all produce spans that line up in the same waterfall — and you could point them at a different backend tomorrow without rewriting your instrumentation.
Server-side traces come free. Now that Application Insights is connected to your project, Foundry already records traces for agents it hosts — no code required. What you add here is client-side instrumentation: spans around your code. Both land in the same Application Insights resource, but Foundry’s Agents > Traces page only renders its own server-side view (
Invoke Agent/Execute tool/Chat) — to see your own spans and attributes alongside it, you’ll look directly at Application Insights.
Open the Python folder and activate the virtual environment from Getting started (.\labenv\Scripts\Activate.ps1), then continue below.
Instrument the agent
Open traced_agent.py and add code at each commented placeholder.
Tip: As you add code, keep the indentation aligned with the comments.
-
Add references:
# Add references from azure.identity import DefaultAzureCredential from azure.ai.projects import AIProjectClient from azure.monitor.opentelemetry import configure_azure_monitor from opentelemetry import trace -
Turn on GenAI tracing — the spans that capture model calls are off by default, and message content is off separately because prompts can contain personal data. Turn both on for this lab:
# Turn on GenAI tracing os.environ.setdefault("AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING", "true") os.environ.setdefault("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT", "true")These must be set before the client is created, which is why they go at the top of the file. In production, think hard before turning message content on.
-
Connect to the project:
# Connect to the project with ( DefaultAzureCredential() as credential, AIProjectClient(endpoint=project_endpoint, credential=credential) as project_client, project_client.get_openai_client() as openai_client, ): -
Read the Application Insights connection string and start exporting traces — the project hands you the connection string of the resource you connected in setup, and
configure_azure_monitorwires up the exporter:# Read the Application Insights connection string and start exporting traces try: connection_string = project_client.telemetry.get_application_insights_connection_string() except Exception as error: raise SystemExit( "Could not read an Application Insights connection string from this project.\n" "In the Foundry portal, open your project, select Agents > Traces, and select\n" f"Connect to create or connect an Application Insights resource.\n\nDetails: {error}" ) configure_azure_monitor(connection_string=connection_string) -
Get a tracer for this script — a tracer is what you create your own spans from:
# Get a tracer for this script tracer = trace.get_tracer(__name__) -
Look up the agent — its
id(not just its name) is needed to correlate traces with this specific agent in the Foundry portal:# Look up the agent so its id can be included in agent_reference agent = project_client.agents.get(agent_name=agent_name) -
Ask each question inside its own span — this is the part that pays off. An outer span represents the review; each question gets a child span, tagged with attributes you choose so you can tell them apart in the portal. This reuses
caldova-knowledge-agentrather than standing up a separate agent just for this task:# Ask each question inside its own span with tracer.start_as_current_span("morning-planning-review") as shift_span: shift_span.set_attribute("caldova.site", "ashford") conversation = openai_client.conversations.create() for number, question in enumerate(QUESTIONS, start=1): with tracer.start_as_current_span("planner-question") as question_span: question_span.set_attribute("caldova.question_number", number) response = openai_client.responses.create( conversation=conversation.id, input=question, extra_body={"agent_reference": {"name": agent.name, "id": agent.id, "type": "agent_reference"}}, ) question_span.set_attribute("caldova.answer_length", len(response.output_text)) print(f"\nQ{number}: {question}") print(f"A{number}: {response.output_text}") -
Save the file (Ctrl+S).
Run and test
-
In the terminal, sign in and run the app:
az loginpython traced_agent.py -
You should see the three answers print:
Q1: How long does review take for a capacity request with a complete brief? A1: ...If you get an error about the connection string, Application Insights isn’t connected to your project yet — go back to Getting started and connect it.
Read the traces
Two views, two purposes. Foundry’s Agents > Traces page shows the automatic
server-side trace of the agent’s own turn (Invoke Agent > Execute tool / Chat) — it
confirms tracing is working, but it doesn’t surface the client-side spans your script just
added. To see morning-planning-review, planner-question, and their custom attributes, look
at the Application Insights resource itself:
-
In the Foundry portal, open your project, select Agents, then caldova-knowledge-agent, then Traces, to confirm the run arrived (telemetry takes a minute or two — wait and refresh if it isn’t there yet). Selecting a trace here shows Foundry’s own
Invoke Agent/Execute tool/Chatview, not your custom spans. -
Open the Application Insights resource in the Azure portal: open the resource group you created for this project, and select the Application Insights resource in it.
-
In Application Insights, expand Investigate in the left navigation, select Search, and search for
morning-planning-review. -
Select a matching result to open its end-to-end transaction details. This is the raw span tree: your
morning-planning-reviewspan at the top, threeplanner-questionchildren, and inside each one the model call the SDK emitted. -
Select a
planner-questionspan and look at its properties. Yourcaldova.question_numberandcaldova.answer_lengthare there alongside the standard GenAI attributes. -
Compare the durations of the three questions. That’s the planning lead’s complaint, answered with data — and the span breakdown tells you which part of the slow one was slow.
Try it: add a fourth, much harder question to
QUESTIONSand run again. Does the extra time show up in the model call, or somewhere else?
✅ Checkpoint: You can see inside a running agent — both the SDK’s own spans and custom spans of your own, with attributes you chose, all in one timeline.
When you’re finished, enter deactivate to exit the virtual environment.