Skip to content

Commit

Permalink
Merge pull request #827 from bolt/feature/logging
Browse files Browse the repository at this point in the history
Feature: Add logs, including Log Viewer screen
  • Loading branch information
bobdenotter committed Jan 4, 2020
2 parents 687e356 + d52b58b commit 720bab9
Show file tree
Hide file tree
Showing 16 changed files with 623 additions and 34 deletions.
7 changes: 6 additions & 1 deletion config/packages/dev/monolog.yaml
@@ -1,4 +1,5 @@
monolog:
channels: ['db']
handlers:
main:
type: stream
Expand All @@ -14,6 +15,10 @@ monolog:
# type: chromephp
# level: info
console:
type: console
type: console
process_psr_3_messages: false
channels: ['!event', '!doctrine', '!console']
db:
channels: ['db']
type: service
id: Bolt\Log\LogHandler
7 changes: 6 additions & 1 deletion config/packages/prod/monolog.yaml
@@ -1,4 +1,5 @@
monolog:
channels: ['db']
handlers:
main:
type: fingers_crossed
Expand All @@ -10,6 +11,10 @@ monolog:
path: '%kernel.logs_dir%/%kernel.environment%.log'
level: debug
console:
type: console
type: console
process_psr_3_messages: false
channels: ['!event', '!doctrine']
db:
channels: ['db']
type: service
id: Bolt\Log\LogHandler
7 changes: 7 additions & 0 deletions config/packages/test/monolog.yaml
@@ -0,0 +1,7 @@
monolog:
channels: ['db']
handlers:
db:
channels: ['db']
type: service
id: Bolt\Log\LogHandler
7 changes: 6 additions & 1 deletion config/services.yaml
Expand Up @@ -69,7 +69,7 @@ services:
Bolt\Menu\BackendMenuBuilderInterface: '@Bolt\Menu\BackendMenuBuilder'

Bolt\Menu\FrontendMenuBuilder: ~

Bolt\Menu\FrontendMenuBuilderInterface: '@Bolt\Menu\FrontendMenuBuilder'

# Needed for SetContent from bolt/core
Expand All @@ -87,5 +87,10 @@ services:

Doctrine\ORM\Query\Expr: ~

monolog.processor.request:
class: Bolt\Log\RequestProcessor
tags:
- { name: monolog.processor, method: processRecord, handler: db }

Twig\Extension\StringLoaderExtension: ~

34 changes: 34 additions & 0 deletions src/Controller/Backend/LogViewerController.php
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Bolt\Controller\Backend;

use Bolt\Controller\TwigAwareController;
use Bolt\Repository\LogRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

/**
* @Security("is_granted('ROLE_ADMIN')")
*/
class LogViewerController extends TwigAwareController implements BackendZone
{
/**
* @Route("/logviewer", name="bolt_logviewer", methods={"GET"})
*/
public function index(LogRepository $log, Request $request): Response
{
$amount = $this->config->get('general/log/amount', 10);
$page = (int) $request->get('page', 1);

/** @var Log $items */
$items = $log->findLatest($page, $amount);

return $this->renderTemplate('@bolt/pages/logviewer.html.twig', [
'items' => $items,
]);
}
}
9 changes: 8 additions & 1 deletion src/Controller/Frontend/HomepageController.php
Expand Up @@ -7,6 +7,7 @@
use Bolt\Controller\TwigAwareController;
use Bolt\Repository\ContentRepository;
use Bolt\TemplateChooser;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

Expand All @@ -15,9 +16,13 @@ class HomepageController extends TwigAwareController implements FrontendZone
/** @var TemplateChooser */
private $templateChooser;

public function __construct(TemplateChooser $templateChooser)
/** @var LoggerInterface */
private $logger;

public function __construct(TemplateChooser $templateChooser, LoggerInterface $dbLogger)
{
$this->templateChooser = $templateChooser;
$this->logger = $dbLogger;
}

/**
Expand All @@ -40,6 +45,8 @@ public function homepage(ContentRepository $contentRepository): Response

$templates = $this->templateChooser->forHomepage();

$this->logger->notice('Huius, Lyco, oratione locuples, rebus ipsis ielunior. Quid autem habent admirationis, cum prope accesseris?!', ['foo' => 'bar']);

return $this->renderTemplate($templates, ['record' => $record]);
}
}
169 changes: 169 additions & 0 deletions src/Entity/Log.php
@@ -0,0 +1,169 @@
<?php

declare(strict_types=1);

namespace Bolt\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\LogRepository")
* @ORM\Table(name="log")
* @ORM\HasLifecycleCallbacks
*/
class Log
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\Column(name="message", type="text")
*/
private $message;

/**
* @ORM\Column(name="context", type="array", nullable=true)
*/
private $context;

/**
* @ORM\Column(name="level", type="smallint")
*/
private $level;

/**
* @ORM\Column(name="level_name", type="string", length=50)
*/
private $levelName;

/**
* @ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;

/**
* @ORM\Column(name="extra", type="array", nullable=true)
*/
private $extra;

/**
* @ORM\Column(name="user", type="array", nullable=true)
*/
private $user;

/**
* @ORM\Column(name="location", type="array", nullable=true)
*/
private $location;

/**
* @ORM\PrePersist
*/
public function onPrePersist(): void
{
$this->createdAt = new \DateTime();
}

public function getId(): int
{
return $this->id;
}

public function setId(int $id): self
{
$this->id = $id;
return $this;
}

public function getMessage(): string
{
return $this->message;
}

public function setMessage(string $message): self
{
$this->message = $message;
return $this;
}

public function getContext(): ?array
{
return $this->context;
}

public function setContext(?array $context): self
{
$this->context = $context;
return $this;
}

public function getLevel(): int
{
return $this->level;
}

public function setLevel(int $level): self
{
$this->level = $level;
return $this;
}

public function getLevelName(): string
{
return $this->levelName;
}

public function setLevelName(string $levelName): self
{
$this->levelName = $levelName;
return $this;
}

public function getExtra(): ?array
{
return $this->extra;
}

public function setExtra(?array $extra): self
{
$this->extra = $extra;
return $this;
}

public function getCreatedAt(): \DateTime
{
return $this->createdAt;
}

public function setCreatedAt(\DateTime $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}

public function getLocation(): ?array
{
return $this->location;
}

public function setLocation(?array $location): self
{
$this->location = $location;
return $this;
}

public function getUser(): ?array
{
return $this->user;
}

public function setUser(?array $user): self
{
$this->user = $user;
return $this;
}
}
41 changes: 41 additions & 0 deletions src/Log/LogHandler.php
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Bolt\Log;

use Bolt\Entity\Log;
use Doctrine\ORM\EntityManagerInterface;
use Monolog\Handler\AbstractProcessingHandler;

class LogHandler extends AbstractProcessingHandler
{
/**
* @var EntityManagerInterface
*/
protected $em;

public function __construct(EntityManagerInterface $em)
{
parent::__construct();
$this->em = $em;
}

/**
* Called when writing to our database
*/
protected function write(array $record): void
{
$logEntry = new Log();
$logEntry->setMessage($record['message']);
$logEntry->setLevel($record['level']);
$logEntry->setLevelName($record['level_name']);
$logEntry->setExtra($record['extra']);
$logEntry->setUser($record['user'] ?? null);
$logEntry->setLocation($record['location']);
$logEntry->setContext($record['context']);

$this->em->persist($logEntry);
$this->em->flush();
}
}

0 comments on commit 720bab9

Please sign in to comment.