StatisticWorker.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. require_once WORKERMAN_ROOT_DIR . 'man/Core/SocketWorker.php';
  3. /**
  4. *
  5. * @author walkor <worker-man@qq.com>
  6. */
  7. class StatisticWorker extends Man\Core\SocketWorker
  8. {
  9. /**
  10. * 最大日志buffer,大于这个值就写磁盘
  11. * @var integer
  12. */
  13. const MAX_LOG_BUFFER_SZIE = 1024000;
  14. /**
  15. * 多长时间写一次数据到磁盘
  16. * @var integer
  17. */
  18. const WRITE_PERIOD_LENGTH = 60;
  19. /**
  20. * 多长时间清理一次老的磁盘数据
  21. * @var integer
  22. */
  23. const CLEAR_PERIOD_LENGTH = 86400;
  24. /**
  25. * 数据多长时间过期
  26. * @var integer
  27. */
  28. const EXPIRED_TIME = 1296000;
  29. /**
  30. * 统计数据
  31. * ip=>modid=>interface=>['code'=>[xx=>count,xx=>count],'suc_cost_time'=>xx,'fail_cost_time'=>xx, 'suc_count'=>xx, 'fail_count'=>xx, 'time'=>xxx]
  32. * @var array
  33. */
  34. protected $statisticData = array();
  35. /**
  36. * 日志的buffer
  37. * @var string
  38. */
  39. protected $logBuffer = '';
  40. public function dealInput($recv_str)
  41. {
  42. return 0;
  43. }
  44. public function dealProcess($recv_str)
  45. {
  46. $unpack_data = StatisticProtocol::decode($recv_str);
  47. $module = $unpack_data['module'];
  48. $interface = $unpack_data['interface'];
  49. $cost_time = $unpack_data['cost_time'];
  50. $success = $unpack_data['success'];
  51. $time = $unpack_data['time'];
  52. $code = $unpack_data['code'];
  53. $msg = str_replace("\n", "<br>", $unpack_data['msg']);
  54. $ip = $this->getRemoteIp();
  55. // 统计相关信息
  56. if(!isset($this->statisticData[$ip]))
  57. {
  58. $this->statisticData[$ip] = array();
  59. }
  60. if(!isset($this->statisticData[$ip][$module]))
  61. {
  62. $this->statisticData[$ip][$module] = array();
  63. }
  64. if(!isset($this->statisticData[$ip][$module][$interface]))
  65. {
  66. $this->statisticData[$ip][$module][$interface] = array('code'=>array(), 'suc_cost_time'=>0, 'fail_cost_time'=>0, 'suc_count'=>0, 'fail_count'=>0, 'time'=>$this->stLastWriteTime);
  67. }
  68. if(!isset($this->statisticData[$ip][$module][$interface]['code'][$code]))
  69. {
  70. $this->statisticData[$ip][$module][$interface]['code'][$code] = 0;
  71. }
  72. $this->statisticData[$ip][$module][$interface]['code'][$code]++;
  73. if($success)
  74. {
  75. $this->statisticData[$ip][$module][$interface]['suc_cost_time'] += $cost_time;
  76. $this->statisticData[$ip][$module][$interface]['suc_count'] ++;
  77. }
  78. else
  79. {
  80. $this->statisticData[$ip][$module][$interface]['fail_cost_time'] += $cost_time;
  81. $this->statisticData[$ip][$module][$interface]['fail_count'] ++;
  82. }
  83. // 失败记录日志
  84. if(!$success)
  85. {
  86. $this->logBuffer .= date('Y-m-d H:i:s',$time)."\t$ip\t$module::$interface\tcode:$code\tmsg:$msg\n";
  87. if(strlen($this->logBuffer) >= self::MAX_LOG_BUFFER_SZIE)
  88. {
  89. $this->writeLogToDisk();
  90. }
  91. }
  92. }
  93. public function writeLogToDisk()
  94. {
  95. }
  96. }
  97. /**
  98. *
  99. * struct statisticPortocol
  100. * {
  101. * unsigned char module_name_len;
  102. * unsigned char interface_name_len;
  103. * float cost_time;
  104. * unsigned char success;
  105. * int code;
  106. * unsigned short msg_len;
  107. * unsigned int time;
  108. * char[module_name_len] module_name;
  109. * char[interface_name_len] interface_name;
  110. * char[msg_len] msg;
  111. * }
  112. *
  113. * @author valkor
  114. */
  115. class StatisticProtocol
  116. {
  117. /**
  118. * 包头长度
  119. * @var integer
  120. */
  121. const PACKEGE_FIXED_LENGTH = 17;
  122. /**
  123. * udp 包最大长度
  124. * @var integer
  125. */
  126. const MAX_UDP_PACKGE_SIZE = 65507;
  127. /**
  128. * char类型能保存的最大数值
  129. * @var integer
  130. */
  131. const MAX_CHAR_VALUE = 255;
  132. /**
  133. * usigned short 能保存的最大数值
  134. * @var integer
  135. */
  136. const MAX_UNSIGNED_SHORT_VALUE = 65535;
  137. /**
  138. * 编码
  139. * @param string $module
  140. * @param string $interface
  141. * @param float $cost_time
  142. * @param int $success
  143. * @param int $code
  144. * @param string $msg
  145. * @return string
  146. */
  147. public static function encode($module, $interface , $cost_time, $success, $code = 0,$msg = '')
  148. {
  149. // 防止模块名过长
  150. if(strlen($module) > self::MAX_CHAR_VALUE)
  151. {
  152. $module = substr($module, 0, self::MAX_CHAR_VALUE);
  153. }
  154. // 防止接口名过长
  155. if(strlen($interface) > self::MAX_CHAR_VALUE)
  156. {
  157. $interface = substr($interface, 0, self::MAX_CHAR_VALUE);
  158. }
  159. // 防止msg过长
  160. $module_name_length = strlen($module);
  161. $interface_name_length = strlen($interface);
  162. $avalible_size = self::MAX_UDP_PACKGE_SIZE - self::PACKEGE_FIXED_LENGTH - $module_name_length - $interface_name_length;
  163. if(strlen($msg) > $avalible_size)
  164. {
  165. $msg = substr($msg, 0, $avalible_size);
  166. }
  167. // 打包
  168. return pack('CCfCNnN', $module_name_length, $interface_name_length, $cost_time, $success ? 1 : 0, $code, strlen($msg), time()).$module.$interface.$msg;
  169. }
  170. /**
  171. * 解包
  172. * @param string $bin_data
  173. * @return array
  174. */
  175. public static function decode($bin_data)
  176. {
  177. // 解包
  178. $data = unpack("Cmodule_name_len/Cinterface_name_len/fcost_time/Csuccess/Ncode/nmsg_len/Ntime", $data);
  179. $module = substr($bin_data, self::PACKEGE_FIXED_LENGTH, $data['module_name_len']);
  180. $interface = substr($bin_data, self::PACKEGE_FIXED_LENGTH + $data['module_name_len'], $data['interface_name_len']);
  181. $msg = substr($bin_data, self::PACKEGE_FIXED_LENGTH + $data['module_name_len'] + $data['interface_name_len']);
  182. return array(
  183. 'module' => $module,
  184. 'interface' => $interface,
  185. 'cost_time' => $data['cost_time'],
  186. 'success' => $data['success'],
  187. 'time' => $data['time'],
  188. 'code' => $data['code'],
  189. 'msg' => $msg,
  190. );
  191. }
  192. }