<?php namespace Library; /** * Logger trait to add logging functionality to a class. * If no logger is set all logging methods, error(), info(), etc. do nothing. * The context for a log message can be provided with the ndc_push() and ndc_pop methods. * NDC stands for Nested Diagnostic Context * * To use this trait add * use \Library\Logger; * at the begin of your class declaration. */ trait LoggerTrait { /** * PSR-3 compatible logger instance, if not set no logging is done * @var \Psr\Log\LoggerInterface */ protected $logger; /** * nested diagnostic context, used as context for log messages * @var array */ protected $ndc_context = []; /** * initialize logger * * @param array $settings with (optional) keys: name, handler, path, level and format * @param string $base_dir base directory for relative paths * @return $this */ public function init_logger(array $settings, string $base_dir = ".") { $name = isset($settings["name"]) ? $settings["name"] : "default"; // create the logger $logger = new \Monolog\Logger($name); // add handlers if (isset($settings["handler"])) { foreach ($settings["handler"] as $handler) { $this->add_handler($logger, $handler, $base_dir); } } else { // if no handler array the settings // then the handler parameters are in the settings (backward compatibility) $this->add_handler($logger, $settings, $base_dir); } return $this->set_logger($logger); } /** * initialize logger * * @param Monolog\Logger $logger logger instance * @param array $settings with (optional) keys: path, level and format * @param string $base_dir base directory for relative paths * @return $this */ protected function add_handler($logger, array $settings, string $base_dir) { $path = isset($settings["path"]) ? $settings["path"] : "php://stderr"; // adjust log path if it is not a php i/o stream or absolute path // so only adjust relative paths if (strncmp($path, 'php:', 4) != 0 && strncmp($path, '/', 1)) { $path = "$base_dir/$path"; } $level = isset($settings["level"]) ? $settings["level"] : "info"; $format = isset($settings["format"]) ? $settings["format"] : "[%datetime%] %channel% %level_name% %extra% %context%: %message%"; // add stream handler $stream = new \Monolog\Handler\StreamHandler($path, $level); $formatter = new \Monolog\Formatter\LineFormatter("$format\n"); $stream->setFormatter($formatter); $logger->pushHandler($stream); } /** * get logger instance * @return \Psr\Log\LoggerInterface or null if not set */ public function get_logger() { return $this->logger; } /** * set logger to send log messages to * @param \Psr\Log\LoggerInterface $logger * @return $this */ public function set_logger(\Psr\Log\LoggerInterface $logger) { $this->logger = $logger; return $this; } /** * debug message * @param string $message * @param array $context if not set the ndc is used * @return $this */ public function debug(string $message, array $context = null) { if (isset($this->logger)) { $this->logger->debug($message, isset($context) ? $context : $this->ndc_context); } return $this; } /** * info message * @param string $message * @param array $context if not set the ndc is used * @return $this */ public function info(string $message, array $context = null) { if (isset($this->logger)) { $this->logger->info($message, isset($context) ? $context : $this->ndc_context); } return $this; } /** * warning message * @param string $message * @param array $context if not set the ndc is used * @return $this */ public function warning(string $message, array $context = null) { if (isset($this->logger)) { $this->logger->warning($message, isset($context) ? $context : $this->ndc_context); } return $this; } /** * error message * @param string $message * @param array $context if not set the ndc is used * @return $this */ public function error(string $message, array $context = null) { if (isset($this->logger)) { $this->logger->error($message, isset($context) ? $context : $this->ndc_context); } return $this; } /** * add message to the ndc (nested diagnostic context) * @param string $message * @return $this */ public function ndc_push(string $message){ $this->ndc_context[] = $message; return $this; } /** * remove last message from the ndc (nested diagnostic context) * @return $this */ public function ndc_pop(){ array_pop($this->ndc_context); return $this; } }