2015-02-19 13 views
5

Mam pewne problemy z konfiguracją Monolog do obsługi "zagnieżdżonych rejestratorów".Monolog: zapisz różne kanały i wiele programów obsługi do zgrupowanego pliku dziennika + dedykowane pliki dziennika

Co chcę zrobić:

Zaloguj z usług dedykowanych do plików (jeden za usługi) I ze wszystkich usług do jednego pliku. Każdy rejestrator powinien być również obsługiwany przez monolog.handlers.console.

Dlaczego chcę zrobić

Każda usługa ma logiki, ale można korzystać z innych usług z DI. Chcę wiedzieć, co dokładnie loguje jedna usługa, więc potrzebuję dedykowanego programu rejestrującego (z niestandardowym kanałem i niestandardowym plikiem dziennika) dla każdej usługi. Ale gdy usługi polegają na innych usługach, chcę czytać logi w porządku chronologicznym w jednym pliku.

Co mam

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 } 

To nie działa zgodnie z oczekiwaniami. Loguje się do my_service.log, ale nie do my.log.

Czy jest możliwość osiągnięcia tego, czego chcę?

+0

Czy rozwiązałeś problem? –

+0

Jeszcze nie, nie miałem wystarczająco czasu, aby z nim eksperymentować. – Wirone

+0

To nie rozwiąże problemu, ale może zaoszczędzić trochę czasu i poprawić obsługę logowań, spróbuj https://www.loggly.com/ – lchachurski

Odpowiedz

4

Kanały w monologu działają dokładnie tak, jak chcesz. konfiguracja

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"   

monolog próbka Jeśli dodasz kod jak

$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"); 

Dostaniesz 3 pliki dziennika z taką zawartością

plik dziennika Kanał

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 

domyślna dziennika env plik

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 

również zauważyć, że z powodu stop_buffering: fałszywe zawiadomienie po błędzie nie pojawi się dev.log, dev_brief.log, ale pojawi się deletion.log

I powinieneś spróbować sentry - jego świetny produkt, a jego właściciele to fajni faceci :)

+0

Tak, pomyślałem, że byłoby lepiej użyć konfiguracji MonologBundle (procedury obsługi z kanałami zdefiniowanymi), ale pod warunkiem, że DI config już tam był (istniejąca aplikacja, poprzedni programista miał własne konwencje) i nie chciałem jej tak dużo. Ale wydaje się, że to tylko sposób. Bardzo dziękuję za twój przykład, spróbuję (czeka nas kwestia dotycząca refaktoryzacji rejestratorów). – Wirone

+0

Po naprawdę długim czasie udało mi się w końcu zrestrukturyzować nasze rejestratory za pomocą konfiguracji MonologBundle i tak, wszystko można osiągnąć za pomocą stosu uchwytów. Nie jest to czasami intuicyjne, ale wiele programów obsługi, procesorów i formaterów jest gotowych do użycia, dzięki czemu każdy rekord dziennika może być wyświetlany w dowolnym miejscu. Dzięki. – Wirone