Closed kristofvc closed 12 years ago
Yes you should use the DBAL directly to avoid this recursive logging of a log of a log... So you can do something like:
$conn = $this->container->get('doctrine')->getEntityManager()->getConnection();
$conn->executeQuery('INSERT INTO log table (a, b, c) VALUES (?, ?, ?)', array($a, $b, $c));
You can also look at this for inspiration: https://github.com/Seldaek/monolog/blob/master/doc/extending.md
I tried that already, same error. Also tried to push a nullhandler to the logger before the persist and push, and pop it afterwards. But also, same error. Any other suggestions?
Oh right, executeQuery won't work since it logs. You can call getWrappedConnection() on the connection, and that will give you the raw PDO instance with which you can work.
The NullHandler should work IMO, but I guess I'm overlooking something that makes it fail..
you need to use a separate DBAL connection for which you disable the logging of queries
Using the raw PDO object will work too.. no need to connect twice to the DB.
I'm trying to acheave what you have describe but I get a ServiceCircularReferenceException:
Circular reference detected for service "doctrine.dbal.default_connection", path: "doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> doctrine.dbal.logger -> monolog.logger.doctrine -> my.monologhandler.pdo -> doctrine.dbal.default.wrapped_connection".
I think this is more a Symfony2 DIC related issue (as there is no Logger left in my doctrine.dbal.default.wrapped_connection, the Exception should not be thrown) but maybe this example can help.
The documentation miss a point: reusing an existing DBAL connection, and I think it's realy important.
doctrine.dbal.default.wrapped_connection:
factory_service: doctrine.dbal.default_connection
factory_method: getWrappedConnection
class: PDO
my.monologhandler.pdo:
class: sojeans\BackBundle\Monolog\Handler\PDOHandler
arguments:
- '@doctrine.dbal.default.wrapped_connection'
tags:
- { name: log_handler }
Any idea on how we can solve (and then document all over the web) this issue?
there is a circular reference here: you need to create the doctrine.dbal.default_connection
service to create the doctrine.dbal.default.wrapped_connection`` (as it is used a factory service) and this service uses the logger.
btw, I don't think you should use the same connection: it would put your logging queries inside the transactions, meaning you would loose them when the transaction is rollbacked (which is generally the case where you need your logs)
I am getting circular reference error Can someone please explain how to create as mentioned above
doctrine.dbal.default_connection service to create the doctrine.dbal.default.wrapped_connection``
Hello, This is happening due to circular referencing caused by the $em->flush().
I have got this to work by adding the following code to only log messages coming from the 'app' channel. All others, including the ones caused by $em->flush() will be ignored.
protected function write(array $record){
if (!$this->initialized) {
$this->initialize();
}
# Only accept logs from the 'app' channel.
# Logs from other channels (e.g. request, security, event)
# will be ignored to avoid circular reference error on flush()
if ($record['channel'] !== 'app') {
return;
}
# the rest is the same ...
Alternatively, you can add the channel name in the config.yml:
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
doctrine:
type: service
id: kunstmaan_admin.handler.log
level: info
channels: [app]
Fully working example is here: http://www.inanzzz.com/index.php/post/53en/storing-symfony-log-messages-in-database-with-custom-monolog-handler
Great! Thank you! I've implemented it in a slightly different way, filtering out anything but the 'app' channel, and also have log rotation. Thanks!
On Tue, Nov 29, 2016 at 6:13 PM, BentCoder notifications@github.com wrote:
Fully working example is here: http://www.inanzzz.com/index. php/post/53en/storing-symfony-log-messages-in-database-with- custom-monolog-handler
ā You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Seldaek/monolog/issues/55#issuecomment-263730986, or mute the thread https://github.com/notifications/unsubscribe-auth/AAVMzUYbEpUh8ruHEP2ki3N1invT1WQfks5rDLGkgaJpZM4AAkIQ .
@BentCoder Thanks but not worked for Symfony 4.3.3
@BentCoder Thanks but not worked for Symfony 4.3.3
Well, you are nearly 3 years late :)
oh! :smile: I found the solution thanks
oh! š I found the solution thanks
@seddighi78 how you solved?
By creating a new Logger file in Logger/DatabaseLogger.php
with this code:
namespace App\Logger;
use Psr\Log\LoggerInterface;
class DatabaseLogger implements LoggerInterface
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* System is unusable.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function emergency($message, array $context = array())
{
$this->logger->emergency($message, $context);
}
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function alert($message, array $context = array())
{
$this->logger->alert($message, $context);
}
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function critical($message, array $context = array())
{
$this->logger->critical($message, $context);
}
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function error($message, array $context = array())
{
$this->logger->error($message, $context);
}
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function warning($message, array $context = array())
{
$this->logger->warning($message, $context);
}
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function notice($message, array $context = array())
{
$this->logger->notice($message, $context);
}
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function info($message, array $context = array())
{
$this->logger->info($message, $context);
}
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function debug($message, array $context = array())
{
$this->logger->debug($message, $context);
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
*
* @return void
*/
public function log($level, $message, array $context = array())
{
$this->logger->log($level, $message, $context);
}
}
And then register to services:
App\Logger\DatabaseLogger:
arguments: ['@monolog.logger.database']
So I wrote a custom handler in symfony2:
In my config I defined this handler:
and I add it to the monolog:
I get the following error:
Think this is because doctrine tries to write to the log, and I use doctrine to safe a logitem, etc.
Is there a way around?