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