The EventLog component provides an API to log events and audit trails. These
events and audit trails are written to files or other storage spaces in
various formats. How and where the log messages (events and audit trails) are
written depends on the chosen or customized log writer.
The available log writers are:
- ezcLogDatabaseWriter, which writes log messages to the database.
- ezcLogUnixFileWriter, which writes log messages to a file in an 'Unix' file
format.
Each of these writers can be customized or extended.
An incoming log message can be written to zero or more writers. The writers
that write the log message depends on the variables of the log message itself and the
ezcLogMapper implementation. An implementation of the ezcLogMapper checks the
severity, source, and category from the log message and forwards the message
to the matching writers.
This example creates a file writer, and assigns it to the default log mapper.
1. <?php
2.
3. include( "tutorial_autoload.php" );
4. date_default_timezone_set( "UTC" );
5.
6. // Get the one and only instance of the ezcLog.
7. $log = ezcLog::getInstance();
8.
9. // Get an instance to the default log mapper.
10. $mapper = $log->getMapper();
11.
12. // Create a new Unix file writer, that writes to the file: "default.log".
13. $writer = new ezcLogUnixFileWriter( "/tmp/logs", "default.log" );
14.
15. // Create a filter that accepts every message (default behavior).
16. $filter = new ezcLogFilter;
17.
18. // Combine the filter with the writer in a filter rule.
19. $rule = new ezcLogFilterRule( $filter, $writer, true );
20.
21. // And finally assign the rule to the mapper.
22. $mapper->appendRule( $rule );
23.
24. // Write a message to the log.
25. $log->log( "Could not connect with the payment server.", ezcLog::WARNING );
26.
27. ?>
First the tutorial_autoload.php is included. The included file loads the
correct php files for the EventLog component. Hereafter the time zone is set to
"UTC". The log uses some date functions and without a time zone set, PHP may
show warnings.
Hereafter the log is set up, and a message is written to the log file
"default.log" and the file will be placed in the "/tmp/log" directory.
After execution, the file "/tmp/log/default.php" contains something like:
Jan 24 14:39:57 [Warning] [default] [default] Could not connect with the payment server.
Respectively the date, severity, source, category, and message are shown. The
source and category are both set to default, because they were not specified in
the message.
The default source and category from the ezcLog can be set via the properties:
"source" and "category". The next example demonstrates how the default
properties can be set and how extra variables can be added to the log.
1. <?php
2.
3. include( "tutorial_autoload.php" );
4. date_default_timezone_set( "UTC" );
5.
6. // Same set up as the previous example.
7. $log = ezcLog::getInstance();
8. $writer = new ezcLogUnixFileWriter( "/tmp/logs", "default.log" );
9. $log->getmapper()->appendRule( new ezcLogFilterRule( new ezcLogFilter, $writer, true ) );
10.
11. // Set the source and category.
12. $log->source = "Payment module";
13. $log->category = "Template";
14.
15. $log->log( "Could not find cache file: </var/cache/payment1234.cache>.", ezcLog::WARNING );
16.
17. // ...
18.
19. // Write a SQL error. The category is set to SQL for this message only.
20. $log->log( "Cannot execute query: <SELECT * FROM Orders WHERE ID = '123'>.", ezcLog::ERROR, array( "category" => "SQL" ) );
21.
22. // ...
23.
24. // Write a debug message that includes the current filename and line number.
25. // The category is left out.
26. $log->log( "Starting shutdown process.", ezcLog::DEBUG, array( "category" => "", "file" => __FILE__, "line" => __LINE__ ) );
27.
28. ?>
After execution, the file "/tmp/log/default.php" contains something like:
Jan 24 15:45:04 [Warning] [Payment module] [Template] Could not find cache file: </var/cache/payment1234.cache>.
Jan 24 15:45:04 [Error] [Payment module] [SQL] Cannot execute query: <SELECT * FROM Orders WHERE ID = '123'>.
Jan 24 15:45:04 [Debug] [Payment module] Starting shutdown process. (file: /home/rb/php5/ezcomponents/packages/EventLog/trunk/docs/tutorial_sources_categories.php, line: 25)
Some cases it is convenient to add automatically log attributes to the log
message. For example:
- Audit trails should include the current user.
- A payment system should always include the order number.
However, the log attributes appended to the log message are static. The
value assigned to the attribute will be the same.
The next example assigns two automatic attributes:
1. <?php
2.
3. include( "tutorial_autoload.php" );
4. date_default_timezone_set( "UTC" );
5.
6. // Same set up as the previous examples.
7. $log = ezcLog::getInstance();
8. $writer = new ezcLogUnixFileWriter( "/tmp/logs", "default.log" );
9. $log->getmapper()->appendRule( new ezcLogFilterRule( new ezcLogFilter, $writer, true ) );
10.
11. // ...
12.
13. $username = "John Doe";
14. $service = "Paynet Terminal";
15.
16. // ...
17.
18. // Add automatically the username to the log message, when the log message is either a SUCCESS_AUDIT or a FAILED_AUDIT.
19. $log->setSeverityAttributes( ezcLog::SUCCESS_AUDIT | ezcLog::FAILED_AUDIT, array( "username" => $username ) );
20.
21. // Same can be done with the source of the log message.
22. $log->setSourceAttributes( array( "Payment" ), array( "service" => $service ) );
23.
24. // Writing some log messages.
25. $log->log( "Authentication failed", ezcLog::FAILED_AUDIT, array( "source" => "security", "category" => "login/logoff" ) );
26.
27. $log->source = "Payment";
28. $log->log( "Connecting with the server.", ezcLog::DEBUG, array( "category" => "external connections" ) );
29.
30. $log->log( "Payed with creditcard.", ezcLog::SUCCESS_AUDIT, array( "category" => "shop" ) );
31.
32.
33. ?>
After execution, the file "/tmp/log/default.php" contains:
Jan 25 10:15:19 [Failed audit] [security] [login/logoff] Authentication failed (username: John Doe)
Jan 25 10:15:19 [Debug] [Payment] [external connections] Connecting with the server. (service: Paynet Terminal)
Jan 25 10:15:19 [Success audit] [Payment] [shop] Payed with creditcard. (username: John Doe, service: Paynet Terminal)
Depending on the incoming log message, the message can be stored on different
writers. This example handles the log message as follows:
- Ignore all message with the severity DEBUG.
- Store the audit trails in the "audit.log" file.
- Store the logs with the Payment category in the "payment.log" file.
- Store all the messages, except DEBUG, in the "general.log" file.
The code is as follows:
1. <?php
2. include( "tutorial_autoload.php" );
3. date_default_timezone_set( "UTC" );
4.
5. // Same set up as the previous examples.
6. $log = ezcLog::getInstance();
7.
8. // Create the writers
9. $writeAll = new ezcLogUnixFileWriter( "/tmp/logs", "general.log" );
10. $writePayment = new ezcLogUnixFileWriter( "/tmp/logs", "payment.log" );
11. $writeAuditTrails = new ezcLogUnixFileWriter( "/tmp/logs", "audit_trails.log" );
12.
13. $debugFilter = new ezcLogFilter;
14. $debugFilter->severity = ezcLog::DEBUG;
15. $log->getmapper()->appendRule( new ezcLogFilterRule( $debugFilter, array(), false ) );
16.
17. $auditFilter = new ezcLogFilter;
18. $auditFilter->severity = ezcLog::SUCCESS_AUDIT | ezcLog::FAILED_AUDIT;
19. $log->getMapper()->appendRule( new ezcLogFilterRule( $auditFilter, $writeAuditTrails, true ) );
20.
21. $paymentFilter = new ezcLogFilter;
22. $paymentFilter->source = array( "Payment" );
23. $log->getMapper()->appendRule( new ezcLogFilterRule( $paymentFilter, $writePayment, true ) );
24.
25. $log->getMapper()->appendRule( new ezcLogFilterRule( new ezcLogFilter, $writeAll, true ) );
26.
27.
28. // Writing some log messages.
29. $log->log( "Authentication failed", ezcLog::FAILED_AUDIT, array( "source" => "security", "category" => "login/logoff" ) );
30.
31. $log->source = "Payment";
32. $log->log( "Connecting with the server.", ezcLog::DEBUG, array( "category" => "external connections" ) );
33.
34. $log->log( "Payed with creditcard.", ezcLog::SUCCESS_AUDIT, array( "category" => "shop" ) );
35.
36. $log->log( "The credit card information is removed.", ezcLog::NOTICE, array( "category" => "shop" ) );
37. ?>
To write log messages to the database, the Database component is used. The
table to which the log is written should already exist.
1. <?php
2.
3. include( "tutorial_autoload.php" );
4. date_default_timezone_set( "UTC" );
5.
6. // Open database connection.
7. $db = ezcDbFactory::create( "mysql://root@localhost/logs" );
8.
9. // Create the database writer.
10. // Attach to the database handler. And write log entries to the table: "default".
11. $writer = new ezcLogDatabaseWriter( $db, "general" );
12.
13. $log = ezcLog::getInstance();
14.
15. // Write everything to the database.
16. $log->getmapper()->appendRule( new ezcLogFilterRule( new ezcLogFilter, $writer, true ) );
17.
18. // Write a message
19. $log->log( "Cannot load Payment module", ezcLog::ERROR, array( "source" => "shop", "category" => "modules" ) );
20.
21. ?>
The database: "logs" and the table "general" should exist. The table should at
least contain the columns: time, message, severity, source, category. An
example MySQL query to create the table:
CREATE TABLE `general`
(
`id` INT NOT NULL AUTO_INCREMENT,
`time` DATETIME NOT NULL,
`message` VARCHAR( 255 ) NOT NULL,
`severity` VARCHAR( 40 ) NOT NULL,
`source` VARCHAR( 100 ) NOT NULL ,
`category` VARCHAR( 100 ) NOT NULL,
`file` VARCHAR( 100 ) NOT NULL,
`line` INT NOT NULL,
PRIMARY KEY ( `id` )
)
The EventLog component is designed that it can be used with trigger_error or
stand-alone. Instead of calling the ezcLog::getInstance()->log() method, the
trigger_error can be called. Using the trigger_error method makes your code
less Log package dependent and produces less overhead when logging is disabled.
The function set_error_handler should set up a callback function (or method)
that in its turn calls the EventLog. See for more information the
ezcLog::logHandler method.