Skip to content
This repository has been archived by the owner on Jan 16, 2019. It is now read-only.

Docs Logging

Frank Kleine edited this page Apr 7, 2012 · 1 revision

Table of Contents

Logging data

Stubbles contains a unique logging API which enables logging on different levels with different targets while customisable with what is being logged. The logging API is included in net::stubbles::util::log.

Using the logger

The simplest way to log data is to use the preconfigured logger (add net::stubbles::util::log::ioc::stubLogBindingModule to the list of binding modules to be used) and to inject it into you application classes:

class MyAppClass
{
    protected $logger;

    /**
***sets logger instance
     *
***@param  stubLogger  $logger
***@Inject(optional=true)
***@Named(stubLogger::LEVEL_INFO)
***/
    public function setLogger(stubLogger $logger)
    {
        $this->logger = $logger;
    }

    public function doSomething()
    {
        ...
        if (null !== $this->logger) {
            $this->logger->createLogEntry('myapp')
                         ->addData('foo')
                         ->addData('bar')
                         ->addData('baz')
                         ->log();
        }
    }
}

The above code is a typical usage scenario for the logger: the application class gets the logger injected, but as this dependency is optional (thus the null-check in doSomething()) the application class still works without a logger bound. With the @Named we define the log level that we want to use. If you need different log levels just redefine the class so it gets a logger instance for each required log level. For a complete list of log levels see below.

In the doSomething() method we use the logger instance to create a log entry, and to add data to it. After we finished adding all data we want to log we call the log() method which will take care of the actual logging process.

Delayed logging

Available since Stubbles 1.1.0.

Sometimes you want to log data, but not all of the data required to create the basic log entry is already available. This is where delayed logging comes into play. Instead of calling log() you simple call logDelayed():

class MyAppClass
{
    protected $logger;

    /**
***sets logger instance
     *
***@param  stubLogger  $logger
***@Inject(optional=true)
***@Named(stubLogger::LEVEL_INFO)
***/
    public function setLogger(stubLogger $logger)
    {
        $this->logger = $logger;
    }

    public function doSomething()
    {
        ...
        if (null !== $this->logger) {
            $this->logger->createLogEntry('myapp')
                         ->addData('foo')
                         ->addData('bar')
                         ->addData('baz')
                         ->logDelayed();
        }
    }
}

This will cause a delay in logging the data, it will be logged latest when the logger instance is destroyed, so if you are in a web environment this is most likely at the end of the request. Now all data of the prefilled log entry may be updated by the log entry factory used. Please note: data added by hand with the addData() method call as in the example above are not affected, only prefilled log entry data is updated.

Log level

There are four different error levels:

#php
<?php
stubLogger::LEVEL_DEBUG   // debugging purposes
stubLogger::LEVEL_INFO    // default logging
stubLogger::LEVEL_WARN    // warnings, but not dangerous for the application
stubLogger::LEVEL_ERROR   // errors that can not be handled by the application
?>

The purpose comments above are more a recommendation then a rule. As the log level is a bit switch it is possible to combine two or more of the log levels by adding them:

#php
<?php
stubLogger::LEVEL_INFO + stubLogger::LEVEL_WARN
?>

For convenience the log level net::stubbles::util::log::stubLogger::LEVEL_ALL incorporates all log levels and can be used as shortcut. However it should be noted that the integer value of this log level may increase if more log levels are added to the net::stubbles::util::log::stubLogger which may be the case or not in future versions of Stubbles.

The log entry

The data to log is collected in a net::stubbles::util::log::stubLogEntry object. The net::stubbles::util::log::stubLogEntry knows for which log level it should be applied (getLevel(), the return value may be a combination of the log levels explained above). The method getTarget() determines where the log data belongs. The concrete interpretation of the target depends on the log appender which takes the log data. A file log appender might use this as the basename of a file, while a database log appender might use this as the name of the table to write the log data into. Therefore it is advisable to only use ascii characters, numbers and underscores to be sure that the log appender will not mess up the log data. The whole log data contents are returned via get(). The stubLogEntry takes care that fields are seperated by net::stubbles::util::log::stubLogEntry::DEFAULT_SEPERATOR, that the fields itself do not contain this seperator and as well no line break. Line breaks are replaced with <nl></nl>.

Log entry objects are created by implementations of net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;entryfactory&#58;&#58;stubLogEntryFactory. These factories help to fill a log entry with default values before any specific log data is added by the application. For instance, the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;entryfactory&#58;&#58;stubDefaultLogEntryFactory always adds current time and a session id (if applicable) for the first two log fields before returning the log entry object. The other implementation provided by Stubbles is the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;entryfactory&#58;&#58;stubEmptyLogEntryFactory which does not add any data at all is best suited for unit tests.

Configuring the log layer

The logger is configured via dependency injection. Stubbles provides a default configuration with the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;ioc&#58;&#58;stubLogBindingModule. This means by default the log data will be written into logfiles in the projects/$PROJECT/log directory.

To use another log configuration you may want to extend the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;ioc&#58;&#58;stubLogBindingModule class or to create your own binding module.

Saving the data: log appenders

The net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;stubLogger itself does not know how the log data is stored. Storing the log data is the task of the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;appender&#58;&#58;stubLogAppender. A log appender takes log data and writes it to the target. The target can be a file, a database or anything else suited for log data. As a concrete example Stubbles offers a net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;appender&#58;&#58;stubFileLogAppender which writes the log data into a logfile on the hard disk. Other log appenders may be created by implementing the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;appender&#58;&#58;stubLogAppender interface. This interface consists of two methods:

append(stubLogEntry $logEntry)&#59;
finalize()&#59;
While append(stubLogEntry $logEntry) takes the log entry the log appender can do with it whatever it wants. The finalize() method is called when the net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;stubLogger instance where the log appender was added to is destroyed (either explicitly by calling net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;stubLogger&#58;&#58;destroyInstance($id) or implicitly at the end of the request).

A log appender can be added to a concrete net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;stubLogger instance via the addLogAppender() method:

&#35;php
&lt;?php
$debugLogFileAppender &#61; new stubFileLogAppender(&#39;/path/to/dir&#39;)&#59;
$debugLogger&#45;&gt;addLogAppender(debugLogFileAppender)&#59;
?&gt;

Beside the file log appender Stubbles offers a mail log appender (net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;appender&#58;&#58;stubMailLogAppender) which sends all log data in a mail when its finalize() method is called, and a memory log appender (net&#58;&#58;stubbles&#58;&#58;util&#58;&#58;log&#58;&#58;appender&#58;&#58;stubMemoryLogAppender). The memory log appender stores the log entries in memory and can be asked to return all stored log entries with its getLogEntries() method. This is suited for unit tests.

Clone this wiki locally