1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10namespace Zend\Log\Writer; 11 12use Traversable; 13use Zend\Log\Exception; 14use Zend\Log\Formatter\Simple as SimpleFormatter; 15use Zend\Log\Logger; 16 17/** 18 * Writes log messages to syslog 19 */ 20class Syslog extends AbstractWriter 21{ 22 /** 23 * Maps Zend\Log priorities to PHP's syslog priorities 24 * 25 * @var array 26 */ 27 protected $priorities = array( 28 Logger::EMERG => LOG_EMERG, 29 Logger::ALERT => LOG_ALERT, 30 Logger::CRIT => LOG_CRIT, 31 Logger::ERR => LOG_ERR, 32 Logger::WARN => LOG_WARNING, 33 Logger::NOTICE => LOG_NOTICE, 34 Logger::INFO => LOG_INFO, 35 Logger::DEBUG => LOG_DEBUG, 36 ); 37 38 /** 39 * The default log priority - for unmapped custom priorities 40 * 41 * @var string 42 */ 43 protected $defaultPriority = LOG_NOTICE; 44 45 /** 46 * Last application name set by a syslog-writer instance 47 * 48 * @var string 49 */ 50 protected static $lastApplication; 51 52 /** 53 * Last facility name set by a syslog-writer instance 54 * 55 * @var string 56 */ 57 protected static $lastFacility; 58 59 /** 60 * Application name used by this syslog-writer instance 61 * 62 * @var string 63 */ 64 protected $appName = 'Zend\Log'; 65 66 /** 67 * Facility used by this syslog-writer instance 68 * 69 * @var int 70 */ 71 protected $facility = LOG_USER; 72 73 /** 74 * Types of program available to logging of message 75 * 76 * @var array 77 */ 78 protected $validFacilities = array(); 79 80 /** 81 * Constructor 82 * 83 * @param array $params Array of options; may include "application" and "facility" keys 84 * @return Syslog 85 */ 86 public function __construct($params = null) 87 { 88 if ($params instanceof Traversable) { 89 $params = iterator_to_array($params); 90 } 91 92 $runInitializeSyslog = true; 93 94 if (is_array($params)) { 95 parent::__construct($params); 96 97 if (isset($params['application'])) { 98 $this->appName = $params['application']; 99 } 100 101 if (isset($params['facility'])) { 102 $this->setFacility($params['facility']); 103 $runInitializeSyslog = false; 104 } 105 } 106 107 if ($runInitializeSyslog) { 108 $this->initializeSyslog(); 109 } 110 111 if ($this->formatter === null) { 112 $this->setFormatter(new SimpleFormatter('%message%')); 113 } 114 } 115 116 /** 117 * Initialize values facilities 118 * 119 * @return void 120 */ 121 protected function initializeValidFacilities() 122 { 123 $constants = array( 124 'LOG_AUTH', 125 'LOG_AUTHPRIV', 126 'LOG_CRON', 127 'LOG_DAEMON', 128 'LOG_KERN', 129 'LOG_LOCAL0', 130 'LOG_LOCAL1', 131 'LOG_LOCAL2', 132 'LOG_LOCAL3', 133 'LOG_LOCAL4', 134 'LOG_LOCAL5', 135 'LOG_LOCAL6', 136 'LOG_LOCAL7', 137 'LOG_LPR', 138 'LOG_MAIL', 139 'LOG_NEWS', 140 'LOG_SYSLOG', 141 'LOG_USER', 142 'LOG_UUCP' 143 ); 144 145 foreach ($constants as $constant) { 146 if (defined($constant)) { 147 $this->validFacilities[] = constant($constant); 148 } 149 } 150 } 151 152 /** 153 * Initialize syslog / set application name and facility 154 * 155 * @return void 156 */ 157 protected function initializeSyslog() 158 { 159 static::$lastApplication = $this->appName; 160 static::$lastFacility = $this->facility; 161 openlog($this->appName, LOG_PID, $this->facility); 162 } 163 164 /** 165 * Set syslog facility 166 * 167 * @param int $facility Syslog facility 168 * @return Syslog 169 * @throws Exception\InvalidArgumentException for invalid log facility 170 */ 171 public function setFacility($facility) 172 { 173 if ($this->facility === $facility) { 174 return $this; 175 } 176 177 if (!count($this->validFacilities)) { 178 $this->initializeValidFacilities(); 179 } 180 181 if (!in_array($facility, $this->validFacilities)) { 182 throw new Exception\InvalidArgumentException( 183 'Invalid log facility provided; please see http://php.net/openlog for a list of valid facility values' 184 ); 185 } 186 187 if ('WIN' == strtoupper(substr(PHP_OS, 0, 3)) 188 && ($facility !== LOG_USER) 189 ) { 190 throw new Exception\InvalidArgumentException( 191 'Only LOG_USER is a valid log facility on Windows' 192 ); 193 } 194 195 $this->facility = $facility; 196 $this->initializeSyslog(); 197 return $this; 198 } 199 200 /** 201 * Set application name 202 * 203 * @param string $appName Application name 204 * @return Syslog 205 */ 206 public function setApplicationName($appName) 207 { 208 if ($this->appName === $appName) { 209 return $this; 210 } 211 212 $this->appName = $appName; 213 $this->initializeSyslog(); 214 return $this; 215 } 216 217 /** 218 * Close syslog. 219 * 220 * @return void 221 */ 222 public function shutdown() 223 { 224 closelog(); 225 } 226 227 /** 228 * Write a message to syslog. 229 * 230 * @param array $event event data 231 * @return void 232 */ 233 protected function doWrite(array $event) 234 { 235 if (array_key_exists($event['priority'], $this->priorities)) { 236 $priority = $this->priorities[$event['priority']]; 237 } else { 238 $priority = $this->defaultPriority; 239 } 240 241 if ($this->appName !== static::$lastApplication 242 || $this->facility !== static::$lastFacility 243 ) { 244 $this->initializeSyslog(); 245 } 246 247 $message = $this->formatter->format($event); 248 249 syslog($priority, $message); 250 } 251} 252