Skip to content

PYTHON-5745 Consolidate command logging and monitoring logic#2822

Draft
blink1073 wants to merge 6 commits into
mongodb:masterfrom
blink1073:PYTHON-5745
Draft

PYTHON-5745 Consolidate command logging and monitoring logic#2822
blink1073 wants to merge 6 commits into
mongodb:masterfrom
blink1073:PYTHON-5745

Conversation

@blink1073
Copy link
Copy Markdown
Member

@blink1073 blink1073 commented May 27, 2026

[PYTHON-5745]

Changes in this PR

Introduces pymongo/_telemetry.py with a _CommandTelemetry context manager that unifies debug logging and APM event publishing into a single call site, eliminating duplicated telemetry blocks at each command call site. This is a prerequisite for PYTHON-5052 (OpenTelemetry support).

Based on the spike in #2720.

Test Plan

  • just typing passes
  • just lint passes
  • Full CI covers command monitoring and logging specs

Checklist

Checklist for Author

  • Did you update the changelog (if necessary)?
  • Is there test coverage?
  • Is any followup work tracked in a JIRA ticket? If so, add link(s).

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?

@blink1073 blink1073 changed the title PYTHON-5745 Consolidate command logging and monitoring into _CommandTelemetry PYTHON-5745 Consolidate command logging and monitoring logic May 27, 2026
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 27, 2026

Codecov Report

❌ Patch coverage is 88.06818% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.19%. Comparing base (537aa0b) to head (c5f8cba).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
pymongo/asynchronous/server.py 53.33% 6 Missing and 1 partial ⚠️
pymongo/synchronous/server.py 53.33% 6 Missing and 1 partial ⚠️
pymongo/asynchronous/client_bulk.py 85.71% 3 Missing ⚠️
pymongo/synchronous/client_bulk.py 85.71% 3 Missing ⚠️
pymongo/synchronous/monitor.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2822      +/-   ##
==========================================
+ Coverage   82.46%   88.19%   +5.72%     
==========================================
  Files         140      142       +2     
  Lines       24173    24198      +25     
  Branches     4128     4079      -49     
==========================================
+ Hits        19935    21342    +1407     
+ Misses       3362     1984    -1378     
+ Partials      876      872       -4     
Flag Coverage Δ
auth-aws-rhel8-test-auth-aws-rapid-web-identity-python3.14-cov 35.39% <34.65%> (+0.36%) ⬆️
auth-aws-win64-test-auth-aws-rapid-web-identity-python3.14-cov 35.39% <34.65%> (+0.36%) ⬆️
auth-enterprise-macos-test-standard-auth-latest-python3.11-auth-ssl-sharded-cluster-cov 44.11% <45.45%> (+0.36%) ⬆️
auth-enterprise-rhel8-test-standard-auth-latest-python3.11-auth-ssl-sharded-cluster-cov 44.11% <45.45%> (+0.35%) ⬆️
auth-enterprise-win64-test-standard-auth-latest-python3.11-auth-ssl-sharded-cluster-cov 44.16% <45.45%> (+0.36%) ⬆️
auth-oidc-local-ubuntu-22-test-auth-oidc-default 48.88% <55.11%> (?)
compression-snappy-rhel8-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.63% <67.04%> (+0.30%) ⬆️
compression-snappy-rhel8-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.83% <67.04%> (+0.33%) ⬆️
compression-snappy-rhel8-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.41% <65.90%> (+0.33%) ⬆️
compression-snappy-rhel8-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.30% <67.04%> (+0.31%) ⬆️
compression-zlib-rhel8-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.63% <67.04%> (+0.29%) ⬆️
compression-zlib-rhel8-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.89% <67.04%> (+0.39%) ⬆️
compression-zlib-rhel8-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.42% <65.90%> (+0.33%) ⬆️
compression-zlib-rhel8-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.29% <67.04%> (+0.30%) ⬆️
compression-zstd-rhel8-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.65% <67.04%> (+0.30%) ⬆️
compression-zstd-rhel8-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.83% <67.04%> (+0.36%) ⬆️
compression-zstd-rhel8-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.40% <65.90%> (+0.31%) ⬆️
compression-zstd-rhel8-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.30% <67.04%> (+0.28%) ⬆️
compression-zstd-ubuntu-22-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.26% <67.04%> (+0.28%) ⬆️
coverage-report-coverage-report 86.98% <88.06%> (+4.53%) ⬆️
disable-test-commands-rhel8-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.62% <67.04%> (+0.28%) ⬆️
disable-test-commands-rhel8-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.84% <67.04%> (+0.34%) ⬆️
disable-test-commands-rhel8-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.42% <65.90%> (+0.33%) ⬆️
disable-test-commands-rhel8-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.27% <67.04%> (+0.28%) ⬆️
encryption-crypt_shared-macos-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 53.34% <52.84%> (?)
encryption-crypt_shared-macos-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 55.06% <52.84%> (?)
encryption-crypt_shared-macos-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 54.87% <52.84%> (?)
encryption-crypt_shared-rhel8-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 53.35% <52.84%> (?)
encryption-crypt_shared-rhel8-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 54.96% <52.84%> (?)
encryption-crypt_shared-rhel8-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 54.90% <52.84%> (?)
encryption-crypt_shared-win64-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 53.23% <52.84%> (?)
encryption-crypt_shared-win64-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 55.00% <52.84%> (?)
encryption-crypt_shared-win64-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 54.95% <52.84%> (?)
encryption-macos-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 53.36% <52.84%> (?)
encryption-macos-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 54.88% <52.84%> (?)
encryption-pyopenssl-rhel8-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 54.03% <52.84%> (?)
encryption-pyopenssl-rhel8-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 55.66% <52.84%> (?)
encryption-pyopenssl-rhel8-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 55.53% <52.84%> (?)
encryption-rhel8-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 53.35% <52.84%> (?)
encryption-rhel8-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 54.96% <52.84%> (?)
encryption-rhel8-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 54.87% <52.84%> (?)
encryption-win64-test-non-standard-latest-python3.13-noauth-nossl-standalone-cov 53.23% <52.84%> (?)
encryption-win64-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 55.00% <52.84%> (?)
encryption-win64-test-non-standard-latest-python3.14t-noauth-ssl-replica-set-cov 54.94% <52.84%> (?)
load-balancer-test-non-standard-latest-python3.14-auth-ssl-sharded-cluster-cov 48.68% <52.84%> (?)
mongodb-latest-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 61.79% <65.90%> (+0.33%) ⬆️
mongodb-latest-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 59.65% <67.04%> (+0.33%) ⬆️
mongodb-latest-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 59.83% <64.20%> (+0.33%) ⬆️
mongodb-latest-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 59.93% <65.34%> (+0.33%) ⬆️
mongodb-latest-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 61.73% <67.04%> (+0.32%) ⬆️
mongodb-rapid-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 61.80% <65.90%> (+0.31%) ⬆️
mongodb-rapid-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 59.64% <67.04%> (+0.32%) ⬆️
mongodb-rapid-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 59.83% <64.20%> (+0.33%) ⬆️
mongodb-rapid-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 59.93% <65.34%> (+0.34%) ⬆️
mongodb-rapid-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 61.73% <67.04%> (+0.32%) ⬆️
mongodb-v4.2-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 57.54% <55.11%> (+0.38%) ⬆️
mongodb-v4.2-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 55.95% <56.25%> (+0.33%) ⬆️
mongodb-v4.2-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 57.41% <53.40%> (+0.36%) ⬆️
mongodb-v4.2-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 57.52% <54.54%> (+0.36%) ⬆️
mongodb-v4.2-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 57.71% <56.25%> (+0.37%) ⬆️
mongodb-v4.4-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 59.89% <55.11%> (+0.31%) ⬆️
mongodb-v4.4-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 57.93% <56.25%> (+0.32%) ⬆️
mongodb-v4.4-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 57.93% <53.40%> (+0.36%) ⬆️
mongodb-v4.4-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 58.01% <54.54%> (+0.35%) ⬆️
mongodb-v4.4-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 59.70% <56.25%> (+0.35%) ⬆️
mongodb-v5.0-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 60.10% <55.11%> (+0.36%) ⬆️
mongodb-v5.0-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 58.08% <56.25%> (+0.32%) ⬆️
mongodb-v5.0-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 58.12% <53.40%> (+0.36%) ⬆️
mongodb-v5.0-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 58.25% <54.54%> (+0.37%) ⬆️
mongodb-v5.0-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 59.93% <56.25%> (+0.34%) ⬆️
mongodb-v6.0-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 60.13% <55.11%> (+0.36%) ⬆️
mongodb-v6.0-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 58.08% <56.25%> (+0.34%) ⬆️
mongodb-v6.0-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 58.15% <53.40%> (+0.36%) ⬆️
mongodb-v6.0-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 58.31% <54.54%> (+0.38%) ⬆️
mongodb-v6.0-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 60.08% <56.25%> (+0.36%) ⬆️
mongodb-v7.0-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 60.16% <55.11%> (+0.37%) ⬆️
mongodb-v7.0-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 58.08% <56.25%> (+0.37%) ⬆️
mongodb-v7.0-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 58.20% <53.40%> (+0.36%) ⬆️
mongodb-v7.0-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 58.29% <54.54%> (+0.37%) ⬆️
mongodb-v7.0-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 60.08% <56.25%> (+0.37%) ⬆️
mongodb-v8.0-test-server-version-python3.10-async-auth-ssl-sharded-cluster-min-deps-cov 61.79% <65.90%> (+0.33%) ⬆️
mongodb-v8.0-test-server-version-python3.10-async-noauth-nossl-standalone-min-deps-cov 59.62% <67.04%> (+0.28%) ⬆️
mongodb-v8.0-test-server-version-python3.10-sync-auth-ssl-sharded-cluster-min-deps-cov 59.83% <64.20%> (+0.33%) ⬆️
mongodb-v8.0-test-server-version-python3.10-sync-noauth-nossl-replica-set-min-deps-cov 59.93% <65.34%> (+0.34%) ⬆️
mongodb-v8.0-test-server-version-python3.11-async-noauth-nossl-replica-set-cov 61.74% <67.04%> (+0.34%) ⬆️
no-c-ext-rhel8-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 60.86% <67.04%> (+0.32%) ⬆️
no-c-ext-rhel8-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 63.04% <67.04%> (+0.36%) ⬆️
no-c-ext-rhel8-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 62.63% <65.90%> (+0.33%) ⬆️
no-c-ext-rhel8-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 60.49% <67.04%> (+0.29%) ⬆️
ocsp-rhel8-test-ocsp-ecdsa-valid-cert-server-staples-latest-python3.14-cov 34.58% <31.25%> (?)
ocsp-rhel8-test-ocsp-rsa-valid-cert-server-staples-latest-python3.14-cov 34.61% <31.25%> (?)
pyopenssl-macos-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 62.07% <67.04%> (?)
pyopenssl-rhel8-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 62.13% <67.04%> (?)
pyopenssl-win64-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 62.00% <67.04%> (?)
stable-api-accept-v2-rhel8-auth-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.66% <67.04%> (+0.32%) ⬆️
stable-api-accept-v2-rhel8-auth-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.29% <67.04%> (+0.30%) ⬆️
stable-api-require-v1-rhel8-auth-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.62% <67.04%> (+0.32%) ⬆️
stable-api-require-v1-rhel8-auth-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.27% <65.90%> (+0.31%) ⬆️
stable-api-require-v1-rhel8-auth-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.24% <67.04%> (+0.26%) ⬆️
storage-inmemory-rhel8-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.63% <67.04%> (+0.30%) ⬆️
storage-inmemory-rhel8-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.29% <67.04%> (+0.28%) ⬆️
test-macos-arm64-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.61% <65.90%> (+0.30%) ⬆️
test-macos-arm64-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.79% <67.04%> (+0.33%) ⬆️
test-macos-arm64-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.41% <65.90%> (+0.32%) ⬆️
test-macos-arm64-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.26% <65.90%> (+0.28%) ⬆️
test-macos-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.62% <65.90%> (+0.29%) ⬆️
test-macos-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.82% <67.04%> (+0.35%) ⬆️
test-macos-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov ?
test-macos-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.27% <65.90%> (+0.30%) ⬆️
test-numpy-macos-arm64-test-numpy-python3.14-python3.14-cov 32.93% <14.77%> (+0.31%) ⬆️
test-numpy-macos-test-numpy-python3.14-python3.14-cov 32.92% <14.77%> (+0.30%) ⬆️
test-numpy-rhel8-test-numpy-python3.14-python3.14-cov 32.93% <14.77%> (+0.31%) ⬆️
test-numpy-win32-test-numpy-python3.14-python3.14-cov 32.91% <14.77%> (+0.31%) ⬆️
test-numpy-win64-test-numpy-python3.14-python3.14-cov 32.91% <14.77%> (+0.31%) ⬆️
test-win32-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.52% <65.90%> (+0.30%) ⬆️
test-win32-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.76% <67.04%> (+0.33%) ⬆️
test-win32-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.37% <65.90%> (+0.34%) ⬆️
test-win32-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.16% <65.90%> (+0.30%) ⬆️
test-win64-test-standard-latest-python3.11-async-noauth-nossl-standalone-cov 59.50% <65.90%> (+0.32%) ⬆️
test-win64-test-standard-latest-python3.12-async-noauth-ssl-replica-set-cov 61.82% <67.04%> (+0.39%) ⬆️
test-win64-test-standard-latest-python3.13-async-auth-ssl-sharded-cluster-cov 61.39% <65.90%> (+0.32%) ⬆️
test-win64-test-standard-latest-python3.14-async-noauth-nossl-standalone-cov 59.15% <65.90%> (+0.29%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

try:
result = await bwc.conn.unack_write(msg, max_doc_size) # type: ignore[func-returns-value, misc, override]
duration = datetime.datetime.now() - bwc.start_time
if result is not None:
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.

A note about this block and the equivalent in client_bulk.py: unack_write always returns None so there will never be a result. The spec says that we always need to emit a log, so this logic was incorrect before.

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.

2 participants