Writers

A writer is an object that inherits from Zend\Log\Writer\AbstractWriter. A writer's responsibility is to record log data to a storage backend.

Writing to Streams

Zend\Log\Writer\Stream sends log data to a PHP stream.

To write log data to the PHP output buffer, use the php://output stream. Alternately, you can send log data directly to a stream like STDERR (php://stderr).

$writer = new Zend\Log\Writer\Stream('php://output');
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

To write data to a file, use one of the filesystem streams:

$writer = new Zend\Log\Writer\Stream('/path/to/logfile');
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

By default, the stream opens in the append access mode ("a"). To open it with a different access mode, the Zend\Log\Writer\Stream constructor accepts an optional second parameter for the stream mode.

The constructor of Zend\Log\Writer\Stream also accepts an existing stream resource:

$stream = @fopen('/path/to/logfile', 'a', false);
if (! $stream) {
    throw new Exception('Failed to open stream');
}

$writer = new Zend\Log\Writer\Stream($stream);
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

You cannot specify the stream access mode for existing stream resources. Doing so causes a Zend\Log\Exception to be thrown.

You can use an array of options in place of the stream argument when constructing a Stream instance; when doing so, the stream key is required:

$writer = new Zend\Log\Writer\Stream([
    'stream' => 'php://output',
]);
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

The following table details all allowed constructor arguments and their corresponding configuration options.

Constructor Argument Option Name Default Description
$streamOrUrl stream None; required Stream resource or URL to open and log to
$mode mode "a" Stream access mode to use when opening a stream URL
$logSeparator log_separator PHP_EOL Separator string to use between entries
$filePermissions chmod null Permissions mode to use for stream resource; defaults to existing file/stream permissions

Writing to Databases

Zend\Log\Writer\Db writes log information to a database table using Zend\Db\Adapter\Adapter. The constructor of Zend\Log\Writer\Db receives a Zend\Db\Adapter\Adapter instance, a table name, an optional mapping of event data to database columns, and an optional string contains the character separator for the log array:

$dbconfig = [
    // Sqlite Configuration
    'driver' => 'Pdo',
    'dsn' => 'sqlite:' . __DIR__ . '/tmp/sqlite.db',
];
$db = new Zend\Db\Adapter\Adapter($dbconfig);

$writer = new Zend\Log\Writer\Db($db, 'log_table_name');
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

The example above writes a single row of log data to the database table named log_table_name table. The database columns will be created according to the event array generated by the Zend\Log\Logger instance.

If we specify the mapping of the events with the database columns, the log will store only to the selected fields in the database:

$dbconfig = [
    // Sqlite Configuration
    'driver' => 'Pdo',
    'dsn' => 'sqlite:' . __DIR__ . '/tmp/sqlite.db',
];
$db = new Zend\Db\Adapter\Adapter($dbconfig);

$mapping = [
    'timestamp' => 'date',
    'priority'  => 'type',
    'message'   => 'event',
];
$writer = new Zend\Log\Writer\Db($db, 'log_table_name', $mapping);
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

In this example, the writer stores only the log timestamp, priority, and message, in the database fields date, type, and event, respectively.

Zend\Log\Writer\Db has a fourth optional parameter in the constructor. This parameter is the character separator for array fields in the log event. For instance, if we have a log event that contains the field extra, and that field is an array, its elements will be translated as 'extra-field', where '-' is the character separator (default), and 'field' is the subname of the specific field found in the extra array.

Writing to FirePHP

Zend\Log\Writer\FirePHP writes log information to the FirePHP Firefox extension. In order to use it, you must install the FirePHPCore server library and the FirePHP browser extension.

To install the FirePHPCore library you can use Composer:

$ composer require firephp/firephp-core

Writing to ChromePHP

Zend\Log\Writer\ChromePHP sends log data to the ChromePHP Chrome extension.

To use the ChromePHP writer, you will also need to include the ChromePHP Library library in your application. Use Composer to do this:

$ composer require ccampbell/chromephp

Writing to Mail

Zend\Log\Writer\Mail takes a configuration array or Zend\Mail\Message. Basic usage looks like

$message = new \Zend\Mail\Message();
$message->setTo('email@example.com');

$writer = new \Zend\Log\Writer\Mail($message);
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to mail message
$logger->info('Informational message');

An email of the logged information will be sent via sendmail by default. You may also provide a Zend\Mail\Transport during construction. For configuration options checkout the Zend\Mail\Transport documentation.

$writer = new Zend\Log\Writer\Mail($mail, $transport);

Zend\Log\Writer\mail may also be constructed with a configuration array. The configuration array accepts the following keys:

[
    'subject_prepend_text' => '',
    'transport' => $transport
    'mail' => $mail,
    'filters' => [],
    'formatter' => []
]

And expects the following data:

Array Index Accepted Values Description
subject_prepend_text string Mail message
transport Transport\TransportInterface Transport method
mail Zend\Mail\Message mail message
mail array Zend\Mail\Message factory array
filters array, int, string, Zend\Log\Filter\FilterInterface Log filter(s)
formatter array, string, Zend\Log\Formatter\FormatterInterface Log formatter(s)

Basic usage of the configuration array looks like:

$transport = new \Zend\Mail\Transport\Smtp();
// TODO configure the SMTP transport

$message = new \Zend\Mail\Message();
// TODO configure the Mail message

$writer = new \Zend\Log\Writer\Mail([
    'subject_prepend_text' => 'Start of the subject',
    'transport' => $transport,
    'mail' => $mail,
    'filters' => [],
    'formatter' => []
]);

$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to mail message
$logger->info('Informational message');

To use the Zend\Mail\Message factory array construction will look like:

$transport = new \Zend\Mail\Transport\Smtp();
// TODO configure the SMTP transport

$writer = new \Zend\Log\Writer\Mail([
    'subject_prepend_text' => 'Start of the subject',
    'transport' => $transport,
    'mail' => [
        'to' => 'email@example.com'
    ],
    'filters' => [],
    'formatter' => []
]);

$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to mail message
$logger->info('Informational message');

Writing to MongoDB

In this example Zend\Log\Writer\MongoDB uses an array for construction. Available keys include:

[
    'save_options' => [],
    'collection' => '',
    'database' => '',
    'mongo' => $mongo,
    'filters' => [],
    'formatter' => []
]

collection, database, and mongo are required. Each key accepts:

Array Index Accepted Values Description
save_options array MongoDB driver options
collection string collection name
database string database name
mongo Mongo or MongoClient MongoDB connection object
filters array, int, string, Zend\Log\Filter\FilterInterface Log filter(s)
formatter array, string, Zend\Log\Formatter\FormatterInterface Log formatter(s)

And Zend\Log\Writer\MongoDB is used like this:

$mongo = new MongoClient();

$writer = new \Zend\Log\Writer\MongoDB([
    'save_options' => [], // MongoDB Driver Options
    'collection' => 'collectionName',
    'database' => 'databaseName',
    'mongo' => $mongo,
    'filters' => [],
    'formatter' => []
]);

$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to Mongo DB
$logger->info('Informational message');

It may also be constructed by passing the arguments directly

$mongo = new MongoClient();
$database = 'databaseName';
$collection = 'collectionName';
$saveOptions = [];

$writer = new \Zend\Log\Writer\MongoDB($mongo, $database, $collection, $saveOptions);
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to Mongo DB
$logger->info('Informational message');

Writing to Syslog

Zend\Log\Writer\Syslog is a writer generates system log messages from the data it receives.

$writer = new \Zend\Log\Writer\Syslog();
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to system log
$logger->info('Informational message');

The application name and syslog facility may be set

Array Index Accepted Values Description
application string application name
facility string syslog facility (list of facilities)[http://php.net/openlog]
filters array, int, string, Zend\Log\Filter\FilterInterface Log filter(s)
formatter array, string, Zend\Log\Formatter\FormatterInterface Log formatter(s)
$writer = new \Zend\Log\Writer\Syslog([
    'application' => '',
    'facility' => '',
    'filters' => [],
    'formatter' => []
]);

$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

$logger->info('Informational message');

Writing to Zend Monitor

Zend\Log\Writer\ZendMonitor writes log data to the Zend Monitor on a Zend Server. If the web server is not a Zend Server or Zend Monitor is not enabled it will fail silently.

$writer = new \Zend\Log\Writer\ZendMonitor();
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to Zend Monitor
$logger->info('Informational message');

Zend\Log\Writer\AbstractWriter options are available.

Array Index Accepted Values Description
filters array, int, string, Zend\Log\Filter\FilterInterface Log filter(s)
formatter array, string, Zend\Log\Formatter\FormatterInterface Log formatter(s)
$writer = new \Zend\Log\Writer\ZendMonitor([
    'filters' => [],
    'formatter' => []
]);

$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);

// goes to Zend Monitor
$logger->info('Informational message');

Stubbing Out the Writer

Zend\Log\Writer\Noop is a stub that does not write log data to anything; it is useful for disabling logging or stubbing out logging during tests:

$writer = new Zend\Log\Writer\Noop;
$logger = new Zend\Log\Logger();
$logger->addWriter($writer);

// goes nowhere
$logger->info('Informational message');

Migration from 2.0-2.3 to 2.4+

Version 2.4 adds support for PHP 7. In PHP 7, null is a reserved keyword, which required renaming the Null log writer. If you were using the Null writer directly previously, you will now receive an E_USER_DEPRECATED notice on instantiation. Please update your code to refer to the Noop class instead.

Users pulling their Null writer instance from the writer plugin manager receive a Noop instance instead starting in 2.4.0.

Testing with the Mock Writer

Zend\Log\Writer\Mock is a simple writer that records the raw data it receives in an array that it exposes as a public property.

$mock = new Zend\Log\Writer\Mock;
$logger = new Zend\Log\Logger();
$logger->addWriter($mock);

$logger->info('Informational message');

var_dump($mock->events[0]);

// Array
// (
//    [timestamp] => 2007-04-06T07:16:37-07:00
//    [message] => Informational message
//    [priority] => 6
//    [priorityName] => INFO
// )

To clear the events logged by the mock, reset the $events property:

$mock->events = [];

Compositing Writers

There is no composite writer object. However, a Logger instance can write to any number of writers, effectively making it a composite logger.

To utilize this functionality, add writers via the Logger::addWriter() method:

$writer1 = new Zend\Log\Writer\Stream('/path/to/first/logfile');
$writer2 = new Zend\Log\Writer\Stream('/path/to/second/logfile');

$logger = new Zend\Log\Logger();
$logger->addWriter($writer1);
$logger->addWriter($writer2);

// goes to both writers
$logger->info('Informational message');

You can also specify the priority number for each writer to change the order of writing. The priority number is an integer number passed as second parameter in the addWriter() method. Internally, SplPriorityQueue is used to manage writers, which means that: