theorchard / monolog-cascade

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

SwiftMailerHandler configuration #59

Open nayanap opened 8 years ago

nayanap commented 8 years ago

I think this is a great library making life easy in setting up logs. Although, I am trying to configure SwiftMailerHandler as one of the handlers to send alerts for errors. I am having issues in doing so. Do you have samples or documentation on how to set it up ?

rantonmattei commented 8 years ago

Hello,

You can look into setting up handlers that take objects as arguments in their constructor: You have an example here with the RavenHandler https://github.com/theorchard/monolog-cascade/blob/master/examples/dependency_config.yml

It should look something like:


handlers:
    swift:
        class: Monolog\Handler\SwiftMailerHandler
        mailer:
            class: Swift_Mailer
            transport: 
                class: Swift_SmtpTransport
                # Below is optional cause Cascade should pick up
                # default values for you
                #host: '127.0.0.1'
                #port: 25
        message:
            class: Swift_Message
            subject: 'Hello'
            body: 'How are you?'
        level: DEBUG
loggers:
    mylogger:
        handlers: [swift]

This has not been tested I just put it together by looking at different params of the constructors SwiftMailerHandler construtor takes $mailer and $message as required parameters. $mailer being an object (of Swift_Mailer type), you have to provide its contructor params as well.

From the ReadMe:

Note: If you would like to use objects as parameters for your handlers, you can pass a class name (using the class option) with the corresponding arguments just like you would configure your handler. Cascade recursively instantiates and loads those objects as it parses the config file. See this sample config file.

Param names in your config just have to match the param names from the constructor.

I hope this helps.

nayanap commented 8 years ago

Thank you for the timely reply on the question. I tried to set up Swift Handler before sending you this question with the usage examples for RavenClient and Redis but I could not get that to work. With your help I did set up my config for SwiftHandler correctly as previously I missed to provide the object for message instead I was just passing a string as a message.

Although we are providing all the required objects now, I am still getting the same error at the time of instantiation.

Catchable fatal error: Argument 1 passed to Monolog\Handler\SwiftMailerHandler::__construct() must be an instance of Swift_Mailer, array given

I think this is because we are not recursively instantiating the objects before calling the SwiftHandler. I logged the constructor arguments that Cascade is passing to SwiftHandler and they are passed in as arrays instead of instances of the respective classes. Can you please look into this when possible and confirm ?

`Array ( [0] => Array ( [class] => Swift_Mailer [transport] => Array ( [class] => Swift_SmtpTransport )

    )

[1] => Array
    (
        [class] => Swift_Message
        [subject] => Hello
        [body] => How are you?
    )

[2] => DEBUG
[3] => 1

)` Thanks a ton.

rantonmattei commented 8 years ago

So, I tried 2 things:

public function testLoadDependency()
{
    $options = array(
        'class' => 'Cascade\Tests\Fixtures\DependentClass',
        'something_else' => 'Hello',
        'dependency' => array(
            'class' => 'Cascade\Tests\Fixtures\DependentClass',
            'something_else' => 'Hi',
            'dependency' => array(
                'class' => 'Cascade\Tests\Fixtures\SampleClass',
                'mandatory' => 'someValue',
            )
        )
    );

    $loader = new ClassLoader($options);
    $instance = $loader->load();

    $expectedInstance = new DependentClass(
        new DependentClass(
            new SampleClass('someValue'),
            'Hi'
        ),
        'Hello'
    );

    $this->assertEquals($expectedInstance, $instance);
}

That test passed. That piece of code was local I haven't committed it.

<?php

$yaml = <<<EOD
handlers:
    swift:
        class: Monolog\Handler\SwiftMailerHandler
        mailer:
            class: Swift_Mailer
            transport:
                class: Swift_SmtpTransport
                host: '192.168.0.1'
                port: 96
        message:
            class: Swift_Message
            subject: 'Hello'
            body: 'How are you?'
        level: DEBUG
loggers:
    mylogger:
        handlers: [swift]
EOD;

require_once(realpath(__DIR__.'/vendor/autoload.php'));

use Cascade\Cascade;

Cascade::fileConfig($yaml);

print_r(Cascade::logger('mylogger')->getHandlers());

It worked as well. So, I am not sure what's wrong here... I assume there must be something wrong in your Yaml. Check your indentation. Another thing to verify is the version you are using. Object dependency support for options was introduced in 0.2.0.

cxc222 commented 8 years ago

The same question Is there an example?

cxc222 commented 8 years ago

$transport->setUsername(); $transport->setPassword(); How should I set?

rantonmattei commented 6 years ago

You might try

set_username: 'abcdef'
set_password: '123456'

Cascade allows you to call functions with params upon class instantiation.

So here, it should call:

  1. the Swift_SmtpTransport contructor with host and port params, and then
  2. try to call setUsername('abcdef') and setPassword('123456')

See complete config below. I haven't tested it.

<?php

$yaml = <<<EOD
handlers:
    swift:
        class: Monolog\Handler\SwiftMailerHandler
        mailer:
            class: Swift_Mailer
            transport:
                class: Swift_SmtpTransport
                host: '192.168.0.1'
                port: 96
                set_username: 'abcdef'
                set_password: '123456'
        message:
            class: Swift_Message
            subject: 'Hello'
            body: 'How are you?'
        level: DEBUG
loggers:
    mylogger:
        handlers: [swift]
EOD;

require_once(realpath(__DIR__.'/vendor/autoload.php'));

use Cascade\Cascade;

Cascade::fileConfig($yaml);

print_r(Cascade::logger('mylogger')->getHandlers());
orionerossi commented 5 years ago

Unfortunately your configuration can't work because setUsername and setPassword are not Swift_SmtpTransport methods nor they are in any inherited class. They are injected in magic method __call instead, so they can't be recognized by reflection.