Previous Next

Writers

A Writer is an object that inherits from Zend_Log_Writer_Abstract. 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 URL php://output. Alternatively, 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($writer);

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

To write data to a file, use one of the » Filesystem URLs:

$writer = new Zend_Log_Writer_Stream('/path/to/logfile');
$logger = new Zend_Log($writer);

$logger->info('Informational message');
By default, the stream opens in the append mode ("a"). To open it with a different mode, the Zend_Log_Writer_Stream constructor accepts an optional second parameter for the 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($writer);

$logger->info('Informational message');
You cannot specify the mode for existing stream resources. Doing so causes a Zend_Log_Exception to be thrown.

Writing to Databases

Zend_Log_Writer_Db writes log information to a database table using Zend_Db. The constructor of Zend_Log_Writer_Db receives a Zend_Db_Adapter instance, a table name, and a mapping of database columns to event data items:

$params = array ('host'     => '127.0.0.1',
                 'username' => 'malory',
                 'password' => '******',
                 'dbname'   => 'camelot');
$db = Zend_Db::factory('PDO_MYSQL', $params);

$columnMapping = array('lvl' => 'priority', 'msg' => 'message');
$writer = new Zend_Log_Writer_Db($db, 'log_table_name', $columnMapping);

$logger = new Zend_Log($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 column named lvl receives the priority number and the column named msg receives the log message.

Writing to Firebug

Zend_Log_Writer_Firebug sends log data to the » Firebug » Console.

zend.wildfire.firebug.console.png

All data is sent via the Zend_Wildfire_Channel_HttpHeaders component which uses HTTP headers to ensure the page content is not disturbed. Debugging AJAX requests that require clean JSON and XML responses is possible with this approach.

Requirements:

Example #1 Logging with Zend_Controller_Front

// Place this in your bootstrap file before dispatching your front controller
$writer = new Zend_Log_Writer_Firebug();
$logger = new Zend_Log($writer);

// Use this in your model, view and controller files
$logger->log('This is a log message!', Zend_Log::INFO);

Example #2 Logging without Zend_Controller_Front

$writer = new Zend_Log_Writer_Firebug();
$logger = new Zend_Log($writer);

$request = new Zend_Controller_Request_Http();
$response = new Zend_Controller_Response_Http();
$channel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
$channel->setRequest($request);
$channel->setResponse($response);

// Start output buffering
ob_start();

// Now you can make calls to the logger

$logger->log('This is a log message!', Zend_Log::INFO);

// Flush log data to browser
$channel->flush();
$response->sendHeaders();

Setting Styles for Priorities

Built-in and user-defined priorities can be styled with the setPriorityStyle() method.

$logger->addPriority('FOO', 8);
$writer->setPriorityStyle(8, 'TRACE');
$logger->foo('Foo Message');

The default style for user-defined priorities can be set with the setDefaultPriorityStyle() method.

$writer->setDefaultPriorityStyle('TRACE');

The supported styles are as follows:

Firebug Logging Styles
Style Description
LOG Displays a plain log message
INFO Displays an info log message
WARN Displays a warning log message
ERROR Displays an error log message that increments Firebug's error count
TRACE Displays a log message with an expandable stack trace
EXCEPTION Displays an error long message with an expandable stack trace
TABLE Displays a log message with an expandable table

Preparing data for Logging

While any PHP variable can be logged with the built-in priorities, some special formatting is required if using some of the more specialized log styles.

The LOG, INFO, WARN, ERROR and TRACE styles require no special formatting.

Exception Logging

To log a Zend_Exception simply pass the exception object to the logger. It does not matter which priority or style you have set as the exception is automatically recognized.

$exception = new Zend_Exception('Test exception');
$logger->err($exception);

Table Logging

You can also log data and format it in a table style. Columns are automatically recognized and the first row of data automatically becomes the header.

$writer->setPriorityStyle(8, 'TABLE');
$logger->addPriority('TABLE', 8);

$table = array('Summary line for the table',
             array(
                 array('Column 1', 'Column 2'),
                 array('Row 1 c 1',' Row 1 c 2'),
                 array('Row 2 c 1',' Row 2 c 2')
             )
            );
$logger->table($table);

Writing to Email

Zend_Log_Writer_Mail writes log entries in an email message by using Zend_Mail. The Zend_Log_Writer_Mail constructor takes a Zend_Mail object, and an optional Zend_Layout object.

The primary use case for Zend_Log_Writer_Mail is notifying developers, systems administrators, or any concerned parties of errors that might be occurring with PHP-based scripts. Zend_Log_Writer_Mail was born out of the idea that if something is broken, a human being needs to be alerted of it immediately so they can take corrective action.

Basic usage is outlined below:

$mail = new Zend_Mail();
$mail->setFrom('errors@example.org')
     ->addTo('project_developers@example.org');

$writer = new Zend_Log_Writer_Mail($mail);

// Set subject text for use; summary of number of errors is appended to the
// subject line before sending the message.
$writer->setSubjectPrependText('Errors with script foo.php');

// Only email warning level entries and higher.
$writer->addFilter(Zend_Log::WARN);

$log = new Zend_Log();
$log->addWriter($writer);

// Something bad happened!
$log->error('unable to connect to database');

// On writer shutdown, Zend_Mail::send() is triggered to send an email with
// all log entries at or above the Zend_Log filter level.

Zend_Log_Writer_Mail will render the email body as plain text by default.

One email is sent containing all log entries at or above the filter level. For example, if warning-level entries an up are to be emailed, and two warnings and five errors occur, the resulting email will contain a total of seven log entries.

Zend_Layout Usage

A Zend_Layout instance may be used to generate the HTML portion of a multipart email. If a Zend_Layout instance is in use, Zend_Log_Writer_Mail assumes that it is being used to render HTML and sets the body HTML for the message as the Zend_Layout-rendered value.

When using Zend_Log_Writer_Mail with a Zend_Layout instance, you have the option to set a custom formatter by using the setLayoutFormatter() method. If no Zend_Layout-specific entry formatter was specified, the formatter currently in use will be used. Full usage of Zend_Layout with a custom formatter is outlined below.

$mail = new Zend_Mail();
$mail->setFrom('errors@example.org')
     ->addTo('project_developers@example.org');
// Note that a subject line is not being set on the Zend_Mail instance!

// Use a simple Zend_Layout instance with its defaults.
$layout = new Zend_Layout();

// Create a formatter that wraps the entry in a listitem tag.
$layoutFormatter = new Zend_Log_Formatter_Simple(
    '
  • ' . Zend_Log_Formatter_Simple::DEFAULT_FORMAT . '
  • ' ); $writer = new Zend_Log_Writer_Mail($mail, $layout); // Apply the formatter for entries as rendered with Zend_Layout. $writer->setLayoutFormatter($layoutFormatter); $writer->setSubjectPrependText('Errors with script foo.php'); $writer->addFilter(Zend_Log::WARN); $log = new Zend_Log(); $log->addWriter($writer); // Something bad happened! $log->error('unable to connect to database'); // On writer shutdown, Zend_Mail::send() is triggered to send an email with // all log entries at or above the Zend_Log filter level. The email will // contain both plain text and HTML parts.

    Subject Line Error Level Summary

    The setSubjectPrependText() method may be used in place of Zend_Mail::setSubject() to have the email subject line dynamically written before the email is sent. For example, if the subject prepend text reads "Errors from script", the subject of an email generated by Zend_Log_Writer_Mail with two warnings and five errors would be "Errors from script (warn = 2; error = 5)". If subject prepend text is not in use via Zend_Log_Writer_Mail, the Zend_Mail subject line, if any, is used.

    Caveats

    Sending log entries via email can be dangerous. If error conditions are being improperly handled by your script, or if you're misusing the error levels, you might find yourself in a situation where you are sending hundreds or thousands of emails to the recipients depending on the frequency of your errors.

    At this time, Zend_Log_Writer_Mail does not provide any mechanism for throttling or otherwise batching up the messages. Such functionallity should be implemented by the consumer if necessary.

    Again, Zend_Log_Writer_Mail's primary goal is to proactively notify a human being of error conditions. If those errors are being handled in a timely fashion, and safeguards are being put in place to prevent those circumstances in the future, then email-based notification of errors can be a valuable tool.

    Writing to the System Log

    Zend_Log_Writer_Syslog writes log entries to the system log (syslog). Internally, it proxies to PHP's openlog(), closelog(), and syslog() functions.

    One useful case for Zend_Log_Writer_Syslog is for aggregating logs from clustered machines via the system log functionality. Many systems allow remote logging of system events, which allows system adminstrators to monitor a cluster of machines from a single log file.

    By default, all syslog messages generated are prefixed with the string "Zend_Log". You may specify a different "application" name by which to identify such log messages by either passing the application name to the contructor or the application accessor:

    // At instantiation, pass the "application" key in the options:
    $writer = new Zend_Log_Writer_Syslog(array('application' => 'FooBar'));
    
    // Any other time:
    $writer->setApplication('BarBaz');

    The system log also allows you to identify the "facility," or application type, logging the message; many system loggers will actually generate different log files per facility, which again aids administrators monitoring server activity.

    You may specify the log facility either in the constructor or via an accessor. It should be one of the openlog() constants defined on the » openlog() manual page.

    // At instantiation, pass the "facility" key in the options:
    $writer = new Zend_Log_Writer_Syslog(array('facility' => LOG_AUTH));
    
    // Any other time:
    $writer->setFacility(LOG_USER);

    When logging, you may continue to use the default Zend_Log priority constants; internally, they are mapped to the appropriate syslog() priority constants.

    Stubbing Out the Writer

    The Zend_Log_Writer_Null 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_Null;
    $logger = new Zend_Log($writer);
    
    // goes nowhere
    $logger->info('Informational message');

    Testing with the Mock

    The Zend_Log_Writer_Mock is a very simple writer that records the raw data it receives in an array exposed as a public property.

    $mock = new Zend_Log_Writer_Mock;
    $logger = new Zend_Log($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, simply set $mock->events = array().

    Compositing Writers

    There is no composite Writer object. However, a Log instance can write to any number of Writers. To do this, use the 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->addWriter($writer1);
    $logger->addWriter($writer2);
    
    // goes to both writers
    $logger->info('Informational message');

    Previous Next
    Introduction to Zend Framework
    Overview
    Installation
    Zend_Acl
    Introduction
    Refining Access Controls
    Advanced Usage
    Zend_Amf
    Introduction
    Zend_Amf_Server
    Zend_Application
    Introduction
    Zend_Application Quick Start
    Theory of Operation
    Examples
    Core Functionality
    Available Resource Plugins
    Zend_Auth
    Introduction
    Database Table Authentication
    Digest Authentication
    HTTP Authentication Adapter
    LDAP Authentication
    Open ID Authentication
    Zend_Cache
    Introduction
    The Theory of Caching
    Zend_Cache Frontends
    Zend_Cache Backends
    Zend_Captcha
    Introduction
    Captcha Operation
    CAPTCHA Adapters
    Zend_CodeGenerator
    Introduction
    Zend_CodeGenerator Examples
    Zend_CodeGenerator Reference
    Zend_Config
    Introduction
    Theory of Operation
    Zend_Config_Ini
    Zend_Config_Xml
    Zend_Config_Writer
    Zend_Config_Writer
    Zend_Console_Getopt
    Introduction
    Declaring Getopt Rules
    Fetching Options and Arguments
    Configuring Zend_Console_Getopt
    Zend_Controller
    Zend_Controller Quick Start
    Zend_Controller Basics
    The Front Controller
    The Request Object
    The Standard Router
    The Dispatcher
    Action Controllers
    Action Helpers
    The Response Object
    Plugins
    Using a Conventional Modular Directory Structure
    MVC Exceptions
    Migrating from Previous Versions
    Zend_Currency
    Introduction to Zend_Currency
    How to Work with Currencies
    Migrating from Previous Versions
    Zend_Date
    Introduction
    Theory of Operation
    Basic Methods
    Zend_Date API Overview
    Creation of Dates
    Constants for General Date Functions
    Working Examples
    Zend_Db
    Zend_Db_Adapter
    Zend_Db_Statement
    Zend_Db_Profiler
    Zend_Db_Select
    Zend_Db_Table
    Zend_Db_Table_Row
    Zend_Db_Table_Rowset
    Zend_Db_Table Relationships
    Zend_Db_Table_Definition
    Zend_Debug
    Dumping Variables
    Zend_Dojo
    Introduction
    Zend_Dojo_Data: dojo.data Envelopes
    Dojo View Helpers
    Dojo Form Elements and Decorators
    Zend_Dojo build layer support
    Zend_Dom
    Introduction
    Zend_Dom_Query
    Zend_Exception
    Using Exceptions
    Zend_Feed
    Introduction
    Importing Feeds
    Retrieving Feeds from Web Pages
    Consuming an RSS Feed
    Consuming an Atom Feed
    Consuming a Single Atom Entry
    Modifying Feed and Entry structures
    Custom Feed and Entry Classes
    Zend_Feed_Reader
    Zend_File
    Zend_File_Transfer
    Validators for Zend_File_Transfer
    Filters for Zend_File_Transfer
    Migrating from previous versions
    Zend_Filter
    Introduction
    Standard Filter Classes
    Filter Chains
    Writing Filters
    Zend_Filter_Input
    Zend_Filter_Inflector
    Migrating from Previous Versions
    Zend_Form
    Zend_Form
    Zend_Form Quick Start
    Creating Form Elements Using Zend_Form_Element
    Creating Forms Using Zend_Form
    Creating Custom Form Markup Using Zend_Form_Decorator
    Standard Form Elements Shipped With Zend Framework
    Standard Form Decorators Shipped With Zend Framework
    Internationalization of Zend_Form
    Advanced Zend_Form Usage
    Zend_Gdata
    Introduction
    Authenticating with AuthSub
    Using the Book Search Data API
    Authenticating with ClientLogin
    Using Google Calendar
    Using Google Documents List Data API
    Using Google Health
    Using Google Spreadsheets
    Using Google Apps Provisioning
    Using Google Base
    Using Picasa Web Albums
    Using the YouTube Data API
    Catching Gdata Exceptions
    Zend_Http
    Introduction
    Zend_Http_Client - Advanced Usage
    Zend_Http_Client - Connection Adapters
    Migrating from previous versions
    Zend_Http_Cookie and Zend_Http_CookieJar
    Zend_Http_Response
    Zend_InfoCard
    Introduction
    Zend_Json
    Introduction
    Basic Usage
    Advanced Usage of Zend_Json
    XML to JSON conversion
    Zend_Json_Server - JSON-RPC server
    Zend_Layout
    Introduction
    Zend_Layout Quick Start
    Zend_Layout Configuration Options
    Zend_Layout Advanced Usage
    Zend_Ldap
    Introduction
    API overview
    Usage Scenarios
    Tools
    Object oriented access to the LDAP tree using Zend_Ldap_Node
    Getting information from the LDAP server
    Serializing LDAP data to and from LDIF
    Zend_Loader
    Loading Files and Classes Dynamically
    The Autoloader
    Resource Autoloaders
    Loading Plugins
    Zend_Locale
    Introduction
    Using Zend_Locale
    Normalization and Localization
    Working with Dates and Times
    Supported locales
    Migrating from previous versions
    Zend_Log
    Overview
    Writers
    Formatters
    Filters
    Zend_Mail
    Introduction
    Sending via SMTP
    Sending Multiple Mails per SMTP Connection
    Using Different Transports
    HTML E-Mail
    Attachments
    Adding Recipients
    Controlling the MIME Boundary
    Additional Headers
    Character Sets
    Encoding
    SMTP Authentication
    Securing SMTP Transport
    Reading Mail Messages
    Zend_Measure
    Introduction
    Creation of Measurements
    Outputting measurements
    Manipulating Measurements
    Types of measurements
    Zend_Memory
    Overview
    Memory Manager
    Memory Objects
    Zend_Mime
    Zend_Mime
    Zend_Mime_Message
    Zend_Mime_Part
    Zend_Navigation
    Introduction
    Pages
    Containers
    Migrating from Previous Versions
    Zend_OpenId
    Introduction
    Zend_OpenId_Consumer Basics
    Zend_OpenId_Provider
    Zend_Paginator
    Introduction
    Usage
    Configuration
    Advanced usage
    Zend_Pdf
    Introduction
    Creating and Loading PDF Documents
    Save Changes to PDF Documents
    Working with Pages
    Drawing
    Interactive Features
    Document Info and Metadata
    Zend_Pdf module usage example
    Zend_ProgressBar
    Zend_ProgressBar
    Zend_Queue
    Introduction
    Example usage
    Framework
    Adapters
    Customizing Zend_Queue
    Stomp
    Zend_Reflection
    Introduction
    Zend_Reflection Examples
    Zend_Reflection Reference
    Zend_Registry
    Using the Registry
    Zend_Rest
    Introduction
    Zend_Rest_Client
    Zend_Rest_Server
    Zend_Search_Lucene
    Overview
    Building Indexes
    Searching an Index
    Query Language
    Query Construction API
    Character Set
    Extensibility
    Interoperating with Java Lucene
    Advanced
    Best Practices
    Zend_Server
    Introduction
    Zend_Server_Reflection
    Zend_Service
    Introduction
    Zend_Service_Akismet
    Zend_Service_Amazon
    Zend_Service_Amazon_Ec2
    Zend_Service_Amazon_Ec2: Instances
    Zend_Service_Amazon_Ec2: Windows Instances
    Zend_Service_Amazon_Ec2: Reserved Instances
    Zend_Service_Amazon_Ec2: CloudWatch Monitoring
    Zend_Service_Amazon_Ec2: Amazon Machine Images (AMI)
    Zend_Service_Amazon_Ec2: Elastic Block Stroage (EBS)
    Zend_Service_Amazon_Ec2: Elastic IP Addresses
    Zend_Service_Amazon_Ec2: Keypairs
    Zend_Service_Amazon_Ec2: Regions and Availability Zones
    Zend_Service_Amazon_Ec2: Security Groups
    Zend_Service_Amazon_S3
    Zend_Service_Amazon_Sqs
    Zend_Service_Audioscrobbler
    Zend_Service_Delicious
    Zend_Service_Flickr
    Zend_Service_Nirvanix
    Zend_Service_ReCaptcha
    Zend_Service_Simpy
    Introduction
    Zend_Service_StrikeIron
    Zend_Service_StrikeIron: Bundled Services
    Zend_Service_StrikeIron: Advanced Uses
    Zend_Service_Technorati
    Zend_Service_Twitter
    Zend_Service_Yahoo
    Zend_Session
    Introduction
    Basic Usage
    Advanced Usage
    Global Session Management
    Zend_Session_SaveHandler_DbTable
    Zend_Soap
    Zend_Soap_Server
    Zend_Soap_Client
    WSDL Accessor
    AutoDiscovery
    Zend_Tag
    Introduction
    Zend_Tag_Cloud
    Zend_Test
    Introduction
    Zend_Test_PHPUnit
    Zend_Test_PHPUnit_Db
    Zend_Text
    Zend_Text_Figlet
    Zend_Text_Table
    Zend_TimeSync
    Introduction
    Working with Zend_TimeSync
    Zend_Tool_Framework
    Introduction
    Using the CLI Tool
    Architecture
    Creating Providers to use with Zend_Tool_Framework
    Shipped System Providers
    Extending and Configuring Zend_Tool_Framework
    Zend_Tool_Project
    Introduction
    Create A Project
    Zend Tool Project Providers
    Zend_Translate
    Introduction
    Adapters for Zend_Translate
    Using Translation Adapters
    Creating source files
    Additional features for translation
    Plural notations for Translation
    Migrating from previous versions
    Zend_Uri
    Zend_Uri
    Zend_Validate
    Introduction
    Standard Validation Classes
    Validator Chains
    Writing Validators
    Validation Messages
    Zend_Version
    Getting the Zend Framework Version
    Zend_View
    Introduction
    Controller Scripts
    View Scripts
    View Helpers
    Zend_View_Abstract
    Migrating from Previous Versions
    Zend_Wildfire
    Zend_Wildfire
    Zend_XmlRpc
    Introduction
    Zend_XmlRpc_Client
    Zend_XmlRpc_Server
    Zend Framework Requirements
    Introduction
    Zend Framework Coding Standard for PHP
    Overview
    PHP File Formatting
    Naming Conventions
    Coding Style
    Zend Framework Documentation Standard
    Overview
    Documentation File Formatting
    Recommendations
    Recommended Project Structure for Zend Framework MVC Applications
    Overview
    Recommended Project Directory Structure
    Module Structure
    Rewrite Configuration Guide
    Zend Framework Performance Guide
    Introduction
    Class Loading
    Zend_Db Performance
    Internationalization (i18n) and Localization (l10n)
    View Rendering
    Copyright Information