Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4362fce
PYTHON-5947 Add OpenTelemetry operation spans
blink1073 Aug 17, 2026
c5a7e35
PYTHON-5947 Reword the tracing-disabled test comment
blink1073 Aug 18, 2026
3c66e0f
PYTHON-5947 Drop a forward reference from the validator test comment
blink1073 Aug 18, 2026
372e87a
PYTHON-5947 Run the otel tests in GitHub Actions and drop a supersede…
blink1073 Aug 18, 2026
caf81e0
PYTHON-5947 Pin the actions in the temporary otel job and move it to …
blink1073 Aug 18, 2026
f58393a
PYTHON-5947 Clarify the operation_telemetry docstrings
blink1073 Aug 19, 2026
4ee2199
PYTHON-5947 Give unacknowledged collection bulk writes an operation span
blink1073 Aug 20, 2026
a698db5
PYTHON-5947 Trim the operation telemetry comments and docstrings
blink1073 Aug 21, 2026
0911f6d
PYTHON-5947 Restore the review answers the trim removed
blink1073 Aug 23, 2026
77c58ec
PYTHON-5947 Say current span rather than ambient span
blink1073 Aug 23, 2026
270ffd5
PYTHON-5947 Mark up None and tighten the tracing docstrings
blink1073 Aug 24, 2026
96c8ea6
PYTHON-5947 Point the operation name overrides at PYTHON-6054
blink1073 Aug 26, 2026
a7477a8
PYTHON-5947 Name the unspecified operations in the overrides comment
blink1073 Aug 26, 2026
5a17e59
PYTHON-5947 Note the open spec questions in the overrides comment
blink1073 Sep 1, 2026
7fcc1f0
PYTHON-5947 Cut the tracing comments back to what the code doesn't show
blink1073 Sep 1, 2026
4500c80
PYTHON-5947 Address the operation span review comments
blink1073 Sep 1, 2026
8c05974
PYTHON-5947 Say why the backfill runs on every attempt
blink1073 Sep 1, 2026
c174e0d
PYTHON-5947 Tighten the backfill comment
blink1073 Sep 1, 2026
c455df4
PYTHON-5947 Say what a repeated backfill writes
blink1073 Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .evergreen/generated_configs/variants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,10 @@ buildvariants:
# Otel tests
- name: otel-rhel8
tasks:
- name: .test-non-standard .standalone-noauth-nossl
- name: .test-non-standard .replica_set-noauth-ssl
- name: .test-non-standard .sharded_cluster-auth-ssl .python-3.14
- name: .test-non-standard .sharded_cluster-auth-ssl .python-pypy3.11
- name: .test-non-standard .standalone-noauth-nossl .python-3.10
display_name: OTel RHEL8
run_on:
- rhel87-small
Expand Down
18 changes: 17 additions & 1 deletion .evergreen/scripts/generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,23 @@ def create_otel_variants():
expansions = dict(TEST_NAME="otel", COVERAGE="1")
return [
create_variant(
[".test-non-standard .standalone-noauth-nossl"],
[
# All three topologies, subset to keep the task count at 22.
#
# Replica set keeps every task: the only topology where transaction spans
# run at all (they are skipped on standalone and sharded), and
# the only one covering free-threaded Python.
".test-non-standard .replica_set-noauth-ssl",
# Sharded adds mongos, which rewrites commands and reports a
# different server.address, plus auth and ssl, which exercise
# sensitive-command redaction. Newest CPython across server
# versions, and PyPy for the alternate implementation.
".test-non-standard .sharded_cluster-auth-ssl .python-3.14",
".test-non-standard .sharded_cluster-auth-ssl .python-pypy3.11",
# Standalone only for its min-deps tasks, which resolve
# opentelemetry-api down to the floor in requirements/.
".test-non-standard .standalone-noauth-nossl .python-3.10",
],
get_variant_name("OTel", host),
host=host,
tags=["pr"],
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,36 @@ jobs:
source .venv/bin/activate
uv pip install -e ".[test]" --resolution=lowest-direct --force-reinstall
pytest -v test/test_srv_polling.py test/test_dns.py test/asynchronous/test_srv_polling.py test/asynchronous/test_dns.py

# TEMPORARY, remove before merging the PYTHON-5947 stack.
#
# Evergreen only runs on PRs whose base is a configured branch, so the upper
# PRs in this stack (based on each other rather than on otel) get no Evergreen
# coverage at all, and the otel tests only run in Evergreen's otel variant.
# This job runs them on every branch in the stack instead. A replica set is
# requested because the transaction span tests require one. Actions are pinned
# to commit hashes here, unlike the rest of this file, to satisfy the
# mutable-action-tag scanners on newly added lines.
otel:
runs-on: ubuntu-latest
name: OTel Tests (temporary)
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
python-version: "3.11"
- id: setup-mongodb
uses: mongodb-labs/drivers-evergreen-tools@c70d29e2102cd048ad800932209776499553870c # v1.0.1
with:
version: "8.0"
topology: "replica_set"
- name: Install just
run: uv tool install rust-just
- name: Setup tests
run: TEST_NAME=otel just setup-tests
- name: Run tests
run: just run-tests
10 changes: 4 additions & 6 deletions bson/json_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -1115,20 +1115,18 @@ def _truncate_documents(obj: Any, max_length: int) -> tuple[Any, int]:
if hasattr(obj, "items"):
truncated: Any = {}
for k, v in obj.items():
truncated_v, remaining = _truncate_documents(v, remaining)
if truncated_v:
truncated[k] = truncated_v
if remaining <= 0:
break
truncated_v, remaining = _truncate_documents(v, remaining)
truncated[k] = truncated_v
return truncated, remaining
elif hasattr(obj, "__iter__") and not isinstance(obj, (str, bytes)):
truncated: Any = [] # type:ignore[no-redef]
for v in obj:
truncated_v, remaining = _truncate_documents(v, remaining)
if truncated_v:
truncated.append(truncated_v)
if remaining <= 0:
break
truncated_v, remaining = _truncate_documents(v, remaining)
truncated.append(truncated_v)
return truncated, remaining
else:
return _truncate(obj, remaining)
Expand Down
11 changes: 7 additions & 4 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ PyMongo 4.18 brings a number of changes including:
attempts, so consumers can correlate a retried operation's events. As a
result, ``operation_id`` is no longer equal to the per-attempt ``request_id``
for these operations.
- Added optional OpenTelemetry command-span support, conforming to the
- Added optional OpenTelemetry tracing support, conforming to the
`OpenTelemetry driver specification <https://github.com/mongodb/specifications/blob/master/source/open-telemetry/open-telemetry.md>`_.
Enable it with the ``tracing`` :class:`~pymongo.mongo_client.MongoClient`
option or the ``OTEL_PYTHON_INSTRUMENTATION_MONGODB_ENABLED`` environment
variable. Install the ``opentelemetry-api`` package, or use the
Every public API call produces an operation span, which contains one span
per command sent to the server. Inside a transaction, those operation spans
nest under a ``transaction`` span. Enable it with the
``tracing`` :class:`~pymongo.mongo_client.MongoClient` option or the
``OTEL_PYTHON_INSTRUMENTATION_MONGODB_ENABLED`` environment variable.
Install the ``opentelemetry-api`` package, or use the
``pymongo[opentelemetry]`` extra, to enable this feature.
- Fixed a potential out-of-bounds read in the C extension when decoding an
array of BSON documents. An embedded document whose declared length exceeds
Expand Down
Loading
Loading