Start · Sprachen · PHP · Referenz · MongoDB\Driver\Monitoring\CommandSubscriber

MongoDB\Driver\Monitoring\CommandSubscriber

Interface

Interface für Klassen, die MongoDB-Befehlsereignisse (Start, Erfolg, Fehler) abonnieren und überwachen möchten.

seit PHP 1.3.0 Kategorie: db

Signatur

interface CommandSubscriber extends MongoDB\Driver\Monitoring\Subscriber

Beschreibung

Das Interface MongoDB\Driver\Monitoring\CommandSubscriber gehört zur MongoDB-Driver-Monitoring-API (SDAM/Command Monitoring). Es ermöglicht Entwicklern, eigene Klassen zu erstellen, die bei jeder Ausführung eines MongoDB-Befehls (z. B. find, insert, aggregate) automatisch benachrichtigt werden.

Implementierende Klassen müssen drei Methoden bereitstellen: commandStarted(), commandSucceeded() und commandFailed(). Diese Methoden erhalten entsprechende Ereignis-Objekte (CommandStartedEvent, CommandSucceededEvent, CommandFailedEvent), die Details wie Befehlsname, Datenbankname, Dauer und ggf. Fehlerinformationen enthalten.

Typische Einsatzgebiete sind Performance-Monitoring (Query-Laufzeiten messen), Logging aller Datenbankoperationen, Debugging von MongoDB-Abfragen sowie die Integration mit APM-Systemen (Application Performance Monitoring) wie Datadog oder New Relic.

Um einen Subscriber zu aktivieren, muss er über MongoDB\Driver\Monitoring\addSubscriber() (global) oder $manager->addSubscriber() (manager-spezifisch) registriert werden.

Beispiele

Query-Logger mit CommandSubscriber

<?php
use MongoDB\Driver\Monitoring\CommandSubscriber;
use MongoDB\Driver\Monitoring\CommandStartedEvent;
use MongoDB\Driver\Monitoring\CommandSucceededEvent;
use MongoDB\Driver\Monitoring\CommandFailedEvent;
use MongoDB\Driver\Manager;

class QueryLogger implements CommandSubscriber
{
    private array $log = [];

    public function commandStarted(CommandStartedEvent $event): void
    {
        $this->log[$event->getRequestId()] = [
            'command'  => $event->getCommandName(),
            'database' => $event->getDatabaseName(),
            'started'  => microtime(true),
        ];
    }

    public function commandSucceeded(CommandSucceededEvent $event): void
    {
        $id = $event->getRequestId();
        $duration = microtime(true) - ($this->log[$id]['started'] ?? microtime(true));
        echo sprintf(
            "[OK] %s.%s — %.4f ms\n",
            $this->log[$id]['database'] ?? '?',
            $this->log[$id]['command']  ?? '?',
            $duration * 1000
        );
        unset($this->log[$id]);
    }

    public function commandFailed(CommandFailedEvent $event): void
    {
        $id = $event->getRequestId();
        echo sprintf(
            "[ERR] %s — %s\n",
            $this->log[$id]['command'] ?? '?',
            $event->getError()->getMessage()
        );
        unset($this->log[$id]);
    }
}

$manager = new Manager('mongodb://localhost:27017');
$logger  = new QueryLogger();
$manager->addSubscriber($logger);

// Ab hier werden alle über $manager ausgeführten Befehle geloggt.
// Beispiel: $manager->executeCommand(...);
[OK] mydb.find — 1.2340 ms

Globale Registrierung für alle Manager-Instanzen

<?php
use MongoDB\Driver\Monitoring\CommandSubscriber;
use MongoDB\Driver\Monitoring\CommandStartedEvent;
use MongoDB\Driver\Monitoring\CommandSucceededEvent;
use MongoDB\Driver\Monitoring\CommandFailedEvent;

class SimpleCommandLogger implements CommandSubscriber
{
    public function commandStarted(CommandStartedEvent $event): void
    {
        echo "START: " . $event->getCommandName() . "\n";
    }

    public function commandSucceeded(CommandSucceededEvent $event): void
    {
        echo "OK:    " . $event->getCommandName() . "\n";
    }

    public function commandFailed(CommandFailedEvent $event): void
    {
        echo "FAIL:  " . $event->getCommandName() . " — " . $event->getError()->getMessage() . "\n";
    }
}

// Globale Registrierung: gilt für ALLE nachfolgend erstellten Manager-Instanzen
MongoDB\Driver\Monitoring\addSubscriber(new SimpleCommandLogger());

$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
// Alle Befehle über $manager lösen nun den SimpleCommandLogger aus.
START: find OK: find

// Wichtig · Fallstricke

Sicherheitshinweis: Die Ereignis-Objekte können vollständige Befehlsdokumente enthalten, die sensible Daten (z. B. Passwörter bei authenticate-Befehlen) beinhalten können. MongoDB maskiert bekannte sensible Felder automatisch, dennoch sollten Log-Ausgaben nicht ungesichert persistiert oder übertragen werden.

Performance: Da jede Datenbankoperation alle registrierten Subscriber synchron aufruft, können aufwändige Operationen in den Methoden die Gesamtperformance der Anwendung spürbar beeinflussen. Subscriber-Implementierungen sollten daher möglichst schnell sein und teure Operationen (z. B. I/O) asynchron auslagern.

Das Interface erweitert MongoDB\Driver\Monitoring\Subscriber, das als Marker-Interface dient. Subscriber können über MongoDB\Driver\Monitoring\removeSubscriber() bzw. $manager->removeSubscriber() wieder deregistriert werden.