/vendor/monolog/monolog/doc/01-usage.md |
@@ -0,0 +1,231 @@ |
# Using Monolog |
|
- [Installation](#installation) |
- [Core Concepts](#core-concepts) |
- [Log Levels](#log-levels) |
- [Configuring a logger](#configuring-a-logger) |
- [Adding extra data in the records](#adding-extra-data-in-the-records) |
- [Leveraging channels](#leveraging-channels) |
- [Customizing the log format](#customizing-the-log-format) |
|
## Installation |
|
Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog)) |
and as such installable via [Composer](http://getcomposer.org/). |
|
```bash |
composer require monolog/monolog |
``` |
|
If you do not use Composer, you can grab the code from GitHub, and use any |
PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader)) |
to load Monolog classes. |
|
## Core Concepts |
|
Every `Logger` instance has a channel (name) and a stack of handlers. Whenever |
you add a record to the logger, it traverses the handler stack. Each handler |
decides whether it fully handled the record, and if so, the propagation of the |
record ends there. |
|
This allows for flexible logging setups, for example having a `StreamHandler` at |
the bottom of the stack that will log anything to disk, and on top of that add |
a `MailHandler` that will send emails only when an error message is logged. |
Handlers also have a `$bubble` property which defines whether they block the |
record or not if they handled it. In this example, setting the `MailHandler`'s |
`$bubble` argument to false means that records handled by the `MailHandler` will |
not propagate to the `StreamHandler` anymore. |
|
You can create many `Logger`s, each defining a channel (e.g.: db, request, |
router, ..) and each of them combining various handlers, which can be shared |
or not. The channel is reflected in the logs and allows you to easily see or |
filter records. |
|
Each Handler also has a Formatter, a default one with settings that make sense |
will be created if you don't set one. The formatters normalize and format |
incoming records so that they can be used by the handlers to output useful |
information. |
|
Custom severity levels are not available. Only the eight |
[RFC 5424](http://tools.ietf.org/html/rfc5424) levels (debug, info, notice, |
warning, error, critical, alert, emergency) are present for basic filtering |
purposes, but for sorting and other use cases that would require |
flexibility, you should add Processors to the Logger that can add extra |
information (tags, user ip, ..) to the records before they are handled. |
|
## Log Levels |
|
Monolog supports the logging levels described by [RFC 5424](http://tools.ietf.org/html/rfc5424). |
|
- **DEBUG** (100): Detailed debug information. |
|
- **INFO** (200): Interesting events. Examples: User logs in, SQL logs. |
|
- **NOTICE** (250): Normal but significant events. |
|
- **WARNING** (300): Exceptional occurrences that are not errors. Examples: |
Use of deprecated APIs, poor use of an API, undesirable things that are not |
necessarily wrong. |
|
- **ERROR** (400): Runtime errors that do not require immediate action but |
should typically be logged and monitored. |
|
- **CRITICAL** (500): Critical conditions. Example: Application component |
unavailable, unexpected exception. |
|
- **ALERT** (550): Action must be taken immediately. Example: Entire website |
down, database unavailable, etc. This should trigger the SMS alerts and wake |
you up. |
|
- **EMERGENCY** (600): Emergency: system is unusable. |
|
## Configuring a logger |
|
Here is a basic setup to log to a file and to firephp on the DEBUG level: |
|
```php |
<?php |
|
use Monolog\Logger; |
use Monolog\Handler\StreamHandler; |
use Monolog\Handler\FirePHPHandler; |
|
// Create the logger |
$logger = new Logger('my_logger'); |
// Now add some handlers |
$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG)); |
$logger->pushHandler(new FirePHPHandler()); |
|
// You can now use your logger |
$logger->addInfo('My logger is now ready'); |
``` |
|
Let's explain it. The first step is to create the logger instance which will |
be used in your code. The argument is a channel name, which is useful when |
you use several loggers (see below for more details about it). |
|
The logger itself does not know how to handle a record. It delegates it to |
some handlers. The code above registers two handlers in the stack to allow |
handling records in two different ways. |
|
Note that the FirePHPHandler is called first as it is added on top of the |
stack. This allows you to temporarily add a logger with bubbling disabled if |
you want to override other configured loggers. |
|
> If you use Monolog standalone and are looking for an easy way to |
> configure many handlers, the [theorchard/monolog-cascade](https://github.com/theorchard/monolog-cascade) |
> can help you build complex logging configs via PHP arrays, yaml or json configs. |
|
## Adding extra data in the records |
|
Monolog provides two different ways to add extra informations along the simple |
textual message. |
|
### Using the logging context |
|
The first way is the context, allowing to pass an array of data along the |
record: |
|
```php |
<?php |
|
$logger->addInfo('Adding a new user', array('username' => 'Seldaek')); |
``` |
|
Simple handlers (like the StreamHandler for instance) will simply format |
the array to a string but richer handlers can take advantage of the context |
(FirePHP is able to display arrays in pretty way for instance). |
|
### Using processors |
|
The second way is to add extra data for all records by using a processor. |
Processors can be any callable. They will get the record as parameter and |
must return it after having eventually changed the `extra` part of it. Let's |
write a processor adding some dummy data in the record: |
|
```php |
<?php |
|
$logger->pushProcessor(function ($record) { |
$record['extra']['dummy'] = 'Hello world!'; |
|
return $record; |
}); |
``` |
|
Monolog provides some built-in processors that can be used in your project. |
Look at the [dedicated chapter](https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md#processors) for the list. |
|
> Tip: processors can also be registered on a specific handler instead of |
the logger to apply only for this handler. |
|
## Leveraging channels |
|
Channels are a great way to identify to which part of the application a record |
is related. This is useful in big applications (and is leveraged by |
MonologBundle in Symfony2). |
|
Picture two loggers sharing a handler that writes to a single log file. |
Channels would allow you to identify the logger that issued every record. |
You can easily grep through the log files filtering this or that channel. |
|
```php |
<?php |
|
use Monolog\Logger; |
use Monolog\Handler\StreamHandler; |
use Monolog\Handler\FirePHPHandler; |
|
// Create some handlers |
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG); |
$firephp = new FirePHPHandler(); |
|
// Create the main logger of the app |
$logger = new Logger('my_logger'); |
$logger->pushHandler($stream); |
$logger->pushHandler($firephp); |
|
// Create a logger for the security-related stuff with a different channel |
$securityLogger = new Logger('security'); |
$securityLogger->pushHandler($stream); |
$securityLogger->pushHandler($firephp); |
|
// Or clone the first one to only change the channel |
$securityLogger = $logger->withName('security'); |
``` |
|
## Customizing the log format |
|
In Monolog it's easy to customize the format of the logs written into files, |
sockets, mails, databases and other handlers. Most of the handlers use the |
|
```php |
$record['formatted'] |
``` |
|
value to be automatically put into the log device. This value depends on the |
formatter settings. You can choose between predefined formatter classes or |
write your own (e.g. a multiline text file for human-readable output). |
|
To configure a predefined formatter class, just set it as the handler's field: |
|
```php |
// the default date format is "Y-m-d H:i:s" |
$dateFormat = "Y n j, g:i a"; |
// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n" |
$output = "%datetime% > %level_name% > %message% %context% %extra%\n"; |
// finally, create a formatter |
$formatter = new LineFormatter($output, $dateFormat); |
|
// Create a handler |
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG); |
$stream->setFormatter($formatter); |
// bind it to a logger object |
$securityLogger = new Logger('security'); |
$securityLogger->pushHandler($stream); |
``` |
|
You may also reuse the same formatter between multiple handlers and share those |
handlers between multiple loggers. |
|
[Handlers, Formatters and Processors](02-handlers-formatters-processors.md) → |
/vendor/monolog/monolog/doc/02-handlers-formatters-processors.md |
@@ -0,0 +1,157 @@ |
# Handlers, Formatters and Processors |
|
- [Handlers](#handlers) |
- [Log to files and syslog](#log-to-files-and-syslog) |
- [Send alerts and emails](#send-alerts-and-emails) |
- [Log specific servers and networked logging](#log-specific-servers-and-networked-logging) |
- [Logging in development](#logging-in-development) |
- [Log to databases](#log-to-databases) |
- [Wrappers / Special Handlers](#wrappers--special-handlers) |
- [Formatters](#formatters) |
- [Processors](#processors) |
- [Third Party Packages](#third-party-packages) |
|
## Handlers |
|
### Log to files and syslog |
|
- _StreamHandler_: Logs records into any PHP stream, use this for log files. |
- _RotatingFileHandler_: Logs records to a file and creates one logfile per day. |
It will also delete files older than `$maxFiles`. You should use |
[logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile |
setups though, this is just meant as a quick and dirty solution. |
- _SyslogHandler_: Logs records to the syslog. |
- _ErrorLogHandler_: Logs records to PHP's |
[`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function. |
|
### Send alerts and emails |
|
- _NativeMailerHandler_: Sends emails using PHP's |
[`mail()`](http://php.net/manual/en/function.mail.php) function. |
- _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance. |
- _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API. |
- _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API. |
- _FlowdockHandler_: Logs records to a [Flowdock](https://www.flowdock.com/) account. |
- _SlackHandler_: Logs records to a [Slack](https://www.slack.com/) account using the Slack API. |
- _SlackbotHandler_: Logs records to a [Slack](https://www.slack.com/) account using the Slackbot incoming hook. |
- _SlackWebhookHandler_: Logs records to a [Slack](https://www.slack.com/) account using Slack Webhooks. |
- _MandrillHandler_: Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance. |
- _FleepHookHandler_: Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks. |
- _IFTTTHandler_: Notifies an [IFTTT](https://ifttt.com/maker) trigger with the log channel, level name and message. |
|
### Log specific servers and networked logging |
|
- _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this |
for UNIX and TCP sockets. See an [example](sockets.md). |
- _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible |
server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+). |
- _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server. |
- _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server. |
- _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using |
[raven](https://packagist.org/packages/raven/raven). |
- _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server. |
- _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application. |
- _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account. |
- _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account. |
- _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server. |
- _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account. |
|
### Logging in development |
|
- _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing |
inline `console` messages within [FireBug](http://getfirebug.com/). |
- _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing |
inline `console` messages within Chrome. |
- _BrowserConsoleHandler_: Handler to send logs to browser's Javascript `console` with |
no browser extension required. Most browsers supporting `console` API are supported. |
- _PHPConsoleHandler_: Handler for [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef), providing |
inline `console` and notification popup messages within Chrome. |
|
### Log to databases |
|
- _RedisHandler_: Logs records to a [redis](http://redis.io) server. |
- _MongoDBHandler_: Handler to write records in MongoDB via a |
[Mongo](http://pecl.php.net/package/mongo) extension connection. |
- _CouchDBHandler_: Logs records to a CouchDB server. |
- _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM. |
- _ElasticSearchHandler_: Logs records to an Elastic Search server. |
- _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php). |
|
### Wrappers / Special Handlers |
|
- _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as |
parameter and will accumulate log records of all levels until a record |
exceeds the defined severity level. At which point it delivers all records, |
including those of lower severity, to the handler it wraps. This means that |
until an error actually happens you will not see anything in your logs, but |
when it happens you will have the full information, including debug and info |
records. This provides you with all the information you need, but only when |
you need it. |
- _DeduplicationHandler_: Useful if you are sending notifications or emails |
when critical errors occur. It takes a logger as parameter and will |
accumulate log records of all levels until the end of the request (or |
`flush()` is called). At that point it delivers all records to the handler |
it wraps, but only if the records are unique over a given time period |
(60seconds by default). If the records are duplicates they are simply |
discarded. The main use of this is in case of critical failure like if your |
database is unreachable for example all your requests will fail and that |
can result in a lot of notifications being sent. Adding this handler reduces |
the amount of notifications to a manageable level. |
- _WhatFailureGroupHandler_: This handler extends the _GroupHandler_ ignoring |
exceptions raised by each child handler. This allows you to ignore issues |
where a remote tcp connection may have died but you do not want your entire |
application to crash and may wish to continue to log to other handlers. |
- _BufferHandler_: This handler will buffer all the log records it receives |
until `close()` is called at which point it will call `handleBatch()` on the |
handler it wraps with all the log messages at once. This is very useful to |
send an email with all records at once for example instead of having one mail |
for every log record. |
- _GroupHandler_: This handler groups other handlers. Every record received is |
sent to all the handlers it is configured with. |
- _FilterHandler_: This handler only lets records of the given levels through |
to the wrapped handler. |
- _SamplingHandler_: Wraps around another handler and lets you sample records |
if you only want to store some of them. |
- _NullHandler_: Any record it can handle will be thrown away. This can be used |
to put on top of an existing handler stack to disable it temporarily. |
- _PsrHandler_: Can be used to forward log records to an existing PSR-3 logger |
- _TestHandler_: Used for testing, it records everything that is sent to it and |
has accessors to read out the information. |
- _HandlerWrapper_: A simple handler wrapper you can inherit from to create |
your own wrappers easily. |
|
## Formatters |
|
- _LineFormatter_: Formats a log record into a one-line string. |
- _HtmlFormatter_: Used to format log records into a human readable html table, mainly suitable for emails. |
- _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded. |
- _ScalarFormatter_: Used to format log records into an associative array of scalar values. |
- _JsonFormatter_: Encodes a log record into json. |
- _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler. |
- _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler. |
- _GelfMessageFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler. |
- _LogstashFormatter_: Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/latest). |
- _ElasticaFormatter_: Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler. |
- _LogglyFormatter_: Used to format log records into Loggly messages, only useful for the LogglyHandler. |
- _FlowdockFormatter_: Used to format log records into Flowdock messages, only useful for the FlowdockHandler. |
- _MongoDBFormatter_: Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler. |
|
## Processors |
|
- _PsrLogMessageProcessor_: Processes a log record's message according to PSR-3 rules, replacing `{foo}` with the value from `$context['foo']`. |
- _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated. |
- _WebProcessor_: Adds the current request URI, request method and client IP to a log record. |
- _MemoryUsageProcessor_: Adds the current memory usage to a log record. |
- _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record. |
- _ProcessIdProcessor_: Adds the process id to a log record. |
- _UidProcessor_: Adds a unique identifier to a log record. |
- _GitProcessor_: Adds the current git branch and commit to a log record. |
- _TagProcessor_: Adds an array of predefined tags to a log record. |
|
## Third Party Packages |
|
Third party handlers, formatters and processors are |
[listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You |
can also add your own there if you publish one. |
|
← [Usage](01-usage.md) | [Utility classes](03-utilities.md) → |
/vendor/monolog/monolog/doc/04-extending.md |
@@ -0,0 +1,76 @@ |
# Extending Monolog |
|
Monolog is fully extensible, allowing you to adapt your logger to your needs. |
|
## Writing your own handler |
|
Monolog provides many built-in handlers. But if the one you need does not |
exist, you can write it and use it in your logger. The only requirement is |
to implement `Monolog\Handler\HandlerInterface`. |
|
Let's write a PDOHandler to log records to a database. We will extend the |
abstract class provided by Monolog to keep things DRY. |
|
```php |
<?php |
|
use Monolog\Logger; |
use Monolog\Handler\AbstractProcessingHandler; |
|
class PDOHandler extends AbstractProcessingHandler |
{ |
private $initialized = false; |
private $pdo; |
private $statement; |
|
public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true) |
{ |
$this->pdo = $pdo; |
parent::__construct($level, $bubble); |
} |
|
protected function write(array $record) |
{ |
if (!$this->initialized) { |
$this->initialize(); |
} |
|
$this->statement->execute(array( |
'channel' => $record['channel'], |
'level' => $record['level'], |
'message' => $record['formatted'], |
'time' => $record['datetime']->format('U'), |
)); |
} |
|
private function initialize() |
{ |
$this->pdo->exec( |
'CREATE TABLE IF NOT EXISTS monolog ' |
.'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)' |
); |
$this->statement = $this->pdo->prepare( |
'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)' |
); |
|
$this->initialized = true; |
} |
} |
``` |
|
You can now use this handler in your logger: |
|
```php |
<?php |
|
$logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite'))); |
|
// You can now use your logger |
$logger->addInfo('My logger is now ready'); |
``` |
|
The `Monolog\Handler\AbstractProcessingHandler` class provides most of the |
logic needed for the handler, including the use of processors and the formatting |
of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``). |
|
← [Utility classes](03-utilities.md) |