Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monolog: log different channels and multiple handlers to grouped log file + dedicated log files

I'm facing some problems with configuring Monolog to handle "nested loggers".

What I want to do:

Log from services to dedicated files (one per service) AND from all services to one file. Each logger should be also handled by monolog.handlers.console.

Why I want to do

Each service has logic, but can use other services from DI. I want to know what exactly one service logs, so I want dedicated logger (with custom channel and custom log file) for each service. But when services relies on other services, I want to read logs in chronological order in one file.

What I have

app/config.yml:

monolog:
    handlers:
        my_handler:
            type:     stream
            path:     %kernel.logs_dir%/%kernel.environment%.my.log
            level:    info
            handler:  my_bundle_handler

src/My/Bundle/Resources/config/config.yml

services:
    # LOGGERS
    my_logger:
        class: Symfony\Bridge\Monolog\Logger
        arguments: [my_logger]
        calls:
            - [pushHandler, [@monolog.handler.console]]
            - [pushHandler, [@my_bundle_handler]]
        tags:
            - { name: monolog.logger, channel: my_channel}

    # HANDLERS
    my_bundle_handler:
        abstract: true # Without it it will throw exception
        type: group
        members: [my_service_handler]
        channels: ["my_channel"]
        tags:
            - { name: log_handler }

    my_service_handler:
        class: Monolog\Handler\StreamHandler
        arguments: [%kernel.logs_dir%/%kernel.environment%.my_service.log, 100]
        channels: ["my_channel"]
        tags:
            - { name: log_handler }

It does not work as expected. It logs to my_service.log, but not to my.log.

Is there possibility to achieve what I want?

like image 688
Wirone Avatar asked Feb 19 '15 14:02

Wirone


People also ask

What are the different levels of logs we can have in monolog?

Monolog log levels Monolog has the following log levels: DEBUG - detailed debug information. INFO - interesting events. NOTICE - normal but significant events.

How do I write logs in a separate file?

- Create a new appender by copying the FILE appender and change the name and path according to the requirement. - Add a threshold parameter to the new appender with the value set to the level to be logged. This will mean that all entries having this log level and above will be written into the file.


1 Answers

Channels in monolog works exactly like you want. Sample monolog configuration

app/config.yml

monolog:
  channels: ['deletion']
  handlers:
    main:
        type:         fingers_crossed
        action_level: error
        handler:      grouped_main
        formatter: "monolog.formatter.request"
        buffer_size: 30
#        if you will set stop_buffering: true - you will get ALL events after first error. It could produce huge logs for console
        stop_buffering: false

#   this is for getsentry.com error catching
    sentry:
        type:  raven
        dsn:   '%sentry_url%'
        level: notice

    # Groups
    grouped_main:
        type:    group
        members: [sentry, streamed_main, streamed_main_brief]

    # Streams
    streamed_main:
        type:  stream
        path:  "%kernel.logs_dir%/%kernel.environment%.log"

    streamed_main_brief:
        type:  stream
        path:  "%kernel.logs_dir%/%kernel.environment%_brief.log"
        formatter: monolog.brief_formatter

    console:
        type: console
        formatter: monolog.console_formatter

    deletion:
         # log deletion related messages
        level:    debug
        type:     stream
        path:     '%kernel.logs_dir%/deletion.log'
        channels: ['deletion']
        formatter: monolog.brief_formatter

services:
    my_service:
        class: Monolog\Processor\IntrospectionProcessor
        tags:
            - { name: monolog.processor }
    monolog.console_formatter:
        class: Symfony\Bridge\Monolog\Formatter\ConsoleFormatter
        arguments:
            - "<fg=black;bg=green>[%%datetime%%]</fg=black;bg=green> %%start_tag%%%%message%%%%end_tag%%\n"
    monolog.brief_formatter:
        class: Monolog\Formatter\LineFormatter
        arguments:
            - "[%%datetime%%] %%message%%\n"
#            default format is
#            - "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"        

If you will add code like

$this->getContainer()->get("logger")->info("Sample info");
$this->getContainer()->get("monolog.logger.deletion")->info("Deletion channel info");
$this->getContainer()->get("monolog.logger.deletion")->error("Deletion channel error");
$this->getContainer()->get("monolog.logger.deletion")->info("Deletion channel info #2");

You will get 3 log files with such a content

Channel log file

deletion.log
[2016-11-11 12:43:18] Deletion channel info
[2016-11-11 12:43:18] Deletion channel error
[2016-11-11 12:43:19] Deletion channel info #2

Default env log file

dev.log
[2016-11-11 12:43:18] event.DEBUG: Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure". [] {"file":"...."}
[2016-11-11 12:43:18] event.DEBUG: Notified event "console.command" to listener "Symfony\Bridge\Monolog\Handler\ConsoleHandler::onCommand". [] {"file":"...."}
[2016-11-11 12:43:18] app.INFO: Sample info [] {"file":"..."}
[2016-11-11 12:43:18] deletion.INFO: Deletion channel info [] {"file":"...."}
[2016-11-11 12:43:18] deletion.ERROR: Deletion channel error [] {"...."}

Brief env.log

[2016-11-11 12:43:18] Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure".
[2016-11-11 12:43:18] Notified event "console.command" to listener "Symfony\Bridge\Monolog\Handler\ConsoleHandler::onCommand".
[2016-11-11 12:43:18] Sample info
[2016-11-11 12:43:18] Deletion channel info
[2016-11-11 12:43:18] Deletion channel error

Also notice, that because of stop_buffering: false notice after error will not appear at dev.log, dev_brief.log, but will appear at deletion.log

And you should try sentry - its great product and his owners are cool guys :)

like image 174
Andrew Zhilin Avatar answered Oct 23 '22 14:10

Andrew Zhilin