Skip to content

Python: [Bug]: configure_otel_providers duplicates log export when the app has a root OTel LoggingHandler #9896

Closed

Description

Observed Behavior

configure_otel_providers attaches an OpenTelemetry LoggingHandler to the agent_framework logger (observability.py, _configure_providers), although the adjacent comment says "to the root logger". If the application has also attached an OTel LoggingHandler to the root logger (for example to export its own, httpx and azure logs), every agent_framework.* log record is exported twice: once by the MAF handler and once by the root handler after propagation.

Expected Behavior

Each log record is exported once. When the root logger already has an OTel LoggingHandler, MAF's records already reach the exporter through propagation, so MAF should not add a second handler.

Steps to Reproduce

  1. Call configure_otel_providers with a log exporter.
  2. Attach LoggingHandler(logger_provider=get_logger_provider()) to the root logger.
  3. Emit a record from an agent_framework.* logger.
  4. Inspect the exported records.

Minimal Reproduction

import logging
from opentelemetry._logs import get_logger_provider
from opentelemetry.sdk._logs import LoggingHandler
from opentelemetry.sdk._logs.export import InMemoryLogRecordExporter
from agent_framework.observability import configure_otel_providers

exporter = InMemoryLogRecordExporter()
configure_otel_providers(exporters=[exporter])
logging.getLogger().addHandler(LoggingHandler(logger_provider=get_logger_provider()))
logging.getLogger().setLevel(logging.INFO)

logging.getLogger("agent_framework.test").warning("hello")
get_logger_provider().force_flush()
print(len(exporter.get_finished_logs()))  # prints 2, expected 1

Package Versions

agent-framework-core: 1.23.0 (main), opentelemetry-sdk: 1.44.0

Python Version

Python 3.13

Operating System

macOS

Regression

Unknown

Additional Context

Proposed fix: before adding the handler, skip it if the root logger already has an OTel LoggingHandler. This only helps when the application attaches its root handler before calling configure_otel_providers; applications that attach it afterwards still need to remove the MAF handler themselves. The comment should also be corrected to say agent_framework logger. I have a small PR ready if the direction is agreeable.

AI assistance: the issue analysis, reproduction and this write-up were prepared with AI assistance. I ran the reproduction and verified the output myself.

Activity

  1. added
    pythonUsage: [Issues, PRs], Target: Python
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 30, 2026
  2. added
    reproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
    on Oct 30, 2026
  3. github-actions commented on Oct 30, 2026

    @github-actions
    Contributor

    🤖 Automated triage reproduction notes (agent-authored — trust but verify)

    Agent analysis

    Repro: python/packages/core/agent_framework/observability.py::ObservabilitySettings._configure_providers at lines 1353-1361 duplicates exports when log exporters are configured and the root logger also has an OTel LoggingHandler. Minimal repro: configure an InMemoryLogRecordExporter, add a handler using the global provider to root, emit one agent_framework.test warning, flush, and observe two records.

    • Failing test: python/packages/core/tests/core/test_observability.py::test_configure_otel_providers_does_not_duplicate_logs_with_root_otel_handler
    • Files examined: python/packages/core/agent_framework/observability.py, python/packages/core/tests/core/test_observability.py, python/packages/core/tests/conftest.py, python/packages/core/pyproject.toml
    • Tests run: uv run pytest packages/core/tests/core/test_observability.py::test_configure_otel_providers_does_not_duplicate_logs_with_root_otel_handler -q
    • Reported version: 1.23.0
    • Current version: 1.24.0
  4. added
    agentsUsage: [Issues, PRs], Target: Single agent
    observabilityUsage: [Issues, PRs], Target: observability related features
    and removed
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 30, 2026
  5. eavanvalkenburg commented on Nov 2, 2026

    @eavanvalkenburg
    Member

    Maintainer direction: this should not change configure_otel_providers() runtime behavior. Resolve the issue by clarifying the function’s docstring. configure_otel_providers() is a convenience setup for Agent Framework telemetry; it does not inspect, coordinate with, or make assumptions about an application’s other logging handlers. Applications that combine it with their own root LoggingHandler configuration own that composition and should use manual OpenTelemetry setup when they need custom providers, filters, propagation, or exporters. Point the docstring to python/samples/02-agents/observability/advanced_manual_setup_console_output.py as the manual setup example.

  6. droideronline commented on Nov 2, 2026

    @droideronline
    ContributorAuthor

    Thanks for the direction. I've reworked #9897 to be docstring only: no runtime change, a note that configure_otel_providers() does not coordinate with the application's other logging handlers, and a pointer to advanced_manual_setup_console_output.py for manual setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

agentsUsage: [Issues, PRs], Target: Single agentobservabilityUsage: [Issues, PRs], Target: observability related featurespythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions