La extensión contiene una API de observaciones de eventos, que permite a las aplicaciones monitorear las órdenes y las actividades internas relacionadas con la » Especificación de descubrimiento y monitoreo del servidor. Este tutorial demostrará el monitoreo de las órdenes utilizando la interfaz MongoDB\Driver\Monitoring\CommandSubscriber.
La interfaz
MongoDB\Driver\Monitoring\CommandSubscriber
define tres métodos: commandStarted,
commandSucceeded, y commandFailed.
Cada uno de estos tres métodos acepta un solo argumento event
de una clase específica para el evento respectivo. Por ejemplo, el argumento
$event de commandSucceeded
es un objeto MongoDB\Driver\Monitoring\CommandSucceededEvent.
En este tutorial, se implementará un observador que crea una lista de todos los perfiles de solicitud y el tiempo promedio que han tomado.
Se comienza con el marco del observador:
<?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
{
}
}
?>Una vez que un objeto observador es instanciado, debe ser registrado con el sistema de monitoreo de la extensión. Esto se hace llamando a MongoDB\Driver\Monitoring\addSubscriber() o MongoDB\Driver\Manager::addSubscriber() para registrar el observador globalmente o con un Manager específico, respectivamente.
<?php
\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );
?>
Con el objeto registrado, la única cosa que queda es implementar la lógica
en la clase observadora. Para correlacionar los dos eventos que componen una
orden ejecutada con éxito (commandStarted y commandSucceeded), cada
objeto de evento expone un campo requestId.
Para registrar el tiempo promedio por forma de solicitud, se comenzará verificando
una orden find en el evento commandStarted. Luego, se añadirá un elemento a la propiedad pendingCommands indexado por su
requestId y con su valor representando la forma de solicitud.
Si se recibe un evento commandSucceeded correspondiente con el mismo
requestId, se añade la duración del evento (desde
durationMicros) al tiempo total e incrementa el
contador de operaciones.
Si se encuentra un evento commandFailed correspondiente, simplemente se elimina
la entrada de la propiedad pendingCommands.
<?php
class QueryTimeCollector implements \MongoDB\Driver\Monitoring\CommandSubscriber
{
private $pendingCommands = [];
private $queryShapeStats = [];
/* Crear una forma de solicitud a partir del argumento de filtro. Por ahora, solo se consideran
* los campos de primer nivel */
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' );
/* Añadir el observador */
\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );
/* Realizar una serie de solicitudes */
$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 );
?>