Skip to content

Query Logging

Wes King edited this page Oct 7, 2016 · 18 revisions

Introduction

As of version 0.3.0, CakeMonga now has query logging support. To define logging callbacks, first create a class that extends the CakeMonga\Logger\MongoLogger class:

namespace App\Logger;
use CakeMonga\Logger\MongoLogger;

class CustomMongoLogger extends MongoLogger
{

}

The MongoLogger has five callback functions that can be overridden with custom behaviors to define how your logger works:

class MongoLogger
{
    public function onQuery(array $server, $arguments, array $query_options);
    public function onInsert(array $server, array $document, array $write_options, array $protocol_options);
    public function onDelete(array $server, array $write_options, array $delete_options, array $protocol_options);
    public function onUpdate(array $server, array $write_options, array $update_options, array $protocol_options);
    public function onBatchInsert(array $server, array $write_options, array $batch, array $protocol_options);
}

There are a few different ways to instantiate your logger. If using the ConnectionManager, you can define the class name of your logger attached to the 'logger' key inside of the connection's Datasource configuration. This will cause all connections created through ConnectionManager::get() to be built with that logger.

// In project_root/config/app.php: 
$config = [
    'Datasources' => [

        'default' => [
            // ... Default SQL Datasource
        ],

        'mongo_db' => [
            'className' => 'CakeMonga\Database\MongoConnection',
            'logger' => 'App\Logger\CustomMongoLogger'
        ]
    ]
];

// In your application:
$connection = ConnectionManager::get('mongo_db'); // Connection already has CustomMongoLogger!

Alternatively, you can set a custom logger class on the $connection class at runtime, but this must be BEFORE the connect() method is called, as the logger is registered with the stream context on connection.

$mongodb = ConnectionManager::get('mongo_db');
$secondary_logger = new SecondaryMongoLogger();
$mongodb->logger($secondary_logger);
$mongodb->logQueries(true);
$connection = $mongodb->connect();

Callback Documentation

The MongoLogger class callbacks map to an array of callback functions defined by the official package specification for MongoDB. Each of these callbacks takes a set of arguments. To view the documentation for the arguments in each callback, consult the table below. Note that there is no official documentation page for the onQuery() callback, and that the array designation for onWriteBatch() is incorrectly defined in the official PHP spec as log_writebatch(). Instead, it should be log_batch_insert().

MongoLogger Callback PHP Context Callback Official PHP Documentation
onQuery() log_query() Documentation Unavailable
onInsert() log_cmd_insert() Documentation
onDelete() log_cmd_delete() Documentation
onUpdate() log_cmd_update() Documentation
onBatchInsert() log_batchinsert() Documentation
onReply() Not supported log_reply() Documentation
onGetMore() Not supported log_getmore() Documentation
onKillCursor() Not supported log_killcursor() Documentation

Extended support for onReply, onGetMore and onKillCursor

The logging callbacks for log_getmore, log_reply, and log_killcursor are not directly supported by this plugin, due to patchy support between Pecl Mongo versions, but it's extremely easy to add support for these callbacks. You will need to extend the MongoLogger class and override the getContext() method to include these callbacks in your stream context:

class ExtendedLogger extends MongoLogger
{
    public function onGetMore(array $server, array $info) {};
    public function onKillCursor(array $server, array $info) {};
    public function onReply(array $server, array $message_headers, array $operation_headers) {};

    public function getContext()
    {
        $context = [
            'log_cmd_insert'    => [$this, 'onInsert'],
            'log_cmd_delete'    => [$this, 'onDelete'],
            'log_cmd_update'    => [$this, 'onUpdate'],
            'log_insert'        => [$this, 'onInsert'],
            'log_delete'        => [$this, 'onDelete'],
            'log_update'        => [$this, 'onUpdate'],
            'log_batchinsert'   => [$this, 'onBatchInsert'],
            'log_write_batch'   => [$this, 'onBatchInsert'],
            'log_query'         => [$this, 'onQuery'],
            'log_getmore'       => [$this, 'onGetMore'],
            'log_killcursor'    => [$this, 'onKillCursor'],
            'log_reply'         => [$this, 'onReply']
        ];
        return $context;
    }
}

This will allow you to receive logging for these callbacks as well.

Clone this wiki locally