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

MongoDB\Driver\Monitoring\Subscriber

Interface

Basis-Interface für alle Ereignisabonnenten des MongoDB-Treibers, das als Marker-Interface für den Monitoring-Mechanismus dient.

seit PHP 1.3.0 Kategorie: db

Signatur

interface Subscriber

Beschreibung

Das Interface MongoDB\Driver\Monitoring\Subscriber ist das grundlegende Marker-Interface des MongoDB-PHP-Treibers für das Command-Monitoring-System. Es definiert selbst keine Methoden, sondern dient als gemeinsame Basis für spezialisierte Abonnenten-Interfaces wie CommandSubscriber, SDAMSubscriber oder ServerMonitoringSubscriber.

Um auf bestimmte Treiberereignisse (z. B. ausgeführte Befehle, Topologie-Änderungen oder Heartbeat-Ereignisse) reagieren zu können, muss eine Klasse das entsprechende spezialisierte Interface implementieren, welches seinerseits Subscriber erweitert. Anschließend wird die Abonnenten-Instanz über MongoDB\Driver\Monitoring\addSubscriber() global oder über MongoDB\Driver\Manager::addSubscriber() pro Verbindung registriert.

Typische Anwendungsfälle sind das Loggen von Datenbankabfragen, das Messen von Ausführungszeiten, das Debugging von Treiberkommunikation oder das Einbinden in APM-Tools (Application Performance Monitoring). Da das Interface selbst keine Methoden vorschreibt, kann eine Klasse mehrere spezialisierte Subscriber-Interfaces gleichzeitig implementieren und so auf verschiedene Ereignistypen reagieren.

Direkte Instanzen von Subscriber ohne eines der spezialisierten Interfaces können zwar registriert werden, empfangen jedoch keine Ereignisse – erst durch die Implementierung der spezifischen Interfaces werden die entsprechenden Callback-Methoden aufgerufen.

Beispiele

Einfacher Command-Subscriber zur Abfrageprotokollierung

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

class QueryLogger implements CommandSubscriber
{
    public function commandStarted(CommandStartedEvent $event): void
    {
        echo sprintf(
            "[START] Befehl '%s' auf DB '%s' (RequestId: %d)\n",
            $event->getCommandName(),
            $event->getDatabaseName(),
            $event->getRequestId()
        );
    }

    public function commandSucceeded(CommandSucceededEvent $event): void
    {
        echo sprintf(
            "[OK]    Befehl '%s' in %.3f ms abgeschlossen\n",
            $event->getCommandName(),
            $event->getDurationMicros() / 1000
        );
    }

    public function commandFailed(CommandFailedEvent $event): void
    {
        echo sprintf(
            "[FAIL]  Befehl '%s' fehlgeschlagen: %s\n",
            $event->getCommandName(),
            $event->getError()->getMessage()
        );
    }
}

// Subscriber global registrieren
\MongoDB\Driver\Monitoring\addSubscriber(new QueryLogger());

$manager = new \MongoDB\Driver\Manager('mongodb://127.0.0.1/');
$query   = new \MongoDB\Driver\Query(['status' => 'aktiv']);
$cursor  = $manager->executeQuery('mydb.users', $query);
[START] Befehl 'find' auf DB 'mydb' (RequestId: 1) [OK] Befehl 'find' in 2.451 ms abgeschlossen

Mehrere Subscriber-Interfaces kombinieren

<?php
use MongoDB\Driver\Monitoring\CommandSubscriber;
use MongoDB\Driver\Monitoring\SDAMSubscriber;
use MongoDB\Driver\Monitoring\CommandStartedEvent;
use MongoDB\Driver\Monitoring\CommandSucceededEvent;
use MongoDB\Driver\Monitoring\CommandFailedEvent;
use MongoDB\Driver\Monitoring\ServerOpeningEvent;
use MongoDB\Driver\Monitoring\ServerClosedEvent;
use MongoDB\Driver\Monitoring\ServerDescriptionChangedEvent;
use MongoDB\Driver\Monitoring\TopologyOpeningEvent;
use MongoDB\Driver\Monitoring\TopologyClosedEvent;
use MongoDB\Driver\Monitoring\TopologyDescriptionChangedEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent;

/**
 * Diese Klasse implementiert sowohl CommandSubscriber als auch SDAMSubscriber
 * und ist damit ein gültiger Subscriber (erbt beide "extends Subscriber"-Ketten).
 */
class UniversalMonitor implements CommandSubscriber, SDAMSubscriber
{
    // --- CommandSubscriber ---
    public function commandStarted(CommandStartedEvent $event): void
    {
        echo "CMD gestartet: " . $event->getCommandName() . "\n";
    }

    public function commandSucceeded(CommandSucceededEvent $event): void {}
    public function commandFailed(CommandFailedEvent $event): void {}

    // --- SDAMSubscriber ---
    public function serverOpening(ServerOpeningEvent $event): void
    {
        echo "Server verbunden: " . $event->getHost() . ":" . $event->getPort() . "\n";
    }

    public function serverClosed(ServerClosedEvent $event): void {}
    public function serverDescriptionChanged(ServerDescriptionChangedEvent $event): void {}
    public function topologyOpening(TopologyOpeningEvent $event): void {}
    public function topologyClosed(TopologyClosedEvent $event): void {}
    public function topologyDescriptionChanged(TopologyDescriptionChangedEvent $event): void {}
    public function serverHeartbeatStarted(ServerHeartbeatStartedEvent $event): void {}
    public function serverHeartbeatSucceeded(ServerHeartbeatSucceededEvent $event): void {}
    public function serverHeartbeatFailed(ServerHeartbeatFailedEvent $event): void {}
}

$monitor = new UniversalMonitor();
\MongoDB\Driver\Monitoring\addSubscriber($monitor);

$manager = new \MongoDB\Driver\Manager('mongodb://127.0.0.1/');
echo "Monitor registriert.\n";
Monitor registriert. Server verbunden: 127.0.0.1:27017 CMD gestartet: find

// Wichtig · Fallstricke

Marker-Interface ohne eigene Methoden: Subscriber selbst schreibt keine Methoden vor. Wer ausschließlich dieses Interface implementiert (ohne ein spezialisiertes Sub-Interface), kann zwar registriert werden, erhält aber keinerlei Ereignisbenachrichtigungen.

Gültigkeitsbereich der Registrierung: Mit MongoDB\Driver\Monitoring\addSubscriber() wird der Abonnent global für alle Manager-Instanzen registriert. Für eine isolierte Überwachung einzelner Verbindungen sollte stattdessen MongoDB\Driver\Manager::addSubscriber() verwendet werden, um unerwünschte Seiteneffekte in größeren Anwendungen zu vermeiden.

Performance-Hinweis: Jeder registrierte Subscriber erhält synchron Ereignisse und blockiert dabei den Treiber. Aufwändige Operationen (z. B. Netzwerkaufrufe, synchrones Schreiben in Datenbanken) innerhalb der Callback-Methoden können die Latenz von MongoDB-Operationen spürbar erhöhen. Für Produktivumgebungen empfiehlt sich asynchrones Puffern der Ereignisse.