Exemplo n.º 1
0
 /**
  * 取得日志分析类装载期
  * 
  * @return Zend_Loader_PluginLoader
  */
 public static function getLogLoader()
 {
     if (null === self::$_loader) {
         self::$_loader = new Zend_Loader_PluginLoader(array('ZtChart_Model_Monitor_Log_' => realpath(__DIR__ . '/Log')));
     }
     return self::$_loader;
 }
Exemplo n.º 2
0
 /**
  * 取得所有的日志分类统计数据
  * 
  * @param array $logPaths
  * @param string $pattern
  * @return array
  */
 public function getCategory($logPaths, $pattern)
 {
     $stats = array();
     foreach ($this->getObjectFiles($logPaths, $pattern) as $objectFile) {
         fprintf(STDOUT, "读取文件:%s (%d Byte)...", $objectFile, filesize($objectFile));
         $sedFile = $this->_sed($objectFile);
         fprintf(STDOUT, "过滤后文件:%s (%d Byte)...", $sedFile, filesize($sedFile));
         foreach (file($sedFile) as $no => $rawline) {
             try {
                 $mlog = new ZtChart_Model_Monitor_Log($rawline);
                 if (false !== ($lines = $mlog->category())) {
                     foreach ($lines as $identifier => $entry) {
                         if (!array_key_exists($identifier, $stats)) {
                             $stats[$identifier] = array();
                         }
                         foreach ($entry as $key => $value) {
                             if (!array_key_exists($key, $stats[$identifier])) {
                                 $stats[$identifier][$key] = 0;
                             }
                             $stats[$identifier][$key] += $value;
                         }
                     }
                 }
             } catch (ZtChart_Model_Monitor_Log_Exception $e) {
                 $this->_logger->warn("日志处理错误({$no}):" . iconv('GBK', 'UTF-8', $rawline));
             }
         }
         @unlink($sedFile);
         fprintf(STDOUT, " 完毕\n");
     }
     return $stats;
 }
Exemplo n.º 3
0
 /**
  * 监控日志文件
  * 
  * @param array $logPaths
  * @return void
  * @throws ZtChart_Model_Monitor_Exception
  */
 public function tail($logPaths)
 {
     if (($inotify = inotify_init()) === false) {
         throw new ZtChart_Model_Monitor_Daemon_Exception('Failed to obtain an inotify instance.');
     }
     $watchFiles = $watchDirs = array();
     foreach ($logPaths as $file) {
         if (($watch = inotify_add_watch($inotify, $file, IN_CREATE | IN_MODIFY)) === false) {
             throw new ZtChart_Model_Monitor_Daemon_Exception("Failed to watch file '{$file}'.");
         }
         if (is_file($file)) {
             if (false === ($fd = fopen($file, "r"))) {
                 throw new ZtChart_Model_Monitor_Daemon_Exception("File '{$file}' is not readable.");
             }
             $this->_ffseek($fd);
             $watchFiles[$watch] = $fd;
         } else {
             if (is_dir($file)) {
                 $watchFiles[$watch] = array();
                 $watchDirs[$watch] = $file;
             }
         }
     }
     while (($events = inotify_read($inotify)) !== false) {
         foreach ($events as $event) {
             if ($event['mask'] & IN_Q_OVERFLOW) {
                 throw new ZtChart_Model_Monitor_Daemon_Exception("The number of inotify queued events reaches upper limit.");
             }
             if (!$this->accept($event['name'])) {
                 continue;
             }
             if ($event['mask'] & (IN_CREATE | IN_MODIFY)) {
                 if (!($event['mask'] & IN_ISDIR)) {
                     if (!array_key_exists($event['name'], $watchFiles[$event['wd']])) {
                         $fn = $fd = null;
                         foreach ($watchFiles[$event['wd']] as $wfn => $wfd) {
                             if (strncasecmp($wfn, $event['name'], strpos($wfn, '.')) == 0) {
                                 $fn = $wfn;
                                 $fd = $wfd;
                                 break;
                             }
                         }
                         // 判断当前创建或修改的日志文件是否最新
                         if (strcasecmp($fn, $event['name']) < 0) {
                             if (is_resource($fd) && fclose($fd)) {
                                 unset($watchFiles[$event['wd']][$fn]);
                             }
                             $filename = $watchDirs[$event['wd']] . DIRECTORY_SEPARATOR . $event['name'];
                             if (false === ($fd = fopen($filename, "r"))) {
                                 $this->_logger->err("File '{$filename}' is not readable\n");
                                 continue;
                             }
                             if ($event['mask'] & IN_MODIFY) {
                                 $this->_ffseek($fd);
                             }
                             $watchFiles[$event['wd']][$event['name']] = $fd;
                         } else {
                             // 如果不是最新的日志文件(重写的上一个小时的日志文件),则不处理。
                             continue;
                         }
                     } else {
                         $fd = $watchFiles[$event['wd']][$event['name']];
                     }
                 } else {
                     continue;
                     // $fd = $watchFiles[$event['wd']];
                 }
                 // 读取日志并分析
                 $raw = '';
                 $lines = 0;
                 while (true) {
                     $raw .= $block = fread($fd, 4096);
                     if (false !== ($pos = strpos($raw, "\n"))) {
                         $rawline = substr($raw, 0, $pos + 1);
                         try {
                             $mlog = new ZtChart_Model_Monitor_Log($rawline);
                             $line = $mlog->transform();
                             if (!empty($line)) {
                                 $this->_shmWrite($mlog->getShmIdentifier(), $line);
                                 $lines++;
                             }
                         } catch (ZtChart_Model_Monitor_Log_Exception $e) {
                             $this->_logger->warn("日志处理错误:" . iconv('GBK', 'UTF-8', $rawline));
                         }
                         $raw = substr($raw, $pos + 1);
                     } else {
                         if (($offset = strlen($block)) > 0) {
                             fseek($fd, -$offset, SEEK_CUR);
                         }
                         break;
                     }
                 }
                 if (0 != $lines) {
                     $this->_logger->info(sprintf("%4s行有效数据已处理:%s", $lines, $watchDirs[$event['wd']] . '/' . $event['name']));
                 }
             }
         }
     }
     foreach ($watchFiles as $watch => $fd) {
         if (is_resource($fd)) {
             $fd = (array) $fd;
         }
         array_walk($fd, 'fclose');
         inotify_rm_watch($inotify, $watch);
     }
     fclose($inotify);
 }