theorchard / monolog-cascade

Configure multiple loggers and handlers in the blink of an eye
MIT License
145 stars 62 forks source link

Formatter Loader + Handler Loader #10

Closed rantonmattei closed 9 years ago

rantonmattei commented 9 years ago

Added the FormatterLoader: loads any Monolog Formatter class (implementing the MonoLog\Formatter\FormatterInterface) Added the HandlerLoader: loads any Monolog Handler class (implementing the MonoLog\Handler\HandlerInterface)

They both extend ClassLoader which was the trouble maker for the previous PR. The reason was a dependency on those extra option handlers in the canHandle method. This PR contains the tests for ClassLoader as well.

I need to revisit this at some point cause it makes a double dependency that seems unnecessary. I'd like to get those closures out of here (see initExtraOptionsHandlers method).

My favorite reviewers: @mortaliorchard @OrCharles, please review!

Some more info on Monolog: Monolog Handlers are the handlers attached to you logger. A logger can log to multiple destinations: a simple log file, a stream like stdout or stderr, using an API (Loggly), etc. In order to log into those destination, you need to set up a handler for each of those. On top of that if you need specific formatter (i.e. formatting each line you log), you need to instantiate a Formatter object and set it in your Handler. That's why it is kind of tedious to set this manually.

$logger = new \Monolog\Logger();
$f1 = new \Monolog\Formatter\LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n');
$h1 = new \Monolog\Handler\LogglyHandler($myToken, $logLevel);
$h2 = new \Monolog\Handler\StreamHandler('php://stdout');
$h1->setFormatter($f1);
$h2->setFormatter($f1);
$logger->pushHandler($h1);
$logger->pushHandler($h2);

// And then finally
$logger->info('Writing with my logger');
$logger->error('uh oh, something happened');

I used the same formatter for the 2 handlers but this gets much longer if you have multiple handlers with multiple formatter.

The formatter loader takes a set of options for the formatter, typically the formatter section of you yaml file

formatters:
    spaced:
        class: Monolog\Formatter\LineFormatter
        format: "%datetime% %channel%.%level_name%  %message%\n"
        include_stacktraces: true

And it instantiate the corresponding Formatter object with the provided options.

The Handler loader does the same thing for the provided Handlers

handlers:
    console:
        class: Monolog\Handler\StreamHandler
        level: DEBUG
        formatter: spaced
        stream: php://stdout
    info_file_handler:
        class: Monolog\Handler\StreamHandler
        level: INFO
        formatter: dashed
        stream: ./example_info.log

You'll notice that handlers can reference previously defined formatter(s). So, Cascade will load formatters first and then will instantiate the Handlers.

I hope this helps

mortaliorchard commented 9 years ago

Lots of code. But I honestly don't find any issues with it. R+

OrCharles commented 9 years ago

thanks for the pre-emptive explanation.. maybe throw that into README.md ?

R+

rantonmattei commented 9 years ago

I'll put together a more detailed doc using ReadTheDoc The REadMe is already a bit long, and I think it should focus on usage more than the implementation details