Reputation: 318
I have been creating an application with Symfony 4.2, I want to save all logs in database, I'm using MonologBundle.
Monolog.yml
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
I want to store data in database like this
How Can I do this with Symfony.
Upvotes: 4
Views: 8294
Reputation: 12740
You can achieve that by creating a custom monolog channel (e.g. doctrine_channel
) and handler (e.g. doctrine
) to go with it. Update the example below as per your needs.
Monolog configuration
monolog:
channels: [doctrine_channel]
handlers:
main:
...
channels: [... !doctrine_channel]
console:
...
channels: [... !doctrine_channel]
doctrine:
type: service
channels: [doctrine_channel]
id: app.logger.doctrine_handler
Service configuration
services:
app.logger.doctrine_handler:
class: App\Logger\DoctrineHandler
arguments:
- "@doctrine.orm.entity_manager"
DoctrineHandler
namespace App\Logger;
use App\Entity\Log;
use Doctrine\ORM\EntityManagerInterface;
use Monolog\Handler\AbstractProcessingHandler;
class DoctrineHandler extends AbstractProcessingHandler
{
private $initialized;
private $entityManager;
private $channel = 'doctrine_channel';
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct();
$this->entityManager = $entityManager;
}
protected function write(array $record)
{
if (!$this->initialized) {
$this->initialize();
}
if ($this->channel != $record['channel']) {
return;
}
$log = new Log();
$log->setMessage($record['message']);
$log->setLevel($record['level_name']);
$this->entityManager->persist($log);
$this->entityManager->flush();
}
private function initialize()
{
$this->initialized = true;
}
}
Result
mysql> SELECT * FROM log;
+----+----------+-----------+---------------------+
| id | message | level | created_at |
+----+----------+-----------+---------------------+
| 1 | Welcome! | INFO | 2019-02-07 19:00:00 |
| 2 | Go back! | WARNING | 2019-02-07 19:00:05 |
| 3 | Help! | EMERGENCY | 2019-02-07 19:00:10 |
+----+----------+-----------+---------------------+
3 rows in set (0.00 sec)
Then inject @monolog.logger.doctrine_channel
(type hinted LoggerInterface
) to your service or wherever you want to log something. This should work! Now, it is up to you to refactor/enhance as you wish.
Upvotes: 19