Skip to content

PYTHON-5745 Consolidate command telemetry#2891

Open
blink1073 wants to merge 5 commits into
mongodb:masterfrom
blink1073:PYTHON-5745
Open

PYTHON-5745 Consolidate command telemetry#2891
blink1073 wants to merge 5 commits into
mongodb:masterfrom
blink1073:PYTHON-5745

Conversation

@blink1073

@blink1073 blink1073 commented Jun 24, 2026

Copy link
Copy Markdown
Member

PYTHON-5745

Changes in this PR

Introduces pymongo/_telemetry.py with a _CommandTelemetry class that unifies structured logging and APM event publishing for command lifecycle events into a single internal API. This refactor is a stepping stone to adding OpenTelemetry support in a _telemetry.py, so all event-related handling is in one centralized location.

Test Plan

No new tests: this is a behavior-preserving refactor. The existing APM / command-monitoring and command-logging spec suites assert the exact event and log documents that any regression would change.

Checklist

Checklist for Author

  • Did you update the changelog (if necessary)? — Not necessary; internal refactor with no user-facing behavior change.
  • Is there test coverage? — Covered by existing spec suites (behavior preserved).
  • Is any followup work tracked in a JIRA ticket? If so, add link(s). — PYTHON-5846 will extend this pattern to cover the remaining logging and APM event types.

Checklist for Reviewer

  • Does the title of the PR reference a JIRA Ticket?
  • Do you fully understand the implementation? (Would you be comfortable explaining how this code works to someone else?)
  • Is all relevant documentation (README or docstring) updated?

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@blink1073 blink1073 marked this pull request as ready for review June 24, 2026 20:47
@blink1073 blink1073 requested a review from a team as a code owner June 24, 2026 20:47
@blink1073 blink1073 requested a review from NoahStapp June 24, 2026 20:47
@NoahStapp NoahStapp requested a review from Copilot June 25, 2026 14:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors command lifecycle telemetry by centralizing structured command logging and APM command monitoring event publishing into a single internal helper (_CommandTelemetry) in pymongo/_telemetry.py, and updates both sync/async command execution paths to use it.

Changes:

  • Added pymongo/_telemetry.py with _CommandTelemetry to unify STARTED/SUCCEEDED/FAILED command logging + APM publishing and duration tracking.
  • Updated sync/async command_runner.py to delegate command telemetry to _CommandTelemetry and simplified call signatures (removing explicit address/start plumbing).
  • Introduced _ConnectionTelemetryInfo protocol and updated sync/async pool connection classes to provide the telemetry-required connection fields.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pymongo/_telemetry.py New centralized internal helper for command telemetry (logging + APM publishing).
pymongo/pool_shared.py Adds _ConnectionTelemetryInfo protocol to type required connection metadata for telemetry.
pymongo/message.py Removes bulk write start_time tracking now handled by telemetry helper.
pymongo/synchronous/command_runner.py Replaces inline telemetry logic with _CommandTelemetry and updates _run_command signature.
pymongo/asynchronous/command_runner.py Async equivalent refactor to _CommandTelemetry and updated _run_command signature.
pymongo/synchronous/pool.py Sync Connection updated to satisfy telemetry connection interface; updates run_command call plumbing.
pymongo/asynchronous/pool.py Async AsyncConnection updated to satisfy telemetry connection interface; updates run_command call plumbing.
pymongo/synchronous/server.py Removes now-unneeded start/address telemetry plumbing for cursor ops.
pymongo/asynchronous/server.py Async equivalent removal of start/address telemetry plumbing for cursor ops.

Comment thread pymongo/pool_shared.py
Comment thread pymongo/_telemetry.py Outdated
self._duration = datetime.datetime.now() - self._start
if not self._should_log and not self._publish:
return
duration = self._duration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this assignment? self._duration should only get assigned once per _CommandTelemetry lifecycle.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread pymongo/_telemetry.py Outdated
self._duration = datetime.datetime.now() - self._start
if not self._should_log and not self._publish:
return
duration = self._duration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread pymongo/_telemetry.py
request_id: int,
op_id: Optional[int],
) -> None:
self._topology_id = topology_id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We construct the whole object even if self.should_log = False, does it make sense to have the constructor short-circuit out with that as the first check?

Comment thread pymongo/_telemetry.py
self._start: datetime.datetime
self._duration: datetime.timedelta

def started(self, orig: MutableMapping[str, Any], ensure_db: bool) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we refactor started, succeeded, failed (or a subset) to use a common internal helper like _emit? All three are very similar and effectively just pass through kwargs to debug_log.

Comment thread pymongo/pool_shared.py
from pymongo.typings import _Address


class _ConnectionTelemetryInfo(Protocol):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to use this over the existing _AgnosticConnection?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants