L'extension contient une API d'observations événements, qui permet aux applications de surveiller les commandes et les activités internes liées à la » Spécification de découverte et de surveillance du serveur. Ce tutoriel démontrera la surveillance des commandes en utilisant l'interface MongoDB\Driver\Monitoring\CommandSubscriber.
L'interface
MongoDB\Driver\Monitoring\CommandSubscriber
définit trois méthodes: commandStarted,
commandSucceeded, et commandFailed.
Chacune de ces trois méthodes accepte un seul argument event
d'une classe spécifique pour l'événement respectif. Par exemple, l'argument
$event de commandSucceeded
est un objet MongoDB\Driver\Monitoring\CommandSucceededEvent.
Dans ce tutoriel, nous allons implĂ©menter un observateur qui crĂ©e une liste de tous les profils de requĂȘte et le temps moyen qu'ils ont pris.
Nous commençons par le cadre de notre observateur:
<?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
{
}
}
?>Une fois qu'un objet observateur est instanciĂ©, il doit ĂȘtre enregistrĂ© avec le systĂšme de surveillance de l'extension. Cela se fait en appelant MongoDB\Driver\Monitoring\addSubscriber() ou MongoDB\Driver\Manager::addSubscriber() pour enregistrer l'observateur globalement ou avec un Manager spĂ©cifique, respectivement.
<?php
\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );
?>
Avec l'objet enregistré, la seule chose qui reste est d'implémenter la logique
dans la classe observatrice. Pour corréler les deux événements qui composent une
commande exécutée avec succÚs (commandStarted et commandSucceeded), chaque
objet d'événement expose un champ requestId.
Pour enregistrer le temps moyen par forme de requĂȘte, nous allons commencer par vĂ©rifier
une commande find dans l'événement commandStarted. Nous allons ensuite
ajouter un élément à la propriété pendingCommands indexé par son
requestId et avec sa valeur reprĂ©sentant la forme de requĂȘte.
Si nous recevons un Ă©vĂ©nement commandSucceeded correspondant avec le mĂȘme
requestId, nous ajoutons la durée de l'événement (depuis
durationMicros) au temps total et incrémentons le
compteur d'opérations.
Si un événement commandFailed correspondant est rencontré, nous supprimons
simplement l'entrée de la propriété pendingCommands.
<?php
class QueryTimeCollector implements \MongoDB\Driver\Monitoring\CommandSubscriber
{
private $pendingCommands = [];
private $queryShapeStats = [];
/* CrĂ©er une forme de requĂȘte Ă partir de l'argument de filtre. Pour l'instant, il ne prend en compte que
* les champs de premier niveau */
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' );
/* Ajouter l'observateur */
\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );
/* Faire une sĂ©rie de requĂȘtes */
$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 );
?>