diff --git a/src/Monolog/Handler/AbstractSyslogHandler.php b/src/Monolog/Handler/AbstractSyslogHandler.php new file mode 100644 index 00000000..3eb83bd4 --- /dev/null +++ b/src/Monolog/Handler/AbstractSyslogHandler.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\LineFormatter; + +/** + * Common syslog functionality + */ +abstract class AbstractSyslogHandler extends AbstractProcessingHandler +{ + protected $facility; + + /** + * Translates Monolog log levels to syslog log priorities. + */ + protected $logLevels = array( + Logger::DEBUG => LOG_DEBUG, + Logger::INFO => LOG_INFO, + Logger::NOTICE => LOG_NOTICE, + Logger::WARNING => LOG_WARNING, + Logger::ERROR => LOG_ERR, + Logger::CRITICAL => LOG_CRIT, + Logger::ALERT => LOG_ALERT, + Logger::EMERGENCY => LOG_EMERG, + ); + + /** + * List of valid log facility names. + */ + protected $facilities = array( + 'auth' => LOG_AUTH, + 'authpriv' => LOG_AUTHPRIV, + 'cron' => LOG_CRON, + 'daemon' => LOG_DAEMON, + 'kern' => LOG_KERN, + 'lpr' => LOG_LPR, + 'mail' => LOG_MAIL, + 'news' => LOG_NEWS, + 'syslog' => LOG_SYSLOG, + 'user' => LOG_USER, + 'uucp' => LOG_UUCP, + ); + + /** + * @param mixed $facility + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) + { + parent::__construct($level, $bubble); + + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->facilities['local0'] = LOG_LOCAL0; + $this->facilities['local1'] = LOG_LOCAL1; + $this->facilities['local2'] = LOG_LOCAL2; + $this->facilities['local3'] = LOG_LOCAL3; + $this->facilities['local4'] = LOG_LOCAL4; + $this->facilities['local5'] = LOG_LOCAL5; + $this->facilities['local6'] = LOG_LOCAL6; + $this->facilities['local7'] = LOG_LOCAL7; + } + + // convert textual description of facility to syslog constant + if (array_key_exists(strtolower($facility), $this->facilities)) { + $facility = $this->facilities[strtolower($facility)]; + } elseif (!in_array($facility, array_values($this->facilities), true)) { + throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); + } + + $this->facility = $facility; + } + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); + } +} diff --git a/src/Monolog/Handler/SyslogHandler.php b/src/Monolog/Handler/SyslogHandler.php index 924ccf47..47c73e12 100644 --- a/src/Monolog/Handler/SyslogHandler.php +++ b/src/Monolog/Handler/SyslogHandler.php @@ -12,7 +12,6 @@ namespace Monolog\Handler; use Monolog\Logger; -use Monolog\Formatter\LineFormatter; /** * Logs to syslog service. @@ -27,42 +26,10 @@ use Monolog\Formatter\LineFormatter; * * @author Sven Paulus */ -class SyslogHandler extends AbstractProcessingHandler +class SyslogHandler extends AbstractSyslogHandler { protected $ident; protected $logopts; - protected $facility; - - /** - * Translates Monolog log levels to syslog log priorities. - */ - private $logLevels = array( - Logger::DEBUG => LOG_DEBUG, - Logger::INFO => LOG_INFO, - Logger::NOTICE => LOG_NOTICE, - Logger::WARNING => LOG_WARNING, - Logger::ERROR => LOG_ERR, - Logger::CRITICAL => LOG_CRIT, - Logger::ALERT => LOG_ALERT, - Logger::EMERGENCY => LOG_EMERG, - ); - - /** - * List of valid log facility names. - */ - private $facilities = array( - 'auth' => LOG_AUTH, - 'authpriv' => LOG_AUTHPRIV, - 'cron' => LOG_CRON, - 'daemon' => LOG_DAEMON, - 'kern' => LOG_KERN, - 'lpr' => LOG_LPR, - 'mail' => LOG_MAIL, - 'news' => LOG_NEWS, - 'syslog' => LOG_SYSLOG, - 'user' => LOG_USER, - 'uucp' => LOG_UUCP, - ); /** * @param string $ident @@ -73,29 +40,10 @@ class SyslogHandler extends AbstractProcessingHandler */ public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID) { - parent::__construct($level, $bubble); - - if (!defined('PHP_WINDOWS_VERSION_BUILD')) { - $this->facilities['local0'] = LOG_LOCAL0; - $this->facilities['local1'] = LOG_LOCAL1; - $this->facilities['local2'] = LOG_LOCAL2; - $this->facilities['local3'] = LOG_LOCAL3; - $this->facilities['local4'] = LOG_LOCAL4; - $this->facilities['local5'] = LOG_LOCAL5; - $this->facilities['local6'] = LOG_LOCAL6; - $this->facilities['local7'] = LOG_LOCAL7; - } - - // convert textual description of facility to syslog constant - if (array_key_exists(strtolower($facility), $this->facilities)) { - $facility = $this->facilities[strtolower($facility)]; - } elseif (!in_array($facility, array_values($this->facilities), true)) { - throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); - } + parent::__construct($facility, $level, $bubble); $this->ident = $ident; $this->logopts = $logopts; - $this->facility = $facility; } /** @@ -116,12 +64,4 @@ class SyslogHandler extends AbstractProcessingHandler } syslog($this->logLevels[$record['level']], (string) $record['formatted']); } - - /** - * {@inheritdoc} - */ - protected function getDefaultFormatter() - { - return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); - } } diff --git a/src/Monolog/Handler/SyslogUdp/UdpSocket.php b/src/Monolog/Handler/SyslogUdp/UdpSocket.php index 3bf6c93e..d87ab9d3 100644 --- a/src/Monolog/Handler/SyslogUdp/UdpSocket.php +++ b/src/Monolog/Handler/SyslogUdp/UdpSocket.php @@ -15,7 +15,7 @@ class UdpSocket { const DATAGRAM_MAX_LENGTH = 2048; - public function __construct($ip, $port) + public function __construct($ip, $port = 514) { $this->ip = $ip; $this->port = $port; diff --git a/src/Monolog/Handler/SyslogUdpHandler.php b/src/Monolog/Handler/SyslogUdpHandler.php index e03cfa88..bfcb29ff 100644 --- a/src/Monolog/Handler/SyslogUdpHandler.php +++ b/src/Monolog/Handler/SyslogUdpHandler.php @@ -16,64 +16,30 @@ use Monolog\Handler\SyslogUdp\UdpSocket; /** * A Handler for logging to a remote syslogd server. - * Example usage (given you have a syslogd server on your local machine): - * - * $logger = new \Monolog\Logger(); - * $handler = new SyslogUdpHandler("local5", "127.0.0.1"); - * $handler->setFormatter(new \Monolog\Formatter\LineFormatter()); - * $logger->pushHandler($handler); - * $logger->warn("Hello from abroard!"); - * + * + * @author Jesper Skovgaard Nielsen */ - -class SyslogUdpHandler extends AbstractProcessingHandler +class SyslogUdpHandler extends AbstractSyslogHandler { - protected $facility; - - protected $facilities = array( - "local0" => 16, - "local1" => 17, - "local2" => 18, - "local3" => 19, - "local4" => 20, - "local5" => 21, - "local6" => 22, - "local7" => 23 - ); - - protected $severityMap = array( - Logger::EMERGENCY => 0, - Logger::ALERT => 1, - Logger::CRITICAL => 2, - Logger::ERROR => 3, - Logger::WARNING => 4, - Logger::NOTICE => 5, - Logger::INFO => 6, - Logger::DEBUG => 7 - ); - - public function __construct($facility, $syslogdIp, $port = null) + /** + * @param string $host + * @param int $port + * @param mixed $facility + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true) { - $port = is_null($port) ? 514 : $port; - $this->socket = new UdpSocket($syslogdIp, $port); + parent::__construct($facility, $level, $bubble); - $this->validateFacility($facility); - $this->facility = $this->facilities[$facility]; - - } - - protected function validateFacility($facility) - { - if (!is_string($facility) || !array_key_exists($facility, $this->facilities)) { - throw new \InvalidArgumentException("Invalid syslog facility: $facility"); - } + $this->socket = new UdpSocket($host, $port ?: 514); } protected function write(array $record) { $lines = $this->splitMessageIntoLines($record['formatted']); - $header = $this->makeCommonSyslogHeader($this->getSeverity($record['level'])); + $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]); foreach ($lines as $line) { $this->socket->write($line, $header); @@ -90,6 +56,7 @@ class SyslogUdpHandler extends AbstractProcessingHandler if (is_array($message)) { $message = implode("\n", $message); } + return preg_split('/$\R?^/m', $message); } @@ -98,20 +65,9 @@ class SyslogUdpHandler extends AbstractProcessingHandler */ protected function makeCommonSyslogHeader($severity) { - $priority = $severity + ($this->facility << 3); - return "<$priority>: "; - } + $priority = $severity + $this->facility; - /** - * Map the Monolog severity levels to syslogd. - */ - protected function getSeverity($priority) - { - if (array_key_exists($priority, $this->severityMap)) { - return $this->severityMap[$priority]; - } else { - return Logger::INFO; - } + return "<$priority>: "; } /** diff --git a/tests/Monolog/Handler/SyslogUdpHandlerTest.php b/tests/Monolog/Handler/SyslogUdpHandlerTest.php index 87c2693c..fcf9307a 100644 --- a/tests/Monolog/Handler/SyslogUdpHandlerTest.php +++ b/tests/Monolog/Handler/SyslogUdpHandlerTest.php @@ -7,16 +7,16 @@ use Monolog\TestCase; class SyslogUdpHandlerTest extends \PHPUnit_Framework_TestCase { /** - * @expectedException InvalidArgumentException + * @expectedException UnexpectedValueException */ public function testWeValidateFacilities() { - $handler = new SyslogUdpHandler("loiwjefoiwjef", "ip"); + $handler = new SyslogUdpHandler("ip", null, "invalidFacility"); } public function testWeSplitIntoLines() { - $handler = new SyslogUdpHandler("local5", "127.0.0.1"); + $handler = new SyslogUdpHandler("127.0.0.1", 514, "local5"); $handler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter()); $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol'));