      1: <?php
      2: /**
      3:  * Licensed to the Apache Software Foundation (ASF) under one or more
      4:  * contributor license agreements. See the NOTICE file distributed with
      5:  * this work for additional information regarding copyright ownership.
      6:  * The ASF licenses this file to You under the Apache License, Version 2.0
      7:  * (the "License"); you may not use this file except in compliance with
      8:  * the License. You may obtain a copy of the License at
      9:  *
     10:  *     http://www.apache.org/licenses/LICENSE-2.0
     11:  *
     12:  * Unless required by applicable law or agreed to in writing, software
     13:  * distributed under the License is distributed on an "AS IS" BASIS,
     14:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15:  * See the License for the specific language governing permissions and
     16:  * limitations under the License.
     17:  */
     18:
     19: /**
     20:  * Log events to a system log using the PHP syslog() function.
     21:  *
     22:  * This appenders requires a layout.
     23:  *
     24:  * ## Configurable parameters: ##
     25:  *
     26:  * - **ident** - The ident of the syslog message.
     27:  * - **priority** - The priority for the syslog message (used when overriding
     28:  *     priority).
     29:  * - **facility** - The facility for the syslog message
     30:  * - **overridePriority** - If set to true, the message priority will always
     31:  *     use the value defined in {@link $priority}, otherwise the priority will
     32:  *     be determined by the message's log level.
     33:  * - **option** - The option value for the syslog message.
     34:  *
     35:  * Recognised syslog options are:
     36:  *
     37:  * - CONS    - if there is an error while sending data to the system logger, write directly to the system console
     38:  * - NDELAY - open the connection to the logger immediately
     39:  * - ODELAY - delay opening the connection until the first message is logged (default)
     40:  * - PERROR - print log message also to standard error
     41:  * - PID    - include PID with each message
     42:  *
     43:  * Multiple options can be set by delimiting them with a pipe character,
     44:  * e.g.: "CONS|PID|PERROR".
     45:  *
     46:  * Recognised syslog priorities are:
     47:  *
     48:  * - EMERG
     49:  * - ALERT
     50:  * - CRIT
     51:  * - ERR
     52:  * - WARNING
     53:  * - NOTICE
     54:  * - INFO
     55:  * - DEBUG
     56:  *
     57:  * Levels are mapped as follows:
     58:  *
     59:  * - <b>FATAL</b> to LOG_ALERT
     60:  * - <b>ERROR</b> to LOG_ERR
     61:  * - <b>WARN</b> to LOG_WARNING
     62:  * - <b>INFO</b> to LOG_INFO
     63:  * - <b>DEBUG</b> to LOG_DEBUG
     64:  * - <b>TRACE</b> to LOG_DEBUG
     65:  *
     66:  * @version $Revision: 1337820 $
     67:  * @package log4php
     68:  * @subpackage appenders
     69:  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
     70:  * @link http://logging.apache.org/log4php/docs/appenders/syslog.html Appender documentation
     71:  */
     72: class LoggerAppenderSyslog extends LoggerAppender {
     73:
     74:     /**
     75:      * The ident string is added to each message. Typically the name of your application.
     76:      *
     77:      * @var string
     78:      */
     79:     protected $ident = "Apache log4php";
     80:
     81:     /**
     82:      * The syslog priority to use when overriding priority. This setting is
     83:      * required if {@link overridePriority} is set to true.
     84:      *
     85:      * @var string
     86:      */
     87:     protected $priority;
     88:
     89:     /**
     90:      * The option used when opening the syslog connection.
     91:      *
     92:      * @var string
     93:      */
     94:     protected $option = 'PID|CONS';
     95:
     96:     /**
     97:      * The facility value indicates the source of the message.
     98:      *
     99:      * @var string
    100:      */
    101:     protected $facility = 'USER';
    102:
    103:     /**
    104:      * If set to true, the message priority will always use the value defined
    105:      * in {@link $priority}, otherwise the priority will be determined by the
    106:      * message's log level.
    107:      *
    108:      * @var string
    109:      */
    110:     protected $overridePriority = false;
    111:
    112:     /**
    113:      * Holds the int value of the {@link $priority}.
    114:      * @var int
    115:      */
    116:     private $intPriority;
    117:
    118:     /**
    119:      * Holds the int value of the {@link $facility}.
    120:      * @var int
    121:      */
    122:     private $intFacility;
    123:
    124:     /**
    125:      * Holds the int value of the {@link $option}.
    126:      * @var int
    127:      */
    128:     private $intOption;
    129:
    130:     /**
    131:      * Sets the {@link $ident}.
    132:      *
    133:      * @param string $ident
    134:      */
    135:     public function setIdent($ident) {
    136:         $this->ident = $ident;
    137:     }
    138:
    139:     /**
    140:      * Sets the {@link $priority}.
    141:      *
    142:      * @param string $priority
    143:      */
    144:     public function setPriority($priority) {
    145:         $this->priority = $priority;
    146:     }
    147:
    148:     /**
    149:      * Sets the {@link $facility}.
    150:      *
    151:      * @param string $facility
    152:      */
    153:     public function setFacility($facility) {
    154:         $this->facility = $facility;
    155:     }
    156:
    157:     /**
    158:      * Sets the {@link $overridePriority}.
    159:      *
    160:      * @param string $overridePriority
    161:      */
    162:     public function setOverridePriority($overridePriority) {
    163:         $this->overridePriority = $overridePriority;
    164:     }
    165:
    166:     /**
    167:     * Sets the 'option' parameter.
    168:     *
    169:     * @param string $option
    170:     */
    171:     public function setOption($option) {
    172:         $this->option = $option;
    173:     }
    174:
    175:     /**
    176:     * Returns the 'ident' parameter.
    177:     *
    178:     * @return string $ident
    179:     */
    180:     public function getIdent() {
    181:         return $this->ident;
    182:     }
    183:
    184:     /**
    185:      * Returns the 'priority' parameter.
    186:      *
    187:      * @return string
    188:      */
    189:     public function getPriority() {
    190:         return $this->priority;
    191:     }
    192:
    193:     /**
    194:      * Returns the 'facility' parameter.
    195:      *
    196:      * @return string
    197:      */
    198:     public function getFacility() {
    199:         return $this->facility;
    200:     }
    201:
    202:     /**
    203:      * Returns the 'overridePriority' parameter.
    204:      *
    205:      * @return string
    206:      */
    207:     public function getOverridePriority() {
    208:         return $this->overridePriority;
    209:     }
    210:
    211:     /**
    212:      * Returns the 'option' parameter.
    213:      *
    214:      * @return string
    215:      */
    216:     public function getOption() {
    217:         return $this->option;
    218:     }
    219:
    220:
    221:     public function activateOptions() {
    222:         $this->intPriority = $this->parsePriority();
    223:         $this->intOption   = $this->parseOption();
    224:         $this->intFacility = $this->parseFacility();
    225:
    226:         $this->closed = false;
    227:     }
    228:
    229:     public function close() {
    230:         if($this->closed != true) {
    231:             closelog();
    232:             $this->closed = true;
    233:         }
    234:     }
    235:
    236:     /**
    237:      * Appends the event to syslog.
    238:      *
    239:      * Log is opened and closed each time because if it is not closed, it
    240:      * can cause the Apache httpd server to log to whatever ident/facility
    241:      * was used in openlog().
    242:      *
    243:      * @see http://www.php.net/manual/en/function.syslog.php#97843
    244:      */
    245:     public function append(LoggerLoggingEvent $event) {
    246:         $priority = $this->getSyslogPriority($event->getLevel());
    247:         $message = $this->layout->format($event);
    248:
    249:         openlog($this->ident, $this->intOption, $this->intFacility);
    250:         syslog($priority, $message);
    251:         closelog();
    252:     }
    253:
    254:     /** Determines which syslog priority to use based on the given level. */
    255:     private function getSyslogPriority(LoggerLevel $level) {
    256:         if($this->overridePriority) {
    257:             return $this->intPriority;
    258:         }
    259:         return $level->getSyslogEquivalent();
    260:     }
    261:
    262:     /** Parses a syslog option string and returns the correspodning int value. */
    263:     private function parseOption() {
    264:         $value = 0;
    265:         $options = explode('|', $this->option);
    266:
    267:         foreach($options as $option) {
    268:             if (!empty($option)) {
    269:                 $constant = "LOG_" . trim($option);
    270:                 if (defined($constant)) {
    271:                     $value |= constant($constant);
    272:                 } else {
    273:                     trigger_error("log4php: Invalid syslog option provided: $option. Whole option string: {$this->option}.", E_USER_WARNING);
    274:                 }
    275:             }
    276:         }
    277:         return $value;
    278:     }
    279:
    280:     /** Parses the facility string and returns the corresponding int value. */
    281:     private function parseFacility() {
    282:         if (!empty($this->facility)) {
    283:             $constant = "LOG_" . trim($this->facility);
    284:             if (defined($constant)) {
    285:                 return constant($constant);
    286:             } else {
    287:                 trigger_error("log4php: Invalid syslog facility provided: {$this->facility}.", E_USER_WARNING);
    288:             }
    289:         }
    290:     }
    291:
    292:     /** Parses the priority string and returns the corresponding int value. */
    293:     private function parsePriority() {
    294:         if (!empty($this->priority)) {
    295:             $constant = "LOG_" . trim($this->priority);
    296:             if (defined($constant)) {
    297:                 return constant($constant);
    298:             } else {
    299:                 trigger_error("log4php: Invalid syslog priority provided: {$this->priority}.", E_USER_WARNING);
    300:             }
    301:         }
    302:     }
    303: }
    304: