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 );
?>