logmonitor.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: lionared
  5. * Date: 2018/8/30
  6. * Time: 下午2:51
  7. */
  8. require_once (BASE_ROOT_PATH . '/global.php');
  9. require_once (BASE_ROOT_PATH . '/fooder.php');
  10. require_once (BASE_ROOT_PATH . '/helper/event_looper.php');
  11. class Monitor
  12. {
  13. private $_ptr_pos = 0;
  14. private $_mark = "]";
  15. private $date_now;
  16. private $input_fname;
  17. private $_fsize;
  18. private $_fd_input;
  19. private $_fd_log;
  20. public function __construct()
  21. {
  22. $this->date_now = date("Y-m-d");
  23. $this->_fd_log = @fopen("logmonitor.log","a+");
  24. $this->setInputFd() or exit("unable open file");
  25. }
  26. public function __destruct()
  27. {
  28. @fclose($this->_fd_input);
  29. @fclose($this->_fd_log);
  30. }
  31. public function run_loop()
  32. {
  33. while (true)
  34. {
  35. if (!is_resource($this->_fd_input)) {
  36. $this->setInputFd();
  37. usleep(1000);
  38. continue;
  39. }
  40. if (@feof($this->_fd_input)) {
  41. if (!$this->switchLogFile()) {
  42. $this->checkStat();
  43. }
  44. usleep(1000);
  45. }
  46. $pos = @ftell($this->_fd_input);
  47. $this->setPtrPos($pos);
  48. $line = @fgets($this->_fd_input);
  49. if (!$line) continue;
  50. if ($line == "") continue;
  51. if (strpos($line, $this->_mark) === 0) continue;
  52. if ($this->DealLine($line) === -1) {
  53. @fseek($this->_fd_input, $this->_ptr_pos);
  54. continue;
  55. }
  56. @fseek($this->_fd_input, $this->_ptr_pos);
  57. $this->addMark();
  58. @fgets($this->_fd_input);
  59. $pos = @ftell($this->_fd_input);
  60. $this->_ptr_pos = $pos;
  61. usleep(1);
  62. }
  63. }
  64. private function DealLine($str)
  65. {
  66. $str = trim($str);
  67. $pattern = "/USER_PATH:/";
  68. $matched = preg_match_all($pattern, $str);
  69. if ($matched)
  70. {
  71. $data = Parser::parse($str);
  72. if (!empty($data)) {
  73. $this->log(date("Y-m-d h:i:s"). " deal a record: {$str}");
  74. $mod = Model();
  75. $insert = $this->formatData($data);
  76. $result = $mod->table('user_path')->insert($insert);
  77. if ($result) {
  78. return $result;
  79. }
  80. return -1; //未成功插入数据库
  81. }
  82. }
  83. return 0;
  84. }
  85. private function formatData(array $data)
  86. {
  87. $ret = [];
  88. if (isset($data['session_id'])) {
  89. $ret['session_id'] = $data['session_id'];
  90. }
  91. if (isset($data['member_id'])) {
  92. $ret['member_id'] = intval($data['member_id']);
  93. }
  94. if (isset($data['time'])) {
  95. $ret['time'] = strtotime($data['time']);
  96. }
  97. if (isset($data['thread_id'])) {
  98. $ret['thread_id'] = intval($data['thread_id']);
  99. }
  100. if (isset($data['act'])) {
  101. $ret['act'] = $data['act'];
  102. }
  103. if (isset($data['op'])) {
  104. $ret['op'] = $data['op'];
  105. }
  106. if (isset($data['data'])) {
  107. $ret['data'] = $data['data'];
  108. }
  109. if (isset($data['from_act'])) {
  110. $ret['from_act'] = $data['from_act'];
  111. }
  112. if (isset($data['from_op'])) {
  113. $ret['from_op'] = $data['from_op'];
  114. }
  115. if (isset($data['from_data'])) {
  116. $ret['from_data'] = $data['from_data'];
  117. }
  118. if (isset($data['type'])) {
  119. $ret['type'] = $data['type'];
  120. }
  121. return $ret;
  122. }
  123. private function addMark()
  124. {
  125. if (@flock($this->_fd_input, LOCK_EX)) {
  126. //ftruncate($this->_fd_input, 0);
  127. @fwrite($this->_fd_input, $this->_mark);
  128. @fflush($this->_fd_input);
  129. @flock($this->_fd_input, LOCK_UN);
  130. }
  131. }
  132. private function checkStat()
  133. {
  134. $size_now = @fstat($this->_fd_input)['size'];
  135. if ($size_now != $this->_fsize)
  136. {
  137. $this->setInputFd();
  138. }
  139. }
  140. private function resetPtrPos()
  141. {
  142. $this->setPtrPos(0);
  143. }
  144. private function setPtrPos($pos)
  145. {
  146. $this->_ptr_pos = intval($pos);
  147. }
  148. private function switchLogFile()
  149. {
  150. if (date("Y-m-d") > $this->date_now) {
  151. if ($this->setInputFd()) {
  152. $this->date_now = date("Y-m-d");
  153. return true;
  154. }
  155. }
  156. return false;
  157. }
  158. private function setInputFd()
  159. {
  160. $date = date("Ymd");
  161. $file_name = BASE_DATA_PATH. DS. 'log'. DS. $date. "-path.log";
  162. file_exists($file_name) or die("{$file_name} 不存在!");
  163. @fclose($this->_fd_input);
  164. $fd = @fopen($file_name, "r+");
  165. if ($fd) {
  166. $this->input_fname = $file_name;
  167. $this->_fd_input = $fd;
  168. $this->_fsize = @fstat($this->_fd_input)['size'];
  169. $this->resetPtrPos();
  170. return true;
  171. }
  172. return false;
  173. }
  174. private function log($msg)
  175. {
  176. //$msg .= "\r\n";
  177. @fwrite($this->_fd_log, $msg);
  178. }
  179. }
  180. class Parser
  181. {
  182. public static function parse($str)
  183. {
  184. $params = [];
  185. $pattern_time_format = "/\d{4}\-\d{2}\-\d{2}\s+\d{2}\:\d{2}\:\d{2}/";
  186. $matched = preg_match_all($pattern_time_format, $str, $matches);
  187. if ($matched) {
  188. if (isset($matches[0][0])) {
  189. $params['time'] = $matches[0][0];
  190. }
  191. unset($matches);
  192. }
  193. $pattern_thead_id = "/^\[\d+/";
  194. $matched = preg_match_all($pattern_thead_id, $str, $matches);
  195. if ($matched) {
  196. if (isset($matches[0][0])) {
  197. $params['thread_id'] = str_replace("[","", $matches[0][0]);
  198. }
  199. unset($matches);
  200. }
  201. $strings = substr($str, strpos($str, "content=") +8);
  202. $pairs = self::matchPairs($strings);
  203. if ($pairs) {
  204. foreach ($pairs as $pair)
  205. {
  206. $kv = explode("=", $pair);
  207. if ($kv[0] != "") {
  208. $params[$kv[0]] = $kv[1];
  209. }
  210. }
  211. return $params;
  212. }
  213. return false;
  214. }
  215. private static function matchPairs($str)
  216. {
  217. $pattern = "/(\w+=[^\&]+)/i";
  218. $matched = preg_match_all($pattern, $str, $matches);
  219. if ($matched) {
  220. return $matches[0];
  221. }
  222. return false;
  223. }
  224. }
  225. function work_proc()
  226. {
  227. Base::run_util();
  228. $monitor = new Monitor();
  229. while (true) {
  230. $monitor->run_loop();
  231. }
  232. }
  233. event\util::fork_worker('work_proc',1);