Od jakiegoś czasu bawię się z S2 i dzisiaj napotkałem problem, którego nie mogę przeskoczyć.
Tak jak w temacie - staram się zrobić zapis logów 400 i 500 w bazie. Znalazłem kilka tutków w necie jak tworzyć logi w plikach, jak wysyłać mailem ale nie trafiłem na konkretny opisujący zapis w bazie :/.
Mam gdzieś z netu przykład ale nie działa :/.
service.yml
parameters: logger_database.class: Tools\LogBundle\Logger\DatabaseHandler services: monolog.processor.request: class: Tools\LogBundle\Processor\RequestProcessor arguments: [ '@session' ] tags: - { name: monolog.processor, method: processRecord } - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest} logger_database: class: %logger_database.class% calls: - [ setContainer, [ '@service_container' ] ] tools.backtrace_logger_listener: class: Tools\LogBundle\EventListener\BacktraceLoggerListener tags: - {name: "monolog.logger", channel: "backtrace"} - {name: "kernel.event_listener", event: "kernel.exception", method: "onKernelException"} arguments: - '@logger'
config.yml
monolog: handlers: main: type: service level: error id: logger_database formatter: monolog.processor.request
Request processor.php
namespace Tools\LogBundle\Processor; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Bridge\Monolog\Processor\WebProcessor; class RequestProcessor extends WebProcessor { private $_session; public function __construct(Session $session) { $this->_session = $session; } { $record['extra']['serverData'] = ""; foreach ($this->serverData as $key => $value) { } $record['extra']['serverData'] .= $key . ": " . $value . "\n"; } } foreach ($_SERVER as $key => $value) { } $record['extra']['serverData'] .= $key . ": " . $value . "\n"; } return $record; } }
BacktraceLoggerListener.php
namespace Tools\LogBundle\EventListener; use Symfony\Component\HttpKernel\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; class BacktraceLoggerListener { private $_logger; public function __construct(LoggerInterface $logger = null) { $this->_logger = $logger; } public function onKernelException(GetResponseForExceptionEvent $event) { $this->_logger->addError($event->getException()); } }
DatabaseHandler.php
<?php namespace Tools\LogBundle\Logger; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; /** * Stores to database * */ class DatabaseHandler extends AbstractProcessingHandler { protected $_container; /** * @param string $stream * @param integer $level The minimum logging level at which this handler will be triggered * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($level = Logger::DEBUG, $bubble = true) { parent::__construct($level, $bubble); } /** * * @param type $container */ public function setContainer($container) { $this->_container = $container; } /** * {@inheritdoc} */ { // Ensure the doctrine channel is ignored (unless its greater than a warning error), otherwise you will create an infinite loop, as doctrine like to log.. a lot.. if( 'doctrine' == $record['channel'] ) { if( (int)$record['level'] >= Logger::WARNING ) { } return; } if( (int)$record['level'] >= Logger::WARNING ) { try { // Logs are inserted as separate SQL statements, separate to the current transactions that may exist within the entity manager. $em = $this->_container->get('doctrine')->getEntityManager(); $conn = $em->getConnection(); $serverData = $record['extra']['serverData']; $stmt = $em->getConnection()->prepare('INSERT INTO system_log(log, level, serverData, modified, created) VALUES(' . $conn->quote($record['message']) . ', \'' . $record['level'] . '\', ' . $conn->quote($serverData) . ', \'' . $created . '\', \'' . $created . '\');'); $stmt->execute(); } catch( \Exception $e ) { // Fallback to just writing to php error logs if something really bad happens } } } }
Problem w powyższym przykładzie jest taki, że dostaję komunikat:
Catchable Fatal Error: Argument 1 passed to Monolog\Handler\AbstractHandler::setFormatter() must implement interface Monolog\Formatter\FormatterInterface, instance of Tools\LogBundle\Processor\RequestProcessor given,
Wiem co on oznacza ale niestety nie potrafię rozwiązać tego problemu. Nie do konca rozgrysłem jeszcze ten mechanizm (kernel listenery itp) w S2.
Czy zapisuje ktoś z Was logi w ten sposób? Może ma ktoś jakiś ciekawy link do tutka ?
Będę wdzięczny za jakiekolwiek pokierowanie.
Pozdrawiam serdecznie.