*/ class StatisticService extends WORKERMAN\Core\SocketWorker { /** * 判断包是否都到达 * @see Worker::dealInput() */ public function dealInput($recv_str) { return \WORKERMAN\Protocols\SimpleHttp::input($recv_str); } /** * 处理业务逻辑 查询log 查询统计信息 * @see Worker::dealProcess() */ public function dealProcess($recv_str) { \WORKERMAN\Protocols\SimpleHttp::decode($recv_str); $module = isset($_GET['module']) ? trim($_GET['module']) : ''; $interface = isset($_GET['interface']) ? trim($_GET['interface']) : ''; $start_time = isset($_GET['start_time']) ? trim($_GET['start_time']) : ''; $end_time = isset($_GET['end_time']) ? trim($_GET['end_time']) : ''; if(0 === strpos($_SERVER['REQUEST_URI'], '/graph')) { if(!extension_loaded('gd')) { return $this->sendToClient("not suport gd\n"); } $type_map = array('request','time'); $type = isset($_GET['type']) && in_array($_GET['type'], $type_map) ? $_GET['type'] : 'request'; $this->displayGraph($module, $interface, $type, $start_time); } // 日志 elseif(0 === strpos($_SERVER['REQUEST_URI'], '/log')) { $right_str = ''; $code = isset($_GET['code']) ? $_GET['code'] : ''; $msg = isset($_GET['msg']) ? $_GET['msg'] : ''; $pointer = isset($_GET['pointer']) ? $_GET['pointer'] : ''; $count = isset($_GET['count']) ? $_GET['count'] : 100; $log_data = $this->getStasticLog($module, $interface , $start_time , $end_time, $code, $msg , $pointer, $count); if($log_data['pointer'] == 0) { return $this->display($log_data['data']); } else { $_GET['pointer'] = $log_data['pointer']; unset($_GET['end_time']); $next_page_url = http_build_query($_GET); $log_data['data'] .= "
下一页
"; return $this->display(nl2br($log_data['data'])); } } // 统计 else { // 首页 if(empty($module)) { return $this->home(); } else { if($interface) { return $this->displayInterface($module, $interface, $start_time, $end_time); } else { return $this->display(); } } } return $this->display(); } /** * 统计主页 * @return void */ protected function home() { $data = ''; $address = '127.0.0.1:10101'; $sock = stream_socket_client($address); if(!$sock) { return $this->display(); } fwrite($sock, 'status'); $read_fds = array($sock); $write_fds = $except_fds = array(); $time_start = time(); while(1) { $ret = @stream_select($read_fds, $write_fds, $except_fds, 1); if(!$ret) { if(time() - $time_start >= 1) { break; } continue; } foreach($read_fds as $fd) { if($ret_str = fread($fd, 8192)) { $data .= $ret_str; } else { break; } } if(time() - $time_start >= 1) { break; } } $data = '
'.$data.'
'; return $this->display($data); } /** * 接口统计信息 * @param string $module * @param string $interface * @param int $start_time * @param int $end_time * @return void */ protected function displayInterface($module ,$interface, $start_time, $end_time) { $data = $this->getStatistic($module, $interface, $start_time, $end_time); $suport_gd = extension_loaded('gd'); $right_str = '
模块:'.$module.'   接口:'.$interface.'

'.($suport_gd ? ' ' : '未安装gd库,图形无法展示') .'
请求量

'.($suport_gd ? ' ' : '未安装gd库,图形无法展示') .'
延迟单位:秒

'; $right_str .= '
'; $date_array = $this->getAvailableStDate($module, $interface); $current_key = strtotime(date('Y-m-d', $start_time ? $start_time : time())); if(!isset($date_array[$current_key])) { $date_array[$current_key] = date('Y-m-d', $current_key); } unset($_GET['start_time']); $st_url = http_build_query($_GET); $date_array_chunk = array_chunk($date_array, 7, true); if($date_array_chunk) { foreach($date_array_chunk as $date_array) { foreach($date_array as $time_stamp => $date) { $right_str .= ($current_key == $time_stamp) ? (''.$date.'  ') : (''.$date.'  '); } $right_str .= "
"; } } $right_str .='

'; $right_str .=' '; if($data) { foreach($data as $item) { $right_str .= "\n"; } } $right_str .= '
时间调用总数平均耗时成功调用总数成功平均耗时失败调用总数失败平均耗时成功率
{$item['time']}{$item['total_count']}{$item['total_avg_time']}{$item['suc_count']}{$item['suc_avg_time']}".($item['fail_count']>0?("{$item['fail_count']}"):$item['fail_count'])."{$item['fail_avg_time']}".($item['precent']<=98?''.$item['precent'].'%' : $item['precent'].'%')."
'; return $this->display($right_str); } /** * 展示曲线图 * @param string $module * @param string $interface * @param string $type * @param integer $start_time * @return void */ protected function displayGraph($module ,$interface, $type = 'request', $start_time = '') { $data = $this->getStatistic($module, $interface, $start_time); \WORKERMAN\Protocols\SimpleHttp::header("Content-type: image/jpeg"); $gg=new buildGraph(); $d2 = $d3 = array(); $time_point = $start_time ? strtotime(date('Y-m-d',$start_time)) : strtotime(date('Y-m-d')); switch($type) { case 'time': for($i=0;$i<288;$i++) { $time_point +=300; $d2[$time_point] = isset($data[$time_point]['total_avg_time']) ? $data[$time_point]['total_avg_time'] : 0; $d3[$time_point] = isset($data[$time_point]['fail_avg_time']) ? $data[$time_point]['fail_avg_time'] : 0; } break; default: for($i=0;$i<288;$i++) { $time_point +=300; $d2[$time_point] = isset($data[$time_point]['total_count']) ? $data[$time_point]['total_count'] : 0; $d3[$time_point] = isset($data[$time_point]['fail_count']) ? $data[$time_point]['fail_count'] : 0; } } $d2 = array_values($d2); $d3 = array_values($d3); $gg->addData($d2); $gg->addData($d3); $gg->setColors("088A08,b40404"); ob_start(); // 生成曲线图 $gg->build("line",0); // 参数0表示显示所有曲线,1为显示第一条,依次类推 return $this->sendToClient(\WORKERMAN\Protocols\SimpleHttp::encode(ob_get_clean())); } /** * 获取模块 * @return array */ public function getModules() { $st_dir = WORKERMAN_LOG_DIR . 'statistic/st/'; return glob($st_dir."/*"); } /** * 渲染页面 * @param string $data * @return bool */ protected function display($data=null) { $left_detail = ''; $html_left = '