fetus Diary

2008/08/21(木) - Zend_Log で syslog を使う

lib/Mondenkind/Log/Writer/Syslog/Resource.php:

<?php
    class Mondenkind_Log_Writer_Syslog_Resource {
        protected
            $prefix   = null,
            $option   = null,
            $facility = null;
        
        public function __construct($prefix, $option, $facility) {
            $option = ($option & ~(LOG_NDELAY | LOG_ODELAY)) | LOG_NDELAY;
            $this->prefix   = $prefix;
            $this->option   = $option;
            $this->facility = $facility;
        }
        
        public function write($string, $level) {
            if(!openlog($this->prefix, $this->option, $this->facility)) {
                throw new Zend_Log_Exception('Could not open syslog');
            }
            if(!syslog($string, $level)) {
                throw new Zend_Log_Exception('Could not write to syslog');
            }
            closelog();
        }
    }
?>

lib/Mondenkind/Log/Writer/Syslog.php:

<?php
    define_syslog_variables();
    
    class Mondenkind_Log_Writer_Syslog extends Zend_Log_Writer_Abstract {
        protected $_priority = array(Zend_Log::EMERG  => LOG_EMERG,
                                     Zend_Log::ALERT  => LOG_ALERT,
                                     Zend_Log::CRIT   => LOG_CRIT,
                                     Zend_Log::ERR    => LOG_ERR,
                                     Zend_Log::WARN   => LOG_WARNING,
                                     Zend_Log::NOTICE => LOG_NOTICE,
                                     Zend_Log::INFO   => LOG_INFO,
                                     Zend_Log::DEBUG  => LOG_DEBUG);
        protected $_syslog = null;
        
        public function __construct($prefix = NULL, $option = LOG_PID, $facility = LOG_USER) {
            $this->_syslog = new Mondenkind_Log_Writer_Syslog_Resource($prefix, $option, $facility);
            $this->_formatter = new Zend_Log_Formatter_Simple();
        }
        
        protected function _write($event) {
            $priority = array_key_exists($event['priority'], $this->_priority) ? $this->_priority[$event['priority']] : LOG_DEBUG;
            $this->_syslog->write($priority, $this->_formatter->format($event));
        }
    }
?>
<?php
    $log_writer = new Mondenkind_Log_Writer_Syslog('Mondenkind', LOG_PID, LOG_USER);
    $log_writer->setFormatter(new Zend_Log_Formatter_Simple('%priorityName%(%priority%): %message%'));
    $logger = new Zend_Log($log_writer);
    $logger->log('hoge', Zend_Log::ERROR);
?>

なぜデフォで装備(違)していないのだろう。

POSIX の syslog インタフェースを模しているから openlog() の戻り値が resource になっていなくて openlog(), syslog(), closelog() がつながっていないのだろうけど、

<?php
    define_syslog_variables();
    openlog('hoge', LOG_NDELAY|LOG_PID, LOG_USER);
    call_function();
    syslog(LOG_WARNING, 'hoge');

    function call_function() {
        openlog('fuga', LOG_NDELAY|LOG_PID, LOG_USER);
        syslog(LOG_WARNING, 'fuga');
    }
?>

こんな呼び出しをしたときに、'hoge' のほうが(たぶん書いた人の予想に反して)こんな出力になって悲しい。

Aug 21 23:59:59 SERVER fuga[3159]: fuga
Aug 21 23:59:59 SERVER fuga[3159]: hoge

普通、ident (上のロジック内では prefix)はプログラム名とかシステム名だから一つのプログラム中から変更することは無いだろうけど。

この辺を無駄に努力したのが Mondenkind_Log_Writer_Syslog_Resource だったりする。実際には気にしなくて良いと思うんだけどねぇ…。

コメント

コメントはありません。

名前
メール
コメント

※HTML タグは使えません。HTTP URL には自動リンクが張られます。

Captcha
画像から読み取れる文字を入力: