Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

Changes in Version 4.6
----------------------

PyMongo 4.6 brings a number of improvements including:
- Added the :attr:`pymongo.monitoring.CommandSucceededEvent.database_name` property.
- Added the :attr:`pymongo.monitoring.CommandFailedEvent.database_name` property.

Changes in Version 4.5
----------------------

Expand Down
2 changes: 2 additions & 0 deletions pymongo/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,7 @@ def _succeed(self, request_id: int, reply: _DocumentOut, duration: timedelta) ->
self.conn.address,
self.op_id,
self.conn.service_id,
database_name=self.db_name,
)

def _fail(self, request_id: int, failure: _DocumentOut, duration: timedelta) -> None:
Expand All @@ -1109,6 +1110,7 @@ def _fail(self, request_id: int, failure: _DocumentOut, duration: timedelta) ->
self.conn.address,
self.op_id,
self.conn.service_id,
database_name=self.db_name,
)


Expand Down
70 changes: 59 additions & 11 deletions pymongo/monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ def _is_speculative_authenticate(command_name: str, doc: Mapping[str, Any]) -> b
class _CommandEvent:
"""Base class for command events."""

__slots__ = ("__cmd_name", "__rqst_id", "__conn_id", "__op_id", "__service_id")
__slots__ = ("__cmd_name", "__rqst_id", "__conn_id", "__op_id", "__service_id", "__db")

def __init__(
self,
Expand All @@ -570,12 +570,14 @@ def __init__(
connection_id: _Address,
operation_id: Optional[int],
service_id: Optional[ObjectId] = None,
database_name: str = "",
) -> None:
self.__cmd_name = command_name
self.__rqst_id = request_id
self.__conn_id = connection_id
self.__op_id = operation_id
self.__service_id = service_id
self.__db = database_name

@property
def command_name(self) -> str:
Expand Down Expand Up @@ -605,6 +607,14 @@ def operation_id(self) -> Optional[int]:
"""An id for this series of events or None."""
return self.__op_id

@property
def database_name(self) -> str:
"""The database_name this command was sent to, or ``""``.

.. versionadded:: 4.6
"""
return self.__db


class CommandStartedEvent(_CommandEvent):
"""Event published when a command starts.
Expand All @@ -619,7 +629,7 @@ class CommandStartedEvent(_CommandEvent):
- `service_id`: The service_id this command was sent to, or ``None``.
"""

__slots__ = ("__cmd", "__db")
__slots__ = ("__cmd",)

def __init__(
self,
Expand All @@ -635,14 +645,18 @@ def __init__(
# Command name must be first key.
command_name = next(iter(command))
super().__init__(
command_name, request_id, connection_id, operation_id, service_id=service_id
command_name,
request_id,
connection_id,
operation_id,
service_id=service_id,
database_name=database_name,
)
cmd_name = command_name.lower()
if cmd_name in _SENSITIVE_COMMANDS or _is_speculative_authenticate(cmd_name, command):
self.__cmd: _DocumentOut = {}
else:
self.__cmd = command
self.__db = database_name

@property
def command(self) -> _DocumentOut:
Expand All @@ -652,7 +666,7 @@ def command(self) -> _DocumentOut:
@property
def database_name(self) -> str:
"""The name of the database this command was run against."""
return self.__db
return super().database_name

def __repr__(self) -> str:
return ("<{} {} db: {!r}, command: {!r}, operation_id: {}, service_id: {}>").format(
Expand All @@ -677,6 +691,7 @@ class CommandSucceededEvent(_CommandEvent):
was sent to.
- `operation_id`: An optional identifier for a series of related events.
- `service_id`: The service_id this command was sent to, or ``None``.
- `database_name`: The database this command was sent to, or ``""``.
"""

__slots__ = ("__duration_micros", "__reply")
Expand All @@ -690,9 +705,15 @@ def __init__(
connection_id: _Address,
operation_id: Optional[int],
service_id: Optional[ObjectId] = None,
database_name: str = "",
) -> None:
super().__init__(
command_name, request_id, connection_id, operation_id, service_id=service_id
command_name,
request_id,
connection_id,
operation_id,
service_id=service_id,
database_name=database_name,
)
self.__duration_micros = _to_micros(duration)
cmd_name = command_name.lower()
Expand All @@ -713,10 +734,11 @@ def reply(self) -> _DocumentOut:

def __repr__(self) -> str:
return (
"<{} {} command: {!r}, operation_id: {}, duration_micros: {}, service_id: {}>"
"<{} {} db: {!r}, command: {!r}, operation_id: {}, duration_micros: {}, service_id: {}>"
).format(
self.__class__.__name__,
self.connection_id,
self.database_name,
self.command_name,
self.operation_id,
self.duration_micros,
Expand All @@ -736,6 +758,7 @@ class CommandFailedEvent(_CommandEvent):
was sent to.
- `operation_id`: An optional identifier for a series of related events.
- `service_id`: The service_id this command was sent to, or ``None``.
- `database_name`: The database this command was sent to, or ``""``.
"""

__slots__ = ("__duration_micros", "__failure")
Expand All @@ -749,9 +772,15 @@ def __init__(
connection_id: _Address,
operation_id: Optional[int],
service_id: Optional[ObjectId] = None,
database_name: str = "",
) -> None:
super().__init__(
command_name, request_id, connection_id, operation_id, service_id=service_id
command_name,
request_id,
connection_id,
operation_id,
service_id=service_id,
database_name=database_name,
)
self.__duration_micros = _to_micros(duration)
self.__failure = failure
Expand All @@ -768,11 +797,12 @@ def failure(self) -> _DocumentOut:

def __repr__(self) -> str:
return (
"<{} {} command: {!r}, operation_id: {}, duration_micros: {}, "
"<{} {} db: {!r}, command: {!r}, operation_id: {}, duration_micros: {}, "
"failure: {!r}, service_id: {}>"
).format(
self.__class__.__name__,
self.connection_id,
self.database_name,
self.command_name,
self.operation_id,
self.duration_micros,
Expand Down Expand Up @@ -1491,6 +1521,7 @@ def publish_command_success(
op_id: Optional[int] = None,
service_id: Optional[ObjectId] = None,
speculative_hello: bool = False,
database_name: str = "",
) -> None:
"""Publish a CommandSucceededEvent to all command listeners.

Expand All @@ -1504,6 +1535,7 @@ def publish_command_success(
- `op_id`: The (optional) operation id for this operation.
- `service_id`: The service_id this command was sent to, or ``None``.
- `speculative_hello`: Was the command sent with speculative auth?
- `database_name`: The database this command was sent to, or ``""``.
"""
if op_id is None:
op_id = request_id
Expand All @@ -1512,7 +1544,14 @@ def publish_command_success(
# speculativeAuthenticate.
reply = {}
event = CommandSucceededEvent(
duration, reply, command_name, request_id, connection_id, op_id, service_id
duration,
reply,
command_name,
request_id,
connection_id,
op_id,
service_id,
database_name=database_name,
)
for subscriber in self.__command_listeners:
try:
Expand All @@ -1529,6 +1568,7 @@ def publish_command_failure(
connection_id: _Address,
op_id: Optional[int] = None,
service_id: Optional[ObjectId] = None,
database_name: str = "",
) -> None:
"""Publish a CommandFailedEvent to all command listeners.

Expand All @@ -1542,11 +1582,19 @@ def publish_command_failure(
command was sent to.
- `op_id`: The (optional) operation id for this operation.
- `service_id`: The service_id this command was sent to, or ``None``.
- `database_name`: The database this command was sent to, or ``""``.
"""
if op_id is None:
op_id = request_id
event = CommandFailedEvent(
duration, failure, command_name, request_id, connection_id, op_id, service_id=service_id
duration,
failure,
command_name,
request_id,
connection_id,
op_id,
service_id=service_id,
database_name=database_name,
)
for subscriber in self.__command_listeners:
try:
Expand Down
9 changes: 8 additions & 1 deletion pymongo/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,13 @@ def command(
assert listeners is not None
assert address is not None
listeners.publish_command_failure(
duration, failure, name, request_id, address, service_id=conn.service_id
duration,
failure,
name,
request_id,
address,
service_id=conn.service_id,
database_name=dbname,
)
raise
if publish:
Expand All @@ -220,6 +226,7 @@ def command(
address,
service_id=conn.service_id,
speculative_hello=speculative_hello,
database_name=dbname,
)

if client and client._encrypter and reply:
Expand Down
2 changes: 2 additions & 0 deletions pymongo/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ def run_operation(
request_id,
conn.address,
service_id=conn.service_id,
database_name=dbn,
)
raise

Expand All @@ -203,6 +204,7 @@ def run_operation(
request_id,
conn.address,
service_id=conn.service_id,
database_name=dbn,
)

# Decrypt response.
Expand Down
26 changes: 17 additions & 9 deletions test/command_monitoring/find.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"description": "find",
"schemaVersion": "1.1",
"schemaVersion": "1.15",
"createEntities": [
{
"client": {
Expand Down Expand Up @@ -103,7 +103,8 @@
]
}
},
"commandName": "find"
"commandName": "find",
"databaseName": "command-monitoring-tests"
}
}
]
Expand Down Expand Up @@ -198,7 +199,8 @@
]
}
},
"commandName": "find"
"commandName": "find",
"databaseName": "command-monitoring-tests"
}
}
]
Expand Down Expand Up @@ -262,7 +264,8 @@
]
}
},
"commandName": "find"
"commandName": "find",
"databaseName": "command-monitoring-tests"
}
}
]
Expand Down Expand Up @@ -338,7 +341,8 @@
]
}
},
"commandName": "find"
"commandName": "find",
"databaseName": "command-monitoring-tests"
}
},
{
Expand Down Expand Up @@ -376,7 +380,8 @@
]
}
},
"commandName": "getMore"
"commandName": "getMore",
"databaseName": "command-monitoring-tests"
}
}
]
Expand Down Expand Up @@ -464,7 +469,8 @@
]
}
},
"commandName": "find"
"commandName": "find",
"databaseName": "command-monitoring-tests"
}
},
{
Expand Down Expand Up @@ -498,7 +504,8 @@
]
}
},
"commandName": "getMore"
"commandName": "getMore",
"databaseName": "command-monitoring-tests"
}
}
]
Expand Down Expand Up @@ -539,7 +546,8 @@
},
{
"commandFailedEvent": {
"commandName": "find"
"commandName": "find",
"databaseName": "command-monitoring-tests"
}
}
]
Expand Down
Loading