Share via


Agent observability

Important

You need to be part of the Frontier preview program to get early access to Microsoft Agent 365. Frontier connects you directly with Microsoft’s latest AI innovations. Frontier previews are subject to the existing preview terms of your customer agreements. As these features are still in development, their availability and capabilities may change over time.

To participate in the Agent 365 ecosystem, add Agent 365 Observability capabilities to your agent. Agent 365 Observability builds on OpenTelemetry (OTel) and provides a unified framework for capturing telemetry consistently and securely across all agent platforms. By implementing this required component, you enable IT admins to monitor your agent's activity in Microsoft admin center and allow security teams to use Defender and Purview for compliance and threat detection.

Key benefits

  • End-to-end visibility: Capture comprehensive telemetry for every agent invocation, including sessions, tool calls, and exceptions, giving you full traceability across platforms.
  • Security and compliance enablement: Feed unified audit logs into Defender and Purview, enabling advanced security scenarios and compliance reporting for your agent.
  • Cross-platform flexibility: Build on OTel standards and support diverse runtimes and platforms like Copilot Studio, Foundry, and future agent frameworks.
  • Operational efficiency for admins: Provide centralized observability in Microsoft 365 admin center, reducing troubleshooting time and improving governance with role-based access controls for IT teams managing your agent.

Installation

Use these commands to install the observability modules for the languages supported by Agent 365.

Install the core observability and runtime packages. All agents that use Agent 365 Observability need these packages.

pip install microsoft-agents-a365-observability-core
pip install microsoft-agents-a365-runtime

If your agent uses the Microsoft Agents Hosting package, install the hosting integration package. It provides middleware that automatically populates baggage and scopes from the TurnContext, and includes token caching for the observability exporter.

pip install microsoft-agents-a365-observability-hosting

If your agent uses one of the supported AI frameworks, install the corresponding auto-instrumentation extension to automatically capture telemetry without manual instrumentation code. For configuration details, see Auto-instrumentation.

# For Semantic Kernel
pip install microsoft-agents-a365-observability-extensions-semantic-kernel

# For OpenAI Agents SDK
pip install microsoft-agents-a365-observability-extensions-openai

# For Microsoft Agent Framework
pip install microsoft-agents-a365-observability-extensions-agent-framework

# For LangChain
pip install microsoft-agents-a365-observability-extensions-langchain

Configuration

Use the following settings to enable and customize Agent 365 Observability for your agent.

Set the ENABLE_A365_OBSERVABILITY_EXPORTER environment variable to true for observability. This setting exports logs to the service and requires a token_resolver to be provided. Otherwise, the console exporter is used.

from microsoft_agents_a365.observability.core import configure

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    # Implement secure token retrieval here
    return "Bearer <token>"

configure(
    service_name="my-agent-service",
    service_namespace="my.namespace",
    token_resolver=token_resolver,
)

The token resolver is excluded from logging to the console.

You can customize the exporter behavior by passing an Agent365ExporterOptions instance to exporter_options. When exporter_options is provided, it takes precedence over the token_resolver and cluster_category parameters.

from microsoft_agents_a365.observability.core import configure, Agent365ExporterOptions

configure(
    service_name="my-agent-service",
    service_namespace="my.namespace",
    exporter_options=Agent365ExporterOptions(
        cluster_category="prod",
        token_resolver=token_resolver,
    ),
    suppress_invoke_agent_input=True,
)

The following table describes the optional parameters for configure().

Parameter Description Default
logger_name Name of the Python logger used for debugging and console log output. microsoft_agents_a365.observability.core
exporter_options An Agent365ExporterOptions instance that configures the token resolver and cluster category together. None
suppress_invoke_agent_input When True, suppresses input messages on InvokeAgent spans. False

The following table describes the optional properties for Agent365ExporterOptions.

Property Description Default
use_s2s_endpoint When True, uses the service-to-service endpoint path. False
max_queue_size Maximum queue size for the batch processor. 2048
scheduled_delay_ms Delay in milliseconds between export batches. 5000
exporter_timeout_ms Timeout in milliseconds for the export operation. 30000
max_export_batch_size Maximum batch size for export operations. 512

Baggage attributes

Use BaggageBuilder to set contextual information that flows through all spans in a request. The SDK implements a SpanProcessor that copies all nonempty baggage entries to newly started spans without overwriting existing attributes.

from microsoft_agents_a365.observability.core import BaggageBuilder

with (
    BaggageBuilder()
    .tenant_id("tenant-123")
    .agent_id("agent-456")
    .conversation_id("conv-789")
    .build()
):
    # Any spans started in this context will receive these as attributes
    pass

To auto-populate the BaggageBuilder from the TurnContext, use the populate helper in the microsoft-agents-a365-observability-hosting package. This helper automatically extracts caller, agent, tenant, channel, and conversation details from the activity.

from microsoft_agents.hosting.core.turn_context import TurnContext
from microsoft_agents_a365.observability.core import BaggageBuilder
from microsoft_agents_a365.observability.hosting.scope_helpers.populate_baggage import populate

builder = BaggageBuilder()
populate(builder, turn_context)

with builder.build():
    # Baggage is auto-populated from the TurnContext activity
    pass

Token resolver

When you use the Agent 365 exporter, you must provide a token resolver function that returns an authentication token. When you use the Agent 365 Observability SDK with the Agent Hosting framework, you can generate tokens by using the TurnContext from agent activities.

from microsoft_agents.activity import load_configuration_from_env
from microsoft_agents.authentication.msal import MsalConnectionManager
from microsoft_agents.hosting.aiohttp import CloudAdapter
from microsoft_agents.hosting.core import (
    AgentApplication,
    Authorization,
    MemoryStorage,
    TurnContext,
    TurnState,
)
from microsoft_agents_a365.runtime import (
    get_observability_authentication_scope,
)

agents_sdk_config = load_configuration_from_env(environ)

STORAGE = MemoryStorage()
CONNECTION_MANAGER = MsalConnectionManager(**agents_sdk_config)
ADAPTER = CloudAdapter(connection_manager=CONNECTION_MANAGER)
ADAPTER.use(TranscriptLoggerMiddleware(ConsoleTranscriptLogger()))
AUTHORIZATION = Authorization(STORAGE, CONNECTION_MANAGER, **agents_sdk_config)

AGENT_APP = AgentApplication[TurnState](
    storage=STORAGE, adapter=ADAPTER, authorization=AUTHORIZATION, **agents_sdk_config
)

@AGENT_APP.activity("message", auth_handlers=["AGENTIC"])
async def on_message(context: TurnContext, _state: TurnState):
    aau_auth_token = await AGENT_APP.auth.exchange_token(
                        context,
                        scopes=get_observability_authentication_scope(),
                        auth_handler_id="AGENTIC",
                    )
    # cache this auth token and return via token resolver

For the digital worker scenario, if your agent uses the Microsoft Agent 365 Observability Hosting Library package, use AgenticTokenCache to handle token caching automatically. Register the token once per agent and tenant during an activity handler, and pass cache.get_observability_token as the token_resolver in your observability configuration.

from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.hosting.token_cache_helpers import (
    AgenticTokenCache,
    AgenticTokenStruct,
)
from microsoft_agents_a365.runtime import get_observability_authentication_scope

# Create a shared cache instance
token_cache = AgenticTokenCache()

# Use the cache as your token resolver in configure()
configure(
    service_name="my-agent-service",
    service_namespace="my.namespace",
    token_resolver=token_cache.get_observability_token,
)

@AGENT_APP.activity("message", auth_handlers=["AGENTIC"])
async def on_message(context: TurnContext, _state: TurnState):
    token_cache.register_observability(
        agent_id="agent-456",
        tenant_id="tenant-123",
        token_generator=AgenticTokenStruct(
            authorization=AGENT_APP.auth,
            turn_context=context,
        ),
        observability_scopes=get_observability_authentication_scope(),
    )

Auto-instrumentation

Auto-instrumentation automatically listens to agentic frameworks (SDKs) existing telemetry signals for traces and forwards them to Agent 365 observability service. This feature eliminates the need for developers to write monitoring code manually, simplifies setup, and ensures consistent performance tracking.

Multiple SDKs and platforms support auto-instrumentation:

Platform Supported SDKs / Frameworks
.NET Semantic Kernel, OpenAI, Agent Framework
Python Semantic Kernel, OpenAI, Agent Framework, LangChain
Node.js OpenAI, LangChain

Note

Support for auto-instrumentation varies by platform and SDK implementation.

Semantic Kernel

Auto instrumentation requires the use of baggage builder. Set agent ID and tenant ID by using BaggageBuilder.

Install the package.

pip install microsoft-agents-a365-observability-extensions-semantic-kernel

Configure observability.

from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.extensions.semantickernel.trace_instrumentor import SemanticKernelInstrumentor

# Configure observability
configure(
    service_name="my-semantic-kernel-agent",
    service_namespace="ai.agents"
)

# Enable auto-instrumentation
instrumentor = SemanticKernelInstrumentor()
instrumentor.instrument()

# Your Semantic Kernel code is now automatically traced

OpenAI

Auto instrumentation requires the use of baggage builder. Set agent ID and tenant ID by using BaggageBuilder.

Install the package.

pip install microsoft-agents-a365-observability-extensions-openai

Configure observability.

from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.extensions.openai import OpenAIAgentsTraceInstrumentor

# Configure observability
configure(
    service_name="my-openai-agent",
    service_namespace="ai.agents"
)

# Enable auto-instrumentation
instrumentor = OpenAIAgentsTraceInstrumentor()
instrumentor.instrument()

# Your OpenAI Agents code is now automatically traced

Agent Framework

Auto instrumentation requires the use of baggage builder. Set agent ID and tenant ID by using BaggageBuilder.

Install the package.

pip install microsoft-agents-a365-observability-extensions-agent-framework

Configure observability.

from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.extensions.agentframework import (
    AgentFrameworkInstrumentor,
)

# Configure observability
configure(
    service_name="AgentFrameworkTracingWithAzureOpenAI",
    service_namespace="AgentFrameworkTesting",
)

# Enable auto-instrumentation
AgentFrameworkInstrumentor().instrument()

LangChain Framework

Auto-instrumentation requires the use of baggage builder. Set agent ID and tenant ID by using BaggageBuilder.

Install the package.

pip install microsoft-agents-a365-observability-extensions-langchain

Configure observability.

from microsoft_agents_a365.observability.core.config import configure
from microsoft_agents_a365.observability.extensions.langchain import CustomLangChainInstrumentor

# Configure observability
configure(
    service_name="my-langchain-agent",
    service_namespace="ai.agents"
)

# Enable auto-instrumentation
CustomLangChainInstrumentor()

# Your LangChain code is now automatically traced

Manual Instrumentation

Use Agent 365 observability SDK to understand the internal working of the agent. The SDK provides scopes that you can start: InvokeAgentScope, ExecuteToolScope, InferenceScope, and OutputScope.

Agent invocation

Use this scope at the start of your agent process. By using the invoke agent scope, you can capture properties like the current agent being invoked, agent user data, and more.

from microsoft_agents_a365.observability.core import (
    InvokeAgentScope,
    InvokeAgentScopeDetails,
    AgentDetails,
    CallerDetails,
    UserDetails,
    Channel,
    Request,
    ServiceEndpoint,
)

agent_details = AgentDetails(
    agent_id="agent-456",
    agent_name="My Agent",
    agent_description="An AI agent powered by Azure OpenAI",
    agentic_user_id="auid-123",
    agentic_user_email="agent@contoso.com",
    agent_blueprint_id="blueprint-789",
    tenant_id="tenant-123",
)

scope_details = InvokeAgentScopeDetails(
    endpoint=ServiceEndpoint(hostname="myagent.contoso.com", port=443),
)

request = Request(
    content="User asks a question",
    session_id="session-42",
    conversation_id="conv-xyz",
    channel=Channel(name="msteams"),
)

caller_details = CallerDetails(
    user_details=UserDetails(
        user_id="user-123",
        user_email="jane.doe@contoso.com",
        user_name="Jane Doe",
    ),
)

with InvokeAgentScope.start(request, scope_details, agent_details, caller_details):
    # Perform agent invocation logic
    response = call_agent(...)

Tool execution

The following examples show how to add observability tracking to your agent's tool execution. This tracking captures telemetry for monitoring and auditing purposes.

from microsoft_agents_a365.observability.core import (
    ExecuteToolScope,
    ToolCallDetails,
    Request,
    ServiceEndpoint,
)

# Use the same agent_details and request instances from the InvokeAgentScope example above

tool_details = ToolCallDetails(
    tool_name="summarize",
    tool_type="function",
    tool_call_id="tc-001",
    arguments="{'text': '...'}",
    description="Summarize provided text",
    endpoint=ServiceEndpoint(hostname="tools.contoso.com", port=8080),
)

with ExecuteToolScope.start(request, tool_details, agent_details) as scope:
    result = run_tool(tool_details)
    scope.record_response(result)

Inference

The following examples show how to instrument AI model inference calls with observability tracking to capture token usage, model details, and response metadata.

from microsoft_agents_a365.observability.core import (
    InferenceScope,
    InferenceCallDetails,
    InferenceOperationType,
)

# Use the same agent_details and request instances from the InvokeAgentScope example above

inference_details = InferenceCallDetails(
    operationName=InferenceOperationType.CHAT,
    model="gpt-4o-mini",
    providerName="azure-openai",
    inputTokens=123,
    outputTokens=456,
    finishReasons=["stop"],
)

with InferenceScope.start(request, inference_details, agent_details) as scope:
    completion = call_llm(...)
    scope.record_output_messages([completion.text])
    scope.record_input_tokens(completion.usage.input_tokens)
    scope.record_output_tokens(completion.usage.output_tokens)

Output

Use this scope for asynchronous scenarios where InvokeAgentScope, ExecuteToolScope, or InferenceScope can't capture output data synchronously. Start OutputScope as a child span to record the final output messages after the parent scope finishes.

from microsoft_agents_a365.observability.core import (
    OutputScope,
    Response,
    SpanDetails,
)

# Use the same agent_details and request instances from the InvokeAgentScope example above

# Get the parent context from the originating scope
parent_context = invoke_scope.get_context()

response = Response(messages=["Here is your organized inbox with 15 urgent emails."])

with OutputScope.start(
    request,
    response,
    agent_details,
    span_details=SpanDetails(parent_context=parent_context),
):
    # Output messages are recorded automatically from the response
    pass

Validate locally

To verify that you successfully integrated with the observability SDK, examine the console logs generated by your agent.

Set the environment variable ENABLE_A365_OBSERVABILITY_EXPORTER to false. This setting exports spans (traces) to the console.

To investigate export failures, enable verbose logging by setting ENABLE_A365_OBSERVABILITY_EXPORTER to true and configuring debug logging in your application startup:

import logging

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("microsoft_agents_a365.observability.core").setLevel(logging.DEBUG)

# Or target only the exporter:
logging.getLogger(
    "microsoft_agents_a365.observability.core.exporters.agent365_exporter"
).setLevel(logging.DEBUG)

Key log messages:

DEBUG  Token resolved for agent {agentId} tenant {tenantId}
DEBUG  Exporting {n} spans to {url}
DEBUG  HTTP 200 - correlation ID: abc-123
ERROR  Token resolution failed: {error}
ERROR  HTTP 401 exporting spans - correlation ID: abc-123
INFO   No spans with tenant/agent identity found; nothing exported.

Prerequisites for viewing exported logs

Before you can view agent telemetry in Microsoft Purview or Microsoft Defender, make sure the following prerequisites are met:

Observability requirements

IT administrators use the data you set in your code to monitor your agent's activity. Incomplete data means you don't fully realize the benefits of observability. Agents must provide the required data to receive all expected benefits. A validation process verifies that this data exists.

Within telemetry, there are concepts of scope or context. Each operation your agent performs exists within a different scope. You must include the data within the BaggageScope created by using Baggage attributes, or within the individual scopes as described in Manual Instrumentation.

To validate your implementation, follow the instructions to validate locally to generate console logs for your instrumentation. Then review the Validate for store publishing section to identify which attributes are required and which are optional. You must set all required attributes to successfully pass validation.

Review the required properties and parameter values described for these classes:

  • Properties you set by using the BaggageBuilder class might be set or overridden by the properties for the respective scopes.

  • Set the properties in the following table by using the InvokeAgentScope.start method.

    Data Description
    invoke_agent_details.details.agent_id The unique identifier for the AI agent
    invoke_agent_details.details.agent_name The human-readable name of the AI agent
    invoke_agent_details.details.agent_auid The agent user ID (AUID)
    invoke_agent_details.details.agent_upn The agent user principal name (UPN)
    invoke_agent_details.details.agent_blueprint_id The agent blueprint/application ID
    invoke_agent_details.details.tenant_id The tenant ID for the agent
    invoke_agent_details.details.conversation_id The identifier for the conversation or session
    invoke_agent_details.endpoint The endpoint for the agent invocation
    tenant_details.tenant_id The unique identifier for the tenant
    request.content The payload content sent to the agent for invocation
    request.execution_type Invocation type indicating request origin (for example, HumanToAgent or AgentToAgent)
    caller_details.caller_id The unique identifier for the caller
    caller_details.caller_upn The user principal name (UPN) of the caller
    caller_details.caller_user_id The user ID of the caller
    caller_details.tenant_id The tenant ID of the caller
  • Set the properties in the following table by using the ExecuteToolScope.start method.

    Data Description
    details.tool_name The name of the tool being executed
    details.arguments Tool arguments or parameters
    details.tool_call_id The unique identifier for the tool call
    details.tool_type The type of the tool being executed
    details.endpoint If an external tool call is made
    agent_details.agent_id The unique identifier for the AI agent
    agent_details.agent_name The human-readable name of the AI agent
    agent_details.agent_auid The agent user ID
    agent_details.agent_upn The agent user principal name (UPN)
    agent_details.agent_blueprint_id The agent blueprint or application ID
    agent_details.tenant_id Tenant ID for the agent.
    agent_details.conversation_id The conversation ID for the agent invocation.
    tenant_details.tenant_id Tenant ID for the agent.
  • Set the properties in the following table by using the InferenceScope.start method.

    Data Description
    details.operationName The operation name or type for the inference
    details.model The model name or identifier
    details.providerName The provider name
    agent_details.agent_id The unique identifier for the AI agent
    agent_details.agent_name The human-readable name of the AI agent
    agent_details.agent_auid The agent user ID (AUID)
    agent_details.agent_upn The agent user principal name (UPN)
    agent_details.agent_blueprint_id The agent blueprint or application ID
    agent_details.tenant_id The unique identifier for the tenant
    agent_details.conversation_id The identifier for the conversation or session
    tenant_details.tenant_id The unique identifier for the tenant
    request.content The payload content sent to the agent for inference
    request.execution_type Invocation type indicating request origin (for example, HumanToAgent or AgentToAgent)
    request.source_metadata Represent the channel information

Validate for store publishing

Before publishing, use console logs to validate your observability integration for the agent by implementing the required invoke agent, execute tool, inference, and output scopes. Then compare your agent's logs against the following attribute lists to verify all required attributes are present. Capture attributes on each scope or through the baggage builder, and include optional attributes at your discretion.

For more information about store publishing requirements, see store validation guidelines.

InvokeAgentScope attributes

The following list summarizes the required and optional telemetry attributes recorded when you start an InvokeAgentScope.

"attributes": {
        "error.type": "Optional",
        "microsoft.a365.agent.blueprint.id": "Required",
        "gen_ai.agent.description": "Optional",
        "gen_ai.agent.id": "Required",
        "gen_ai.agent.name": "Required",
        "microsoft.a365.agent.platform.id": "Optional",
        "microsoft.agent.user.email": "Required",
        "microsoft.agent.user.id": "Required",
        "gen_ai.agent.version": "Optional",
        "microsoft.a365.caller.agent.blueprint.id": "Optional",
        "microsoft.a365.caller.agent.id": "Optional",
        "microsoft.a365.caller.agent.name": "Optional",
        "microsoft.a365.caller.agent.platform.id": "Optional",
        "microsoft.a365.caller.agent.user.email": "Optional",
        "microsoft.a365.caller.agent.user.id": "Optional",
        "microsoft.a365.caller.agent.version": "Optional",
        "client.address": "Required",
        "user.id": "Required",
        "user.name": "Optional",
        "user.email": "Required",
        "microsoft.channel.link": "Optional",
        "microsoft.channel.name": "Required",
        "gen_ai.conversation.id": "Required",
        "microsoft.conversation.item.link": "Optional",
        "gen_ai.input.messages": "Required",
        "gen_ai.operation.name": "Required",
        "gen_ai.output.messages": "Required",
        "server.address": "Required",
        "server.port": "Required",
        "microsoft.session.id": "Optional",
        "microsoft.session.description": "Optional",
        "microsoft.tenant.id": "Required"
    }

ExecuteToolScope attributes

The following list summarizes the required and optional telemetry attributes recorded when you start an ExecuteToolScope.

"attributes": {
        "error.type": "Optional",
        "microsoft.a365.agent.blueprint.id": "Required",
        "gen_ai.agent.description": "Optional",
        "gen_ai.agent.id": "Required",
        "gen_ai.agent.name": "Required",
        "microsoft.a365.agent.platform.id": "Optional",
        "microsoft.agent.user.email": "Required",
        "microsoft.agent.user.id": "Required",
        "gen_ai.agent.version": "Optional",
        "client.address": "Required",
        "user.id": "Required",
        "user.name": "Optional",
        "user.email": "Required",
        "microsoft.channel.link": "Optional",
        "microsoft.channel.name": "Required",
        "gen_ai.conversation.id": "Required",
        "microsoft.conversation.item.link": "Optional",
        "gen_ai.operation.name": "Required",
        "gen_ai.tool.call.arguments": "Required",
        "gen_ai.tool.call.id": "Required",
        "gen_ai.tool.call.result": "Required",
        "gen_ai.tool.description": "Optional",
        "gen_ai.tool.name": "Required",
        "gen_ai.tool.type": "Required",
        "server.address": "Optional",
        "server.port": "Optional",
        "microsoft.session.id": "Optional",
        "microsoft.session.description": "Optional",
        "microsoft.tenant.id": "Required"
    }

InferenceScope attributes

The following list summarizes the required and optional telemetry attributes recorded when you start an InferenceScope.

"attributes": {
        "error.type": "Optional",
        "microsoft.a365.agent.blueprint.id": "Required",
        "gen_ai.agent.description": "Optional",
        "gen_ai.agent.id": "Required",
        "gen_ai.agent.name": "Required",
        "microsoft.a365.agent.platform.id": "Optional",
        "microsoft.a365.agent.thought.process": "Optional",
        "microsoft.agent.user.email": "Required",
        "microsoft.agent.user.id": "Required",
        "gen_ai.agent.version": "Optional",
        "client.address": "Required",
        "user.id": "Required",
        "user.name": "Optional",
        "user.email": "Required",
        "microsoft.channel.link": "Optional",
        "microsoft.channel.name": "Required",
        "gen_ai.conversation.id": "Required",
        "microsoft.conversation.item.link": "Optional",
        "gen_ai.input.messages": "Required",
        "gen_ai.operation.name": "Required",
        "gen_ai.output.messages": "Required",
        "gen_ai.provider.name": "Required",
        "gen_ai.request.model": "Required",
        "gen_ai.response.finish_reasons": "Optional",
        "gen_ai.usage.input_tokens": "Optional",
        "gen_ai.usage.output_tokens": "Optional",
        "server.address": "Optional",
        "server.port": "Optional",
        "microsoft.session.description": "Optional",
        "microsoft.session.id": "Optional",
        "microsoft.tenant.id": "Required"
    }

OutputScope attributes

The following list summarizes the required and optional telemetry attributes recorded when you start an OutputScope. Use this scope for asynchronous scenarios where the parent scope can't capture output data synchronously.

"attributes": {
        "microsoft.a365.agent.blueprint.id": "Required",
        "gen_ai.agent.description": "Optional",
        "gen_ai.agent.id": "Required",
        "gen_ai.agent.name": "Required",
        "microsoft.a365.agent.platform.id": "Optional",
        "microsoft.agent.user.email": "Required",
        "microsoft.agent.user.id": "Required",
        "gen_ai.agent.version": "Optional",
        "client.address": "Required",
        "user.id": "Required",
        "user.name": "Optional",
        "user.email": "Required",
        "microsoft.channel.link": "Optional",
        "microsoft.channel.name": "Required",
        "gen_ai.conversation.id": "Required",
        "microsoft.conversation.item.link": "Optional",
        "gen_ai.operation.name": "Required",
        "gen_ai.output.messages": "Required",
        "microsoft.session.id": "Optional",
        "microsoft.session.description": "Optional",
        "microsoft.tenant.id": "Required"
    }

Test your agent with observability

After you implement observability in your agent, test it to make sure it captures telemetry correctly. Follow the testing guide to set up your environment. Then, focus primarily on the View observability logs section to validate your observability implementation is working as expected.

Verification:

  • Go to: https://admin.cloud.microsoft/#/agents/all
  • Select your agent > Activity
  • You see sessions and tool calls

Troubleshooting

This section describes common problems when implementing and using observability.

Tip

Agent 365 Troubleshooting Guide contains high-level troubleshooting recommendations, best practices, and links to troubleshooting content for each part of the Agent 365 development lifecycle.

Observability data doesn't appear

Symptoms:

  • Agent is running
  • No telemetry in admin center
  • Can't see agent activity

Root cause:

  • Observability isn't enabled
  • Configuration errors
  • Token resolver problems

Solutions: Try the following steps to resolve the problem:

  • Verify observability is enabled

    Enable observability flags in your environment.

    # .env file
    ENABLE_A365_OBSERVABILITY_EXPORTER=true
    
  • Check token resolver configuration

    Make sure your code properly implements the token resolver. Check the latest code in the SDK directly.

  • Check for errors in logs

    Use the az webapp log tail command to search logs for observability-related errors.

    # Look for observability-related errors
    az webapp log tail --name <your-app-name> --resource-group <your-resource-group> | Select-String "observability"
    
  • Verify telemetry export

    Confirm telemetry is generated and exported as expected.

    • Add console exporter for testing
    • Check if telemetry is generated locally

Learn more about testing observability: