First working version

This commit is contained in:
Tim 2019-05-24 16:40:34 +02:00
parent c2fe05b827
commit 92f9445633
2 changed files with 406 additions and 0 deletions

187
Entity/LogEntry.php Normal file
View File

@ -0,0 +1,187 @@
<?php
namespace App\Ardent\LoggerBundle\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="logger_bundle_log_entries")
* @ORM\HasLifecycleCallbacks
*/
class LogEntry
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $message;
/**
* @ORM\Column(type="array")
*/
private $context;
/**
* @ORM\Column(type="integer")
*/
private $level;
/**
* @ORM\Column(type="string")
*/
private $levelName;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $channel;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\PrePersist
*/
public function onPrePersist()
{
$this->createdAt = new DateTime();
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
* @return LogEntry
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @return mixed
*/
public function getMessage()
{
return $this->message;
}
/**
* @param mixed $message
* @return LogEntry
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* @return mixed
*/
public function getContext()
{
return $this->context;
}
/**
* @param mixed $context
* @return LogEntry
*/
public function setContext($context)
{
$this->context = $context;
return $this;
}
/**
* @return mixed
*/
public function getLevel()
{
return $this->level;
}
/**
* @param mixed $level
* @return LogEntry
*/
public function setLevel($level)
{
$this->level = $level;
return $this;
}
/**
* @return mixed
*/
public function getLevelName()
{
return $this->levelName;
}
/**
* @param mixed $levelName
* @return LogEntry
*/
public function setLevelName($levelName)
{
$this->levelName = $levelName;
return $this;
}
/**
* @return mixed
*/
public function getChannel()
{
return $this->channel;
}
/**
* @param mixed $channel
* @return LogEntry
*/
public function setChannel($channel)
{
$this->channel = $channel;
return $this;
}
/**
* @return mixed
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param mixed $createdAt
* @return LogEntry
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
}

219
Service/LoggerService.php Normal file
View File

@ -0,0 +1,219 @@
<?php
namespace App\Ardent\LoggerBundle\Service;
use App\Ardent\LoggerBundle\Entity\LogEntry;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use phpDocumentor\Reflection\Types\This;
use Psr\Log\InvalidArgumentException;
class LoggerService
{
/**
* Detailed debug information
*/
const DEBUG = 100;
/**
* Interesting events
*
* Examples: User logs in, SQL logs.
*/
const INFO = 200;
/**
* Uncommon events
*/
const NOTICE = 250;
/**
* Exceptional occurrences that are not errors
*
* Examples: Use of deprecated APIs, poor use of an API,
* undesirable things that are not necessarily wrong.
*/
const WARNING = 300;
/**
* Runtime errors
*/
const ERROR = 400;
/**
* Critical conditions
*
* Example: Application component unavailable, unexpected exception.
*/
const CRITICAL = 500;
/**
* Action must be taken immediately
*
* Example: Entire website down, database unavailable, etc.
* This should trigger the SMS alerts and wake you up.
*/
const ALERT = 550;
/**
* Urgent alert.
*/
const EMERGENCY = 600;
/**
* Logging levels from syslog protocol defined in RFC 5424
*
* @var array $levels Logging levels
*/
protected static $levels = array(
self::DEBUG => 'DEBUG',
self::INFO => 'INFO',
self::NOTICE => 'NOTICE',
self::WARNING => 'WARNING',
self::ERROR => 'ERROR',
self::CRITICAL => 'CRITICAL',
self::ALERT => 'ALERT',
self::EMERGENCY => 'EMERGENCY',
);
private $name;
/**
* @var EntityManagerInterface
*/
private $em;
/**
* LoggerService constructor.
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
$this->name = "";
$this->em = $em;
}
public function addNotice($message, $context = [])
{
return $this->addRecord(self::NOTICE, $message, $context);
}
public function addWarning($message, $context = [])
{
return $this->addRecord(self::WARNING, $message, $context);
}
public function addError($message, $context = [])
{
return $this->addRecord(self::ERROR, $message, $context);
}
/**
* Adds a log record.
*
* @param int $level The logging level
* @param string $message The log message
* @param array $context The log context
*
* @return bool Whether the record has been processed
*/
public function addRecord($level, $message, $context = [])
{
$levelName = static::getLevelName($level);
if( $level > self::WARNING) {
$context += $this->automaticContext();
}
$logEntry = (new LogEntry())
->setMessage((string) $message)
->setContext($context)
->setLevel($level)
->setLevelName($levelName)
->setChannel($this->name)
;
$this->em->persist($logEntry);
$this->em->flush();
return true;
}
private function automaticContext()
{
$classFilters = [
'Ardent\LoggerBundle\Service\LoggerService',
'HttpKernel\Kernel',
'HttpKernel\HttpKernel',
];
$backtraces = debug_backtrace();
$context = [];
$traces = 0;
foreach ($backtraces as $trace) {
$skip = false;
foreach ($classFilters as $class) {
if(strpos($trace['class'], $class)) {
$skip = true;
}
}
if($skip) {
continue;
}
$context[] = "function[$traces]: ".$trace['function'];
$context[] = "class[$traces]: ".$trace['class'];
++$traces;
}
return $context;
}
public function getLatest($level = self::DEBUG, $amount = 1)
{
$qb = $this->em->createQueryBuilder();
$qb
->select('l')
->from('ArdentLoggerBundle:LogEntry', 'l')
->where($qb->expr()->gte('l.level', '?1'))
->orderBy('l.createdAt', 'DESC')
->setParameter(1, $level)
->setMaxResults($amount);
;
return $qb->getQuery()->getResult();
}
/**
* Gets the name of the logging level.
*
* @param int $level
* @return string
*/
public static function getLevelName($level)
{
if (!isset(static::$levels[$level])) {
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
}
return static::$levels[$level];
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
* @return LoggerService
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
}