ΠΠΎΠ΄ΡΠ»Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ API-ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ° ΡΠΎΠ±ΡΡΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΠΌ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΈ Π²Π½ΡΡΡΠ΅Π½Π½ΡΡ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΎΡΠ½ΠΎΡΠΈΡΡΡ ΠΊ » БпСΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΈ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΡΠ΅ΡΠ²Π΅ΡΠΎΠ². ΠΡΠΎ ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ ΠΏΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅Ρ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ ΠΊΠΎΠΌΠ°Π½Π΄ ΡΠ΅ΡΠ΅Π· ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ MongoDB\Driver\Monitoring\CommandSubscriber.
ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ MongoDB\Driver\Monitoring\CommandSubscriber
ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΡΡΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°: commandStarted,
commandSucceeded ΠΈ commandFailed.
ΠΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· Π½ΠΈΡ
ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ event ΠΊΠ»Π°ΡΡΠ°,
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ Π½ΡΠΆΠ½ΠΎΠΌΡ ΡΠΎΠ±ΡΡΠΈΡ. Π ΠΏΡΠΈΠΌΠ΅ΡΡ, commandSucceeded
ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ $event ΠΊΠ»Π°ΡΡΠ°
MongoDB\Driver\Monitoring\CommandSucceededEvent.
Π ΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠΏΠΈΡΠΎΠΊ ΠΏΡΠΎΡΠΈΠ»ΠΈΡΠΎΠ²ΠΎΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ° ΠΈ ΡΡΠ΅Π΄Π½Π΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π·Π°Π½ΡΠ»ΠΈ Π·Π°ΠΏΡΠΎΡΡ.
ΠΠ°ΡΠ½ΡΠΌ Ρ ΡΠ°Π±Π»ΠΎΠ½Π° Π΄Π»Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ°:
<?php
class QueryTimeCollector implements \MongoDB\Driver\Monitoring\CommandSubscriber
{
public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event ): void {}
public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ): void {}
public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ): void {}
}
?>ΠΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ° ΡΠΎΠ·Π΄Π°Π»ΠΈ, ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°ΡΡ Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° ΠΌΠΎΠ΄ΡΠ»Ρ. ΠΠ»ΠΎΠ±Π°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ MongoDB\Driver\Monitoring\addSubscriber(), Π° Π΄Π»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΊΠ»Π°ΡΡΠ° Manager β ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ MongoDB\Driver\Manager::addSubscriber().
<?php
\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );
?>
Π’Π΅ΠΏΠ΅ΡΡ Π·Π°ΠΉΠΌΡΠΌΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΊΠ»Π°ΡΠ° ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ°.
ΠΠ»Ρ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΡ Π΄Π²ΡΡ
ΡΠΎΠ±ΡΡΠΈΠΉ, ΠΎΡΠ½ΠΎΡΡΡΠΈΡ
ΡΡ ΠΊ ΡΡΠΏΠ΅ΡΠ½ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π½ΠΎΠΉ
ΠΊΠΎΠΌΠ°Π½Π΄Ρ (commandStarted and commandSucceeded), ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΎΠ±ΡΡΠΈΡ
ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠΎΠ»Π΅ requestId.
ΠΠ»Ρ Π·Π°ΠΏΠΈΡΠΈ ΡΡΠ΅Π΄Π½Π΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π·Π°ΠΏΡΠΎΡΠ° ΠΌΡ Π½Π°ΡΠ½ΡΠΌ Ρ
ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ find Π² ΡΠΎΠ±ΡΡΠΈΠΈ commandStarted.
ΠΡ Π±ΡΠ΄Π΅ΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π² ΠΌΠ°ΡΡΠΈΠ² pendingCommands
Ρ ΠΈΠ½Π΄Π΅ΠΊΡΠΎΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ requestId ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ
Π·Π°ΠΏΡΠΎΡΡ.
ΠΠΎΠ³Π΄Π° ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ ΡΠΎΠ±ΡΡΠΈΠ΅ commandSucceeded Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ
requestId, ΠΌΡ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ (ΠΈΠ·
durationMicros) ΠΊ ΠΎΠ±ΡΠ΅ΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΈ ΡΠ²Π΅Π»ΠΈΡΠΈΠΌ ΡΡΡΡΡΠΈΠΊ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ.
ΠΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠΎΠ±ΡΡΠΈΠ΅ commandFailed, ΠΌΡ ΠΏΡΠΎΡΡΠΎ ΡΠ΄Π°Π»ΠΈΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΡΡ Π·Π°ΠΏΠΈΡΡ ΠΈΠ·
pendingCommands.
<?php
class QueryTimeCollector implements \MongoDB\Driver\Monitoring\CommandSubscriber
{
private $pendingCommands = [];
private $queryShapeStats = [];
/* Π‘ΠΎΠ·Π΄Π°ΡΡ ΡΠΎΡΠΌΡ Π·Π°ΠΏΡΠΎΡΠ° ΠΈΠ· Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° ΡΠΈΠ»ΡΡΡΠ°. Π£ΡΠΈΡΡΠ²Π°ΡΡΡΡ
* ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΠ»Ρ Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ. */
private function createQueryShape(array $filter)
{
return json_encode(array_keys($filter));
}
public function commandStarted(\MongoDB\Driver\Monitoring\CommandStartedEvent $event): void
{
if ('find' === $event->getCommandName()) {
$queryShape = $this->createQueryShape((array) $event->getCommand()->filter);
$this->pendingCommands[$event->getRequestId()] = $queryShape;
}
}
public function commandSucceeded(\MongoDB\Driver\Monitoring\CommandSucceededEvent $event): void
{
$requestId = $event->getRequestId();
if (array_key_exists($requestId, $this->pendingCommands)) {
$this->queryShapeStats[$this->pendingCommands[$requestId]]['count']++;
$this->queryShapeStats[$this->pendingCommands[$requestId]]['duration'] += $event->getDurationMicros();
unset($this->pendingCommands[$requestId]);
}
}
public function commandFailed(\MongoDB\Driver\Monitoring\CommandFailedEvent $event): void
{
if (array_key_exists($event->getRequestId(), $this->pendingCommands)) {
unset($this->pendingCommands[$event->getRequestId()]);
}
}
public function __destruct()
{
foreach ($this->queryShapeStats as $shape => $stats) {
echo "Shape: ", $shape, " (", $stats['count'], ")\n ",
$stats['duration'] / $stats['count'], "Β΅s\n\n";
}
}
}
$m = new \MongoDB\Driver\Manager('mongodb://localhost:27016');
/* ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΈΠΊΠ° */
\MongoDB\Driver\Monitoring\addSubscriber(new QueryTimeCollector());
/* ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΏΠ°ΡΠΊΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² */
$query = new \MongoDB\Driver\Query([
'region_slug' => 'scotland-highlands', 'age' => ['$gte' => 20]
]);
$cursor = $m->executeQuery('dramio.whisky', $query);
$query = new \MongoDB\Driver\Query([
'region_slug' => 'scotland-lowlands', 'age' => ['$gte' => 15]
]);
$cursor = $m->executeQuery('dramio.whisky', $query);
$query = new \MongoDB\Driver\Query(['region_slug' => 'scotland-lowlands']);
$cursor = $m->executeQuery('dramio.whisky', $query);
?>