date_now = date("Y-m-d"); $this->_fd_log = @fopen("logmonitor.log","a+"); $this->setInputFd() or exit("unable open file"); } public function __destruct() { @fclose($this->_fd_input); @fclose($this->_fd_log); } public function run_loop() { while (true) { if (!is_resource($this->_fd_input)) { $this->setInputFd(); usleep(1000); continue; } if (@feof($this->_fd_input)) { if (!$this->switchLogFile()) { $this->checkStat(); } usleep(1000); } $pos = @ftell($this->_fd_input); $this->setPtrPos($pos); $line = @fgets($this->_fd_input); if (!$line) continue; if ($line == "") continue; if (strpos($line, $this->_mark) === 0) continue; if ($this->DealLine($line) === -1) { @fseek($this->_fd_input, $this->_ptr_pos); continue; } @fseek($this->_fd_input, $this->_ptr_pos); $this->addMark(); @fgets($this->_fd_input); $pos = @ftell($this->_fd_input); $this->_ptr_pos = $pos; usleep(1); } } private function DealLine($str) { $str = trim($str); $pattern = "/USER_PATH:/"; $matched = preg_match_all($pattern, $str); if ($matched) { $data = Parser::parse($str); if (!empty($data)) { $this->log(date("Y-m-d h:i:s"). " deal a record: {$str}"); $mod = Model(); $insert = $this->formatData($data); $result = $mod->table('user_path')->insert($insert); if ($result) { return $result; } return -1; //未成功插入数据库 } } return 0; } private function formatData(array $data) { $ret = []; if (isset($data['session_id'])) { $ret['session_id'] = $data['session_id']; } if (isset($data['member_id'])) { $ret['member_id'] = intval($data['member_id']); } if (isset($data['time'])) { $ret['time'] = strtotime($data['time']); } if (isset($data['thread_id'])) { $ret['thread_id'] = intval($data['thread_id']); } if (isset($data['act'])) { $ret['act'] = $data['act']; } if (isset($data['op'])) { $ret['op'] = $data['op']; } if (isset($data['data'])) { $ret['data'] = $data['data']; } if (isset($data['from_act'])) { $ret['from_act'] = $data['from_act']; } if (isset($data['from_op'])) { $ret['from_op'] = $data['from_op']; } if (isset($data['from_data'])) { $ret['from_data'] = $data['from_data']; } if (isset($data['type'])) { $ret['type'] = $data['type']; } return $ret; } private function addMark() { if (@flock($this->_fd_input, LOCK_EX)) { //ftruncate($this->_fd_input, 0); @fwrite($this->_fd_input, $this->_mark); @fflush($this->_fd_input); @flock($this->_fd_input, LOCK_UN); } } private function checkStat() { $size_now = @fstat($this->_fd_input)['size']; if ($size_now != $this->_fsize) { $this->setInputFd(); } } private function resetPtrPos() { $this->setPtrPos(0); } private function setPtrPos($pos) { $this->_ptr_pos = intval($pos); } private function switchLogFile() { if (date("Y-m-d") > $this->date_now) { if ($this->setInputFd()) { $this->date_now = date("Y-m-d"); return true; } } return false; } private function setInputFd() { $date = date("Ymd"); $file_name = BASE_DATA_PATH. DS. 'log'. DS. $date. "-path.log"; file_exists($file_name) or die("{$file_name} 不存在!"); @fclose($this->_fd_input); $fd = @fopen($file_name, "r+"); if ($fd) { $this->input_fname = $file_name; $this->_fd_input = $fd; $this->_fsize = @fstat($this->_fd_input)['size']; $this->resetPtrPos(); return true; } return false; } private function log($msg) { //$msg .= "\r\n"; @fwrite($this->_fd_log, $msg); } } class Parser { public static function parse($str) { $params = []; $pattern_time_format = "/\d{4}\-\d{2}\-\d{2}\s+\d{2}\:\d{2}\:\d{2}/"; $matched = preg_match_all($pattern_time_format, $str, $matches); if ($matched) { if (isset($matches[0][0])) { $params['time'] = $matches[0][0]; } unset($matches); } $pattern_thead_id = "/^\[\d+/"; $matched = preg_match_all($pattern_thead_id, $str, $matches); if ($matched) { if (isset($matches[0][0])) { $params['thread_id'] = str_replace("[","", $matches[0][0]); } unset($matches); } $strings = substr($str, strpos($str, "content=") +8); $pairs = self::matchPairs($strings); if ($pairs) { foreach ($pairs as $pair) { $kv = explode("=", $pair); if ($kv[0] != "") { $params[$kv[0]] = $kv[1]; } } return $params; } return false; } private static function matchPairs($str) { $pattern = "/(\w+=[^\&]+)/i"; $matched = preg_match_all($pattern, $str, $matches); if ($matched) { return $matches[0]; } return false; } } function work_proc() { Base::run_util(); $monitor = new Monitor(); while (true) { $monitor->run_loop(); } } event\util::fork_worker('work_proc',1);