Author: workerman
Author: xmc 2015.06.06
 /**
  * 上报统计数据
  * 
  * @param string $module        	
  * @param string $interface        	
  * @param bool $success        	
  * @param int $code        	
  * @param string $msg        	
  * @param string $report_address        	
  * @return boolean
  */
 public static function report($module, $interface, $success, $code, $msg, $report_address = '')
 {
     $report_address = $report_address ? $report_address : '127.0.0.1:55656';
     if (isset(self::$timeMap[$module][$interface]) && self::$timeMap[$module][$interface] > 0) {
         $time_start = self::$timeMap[$module][$interface];
         self::$timeMap[$module][$interface] = 0;
     } else {
         if (isset(self::$timeMap['']['']) && self::$timeMap[''][''] > 0) {
             $time_start = self::$timeMap[''][''];
             self::$timeMap[''][''] = 0;
         } else {
             $time_start = microtime(true);
         }
     }
     $cost_time = microtime(true) - $time_start;
     $bin_data = Protocol::encode($module, $interface, $cost_time, $success, $code, $msg);
     if (extension_loaded('swoole')) {
         if (!self::$client || !self::$client->isConnected()) {
             self::$client = new swoole_client(SWOOLE_TCP, SWOOLE_SOCK_SYNC);
             list($ip, $port) = explode(':', $report_address);
             self::$client->connect($ip, $port);
         }
         self::$client->send($bin_data);
         self::$client->close();
         self::$client = null;
     } else {
         return self::sendData($report_address, $bin_data);
     }
 }
 /**
  * 初始化配置
  * @param array $configArray
  */
 public static function config($configArray)
 {
     if (is_array($configArray)) {
         if (isset($configArray['report_address'])) {
             self::$reportAddress = $configArray['report_address'];
         }
     }
 }
Exemple #3
0
 public static function CommonStatistic($module, $interface, $success, $code, $msg, $report_address = '')
 {
     // 统计的产生,接口调用是否成功、错误码、错误日志
     //$success = true; $code = 0; $msg = 'success';
     // 上报结果
     StatisticClient::report($module, $interface, $success, $code, $msg, $report_address);
     StatisticClient::report($module, 'all_pv', $success, $code, $msg, $report_address);
 }
Exemple #4
0
 /**
  * 数据接收完整后处理业务逻辑
  * @see Man\Core.SocketWorker::dealProcess()
  */
 public function dealProcess($recv_str)
 {
     /**
      * data的数据格式为
      * ['class'=>xx, 'method'=>xx, 'param_array'=>array(xx)]
      * @var array
      */
     $data = JsonProtocol::decode($recv_str);
     // 判断数据是否正确
     if (empty($data['class']) || empty($data['method']) || !isset($data['param_array'])) {
         // 发送数据给客户端,请求包错误
         return $this->sendToClient(JsonProtocol::encode(array('code' => 400, 'msg' => 'bad request', 'data' => null)));
     }
     // 获得要调用的类、方法、及参数
     $class = $data['class'];
     $method = $data['method'];
     $param_array = $data['param_array'];
     StatisticClient::tick($class, $method);
     $success = false;
     // 判断类对应文件是否载入
     if (!class_exists($class)) {
         $include_file = ROOT_DIR . "/Services/{$class}.php";
         if (is_file($include_file)) {
             require_once $include_file;
         }
         if (!class_exists($class)) {
             $code = 404;
             $msg = "class {$class} not found";
             StatisticClient::report($class, $method, $success, $code, $msg, $this->statisticAddress);
             // 发送数据给客户端 类不存在
             return $this->sendToClient(JsonProtocol::encode(array('code' => $code, 'msg' => $msg, 'data' => null)));
         }
     }
     // 调用类的方法
     try {
         $ret = call_user_func_array(array($class, $method), $param_array);
         StatisticClient::report($class, $method, 1, 0, '', $this->statisticAddress);
         // 发送数据给客户端,调用成功,data下标对应的元素即为调用结果
         return $this->sendToClient(JsonProtocol::encode(array('code' => 0, 'msg' => 'ok', 'data' => $ret)));
     } catch (Exception $e) {
         // 发送数据给客户端,发生异常,调用失败
         $code = $e->getCode() ? $e->getCode() : 500;
         StatisticClient::report($class, $method, $success, $code, $e, $this->statisticAddress);
         return $this->sendToClient(JsonProtocol::encode(array('code' => $code, 'msg' => $e->getMessage(), 'data' => $e)));
     }
 }
Exemple #5
0
 public static function report($data, $ctx, $source_ip)
 {
     $module = $data['class'];
     $interface = $data['method'];
     $code = 0;
     $msg = '';
     $success = true;
     if (is_array($ctx) && isset($ctx['exception'])) {
         $success = false;
         $code = isset($ctx['exception']['code']) ? $ctx['exception']['code'] : 40404;
         $msg = isset($ctx['exception']['class']) ? $ctx['exception']['class'] . "::" : '';
         $msg .= isset($ctx['exception']['message']) ? $ctx['exception']['message'] : '';
         $msg .= "\n" . $ctx['exception']['traceAsString'];
         $msg .= "\nREQUEST_DATA:[" . json_encode($data) . "]\n";
     }
     // 格式key[模块名,接口名] val[数量,耗时,是否成功,错误码]
     try {
         if (JumeiWorker::$rpcMNLogger) {
             JumeiWorker::$rpcMNLogger->log('RPC-Server,' . JumeiWorker::$appName . ',' . ($success ? 'Success' : 'Failed'), microtime(true) - self::$timeStart);
         }
     } catch (Exception $e) {
     }
     StatisticClient::report($module, $interface, $code, $msg, $success, $source_ip);
 }
        $interface_name_length = strlen($interface);
        $avalible_size = self::MAX_UDP_PACKGE_SIZE - self::PACKAGE_FIXED_LENGTH - $module_name_length - $interface_name_length;
        if (strlen($msg) > $avalible_size) {
            $msg = substr($msg, 0, $avalible_size);
        }
        // 打包
        return pack('CCfCNnN', $module_name_length, $interface_name_length, $cost_time, $success ? 1 : 0, $code, strlen($msg), time()) . $module . $interface . $msg;
    }
    /**
     * 解包
     * @param string $bin_data
     * @return array
     */
    public static function decode($bin_data)
    {
        // 解包
        $data = unpack("Cmodule_name_len/Cinterface_name_len/fcost_time/Csuccess/Ncode/nmsg_len/Ntime", $bin_data);
        $module = substr($bin_data, self::PACKAGE_FIXED_LENGTH, $data['module_name_len']);
        $interface = substr($bin_data, self::PACKAGE_FIXED_LENGTH + $data['module_name_len'], $data['interface_name_len']);
        $msg = substr($bin_data, self::PACKAGE_FIXED_LENGTH + $data['module_name_len'] + $data['interface_name_len']);
        return array('module' => $module, 'interface' => $interface, 'cost_time' => $data['cost_time'], 'success' => $data['success'], 'time' => $data['time'], 'code' => $data['code'], 'msg' => $msg);
    }
}
if (PHP_SAPI == 'cli' && isset($argv[0]) && $argv[0] == basename(__FILE__)) {
    StatisticClient::tick("TestModule", 'TestInterface');
    usleep(rand(10000, 600000));
    $success = rand(0, 1);
    $code = rand(300, 400);
    $msg = '这个是测试消息';
    var_export(StatisticClient::report('TestModule', 'TestInterface', $success, $code, $msg));
}
Exemple #7
0
 /**
  * 每当到达设定的时间时触发
  */
 public function onTime()
 {
     $time_now = microtime(true);
     if (($time_now - $this->lastCallOnTime) * 1000 >= $this->timeIntervalMS) {
         $this->lastCallOnTime = $time_now;
         if (function_exists('on_time')) {
             StatisticClient::tick($this->serviceName, 'on_time');
             try {
                 call_user_func('on_time');
                 StatisticClient::report($this->serviceName, 'on_time');
             } catch (Exception $e) {
                 StatisticClient::report($this->serviceName, 'on_time', $e->getMessage(), $e, false, $this->getLocalIp());
             }
         }
     }
     $time_diff = $this->lastCallOnTime * 1000 + $this->timeIntervalMS - microtime(true) * 1000;
     if ($time_diff <= 0) {
         call_user_func(array($this, 'onTime'));
     } else {
         $this->event->setReadTimeOut($time_diff);
     }
 }
Exemple #8
0
    {
        $errcode = 10001;
        return $errcode;
    }
    public static function getErrMsg()
    {
        $errmsg = '添加用户失败';
        return $errmsg;
    }
}
include 'StatisticClient.php';
// 统计开始
StatisticClient::tick("User", 'addInfo');
// 统计的产生,接口调用是否成功、错误码、错误日志
$success = true;
$code = 0;
$msg = '';
// 假如有个User::getInfo方法要监控
$user_info = User::addInfo();
if (!$user_info) {
    // 标记失败
    $success = false;
    // 获取错误码,假如getErrCode()获得
    $code = User::getErrCode();
    // 获取错误日志,假如getErrMsg()获得
    $msg = User::getErrMsg();
}
// 上报结果
$res = StatisticClient::report('User', 'addInfo', $success, $code, $msg);
echo "done over...\n";
var_dump($user_info, $res);
Exemple #9
0
        $i = $req_cnt;
        // while($i-- > 0)
        while (1) {
            // === tick 用于记录接口调用起始时间,精确到毫秒===
            StatisticClient::tick();
            usleep(rand(1000, 2000000));
            $module_map = array('User' => 'User', 'Order' => 'Order', 'Card' => 'Card');
            $interface_map = array('getUserByUid' => 'getUserByUid', 'getOrderInfo' => 'getOrderInfo', 'getInfo' => 'getInfo', 'getLists' => 'getLists', 'update' => 'update', 'delete' => 'delete');
            $module = array_rand($module_map);
            $interface = array_rand($interface_map);
            $msg_array = array('参数错误', '数据库链接超时', '数据库无法链接,请稍后重试', '用户不存在', '网络繁忙,请稍后再试');
            $msg = $msg_array[array_rand($msg_array)];
            $code = rand(11011, 11100);
            $suc = rand(1, 9999) < 9997 ? true : false;
            // === 上报结果 ===
            $ret = StatisticClient::report($module, $interface, $code, $msg, $suc);
        }
        print_result();
        exit("");
    }
}
while (!empty($pid_array)) {
    $pid = pcntl_wait($status);
    if ($pid > 0) {
        unset($pid_array[$pid]);
    }
}
echo "DONE ........";
print_result($req_cnt * $proc_cnt);
die;
function print_result($cnt = null)
Exemple #10
0
<?php

require '/usr/local/nginx/html/workerman-statistics/Applications/Statistics/Clients/StatisticClient.php';
// 统计开始
StatisticClient::tick("User", 'getInfo');
// 统计的产生,接口调用是否成功、错误码、错误日志
$success = true;
$code = 0;
$msg = '';
// 假如有个User::getInfo方法要监控
$user_info = User::getInfo();
if (!$user_info) {
    // 标记失败
    $success = false;
    // 获取错误码,假如getErrCode()获得
    $code = User::getErrCode();
    // 获取错误日志,假如getErrMsg()获得
    $msg = User::getErrMsg();
}
// 上报结果
StatisticClient::report('User', 'getInfo', $success, $code, $msg);
Exemple #11
0
 /**
  * 有消息时
  * @param int $client_id
  * @param string $message
  */
 public static function onMessage($client_id, $data)
 {
     $class_dir = __DIR__ . "/Services";
     //要读取的类文件路径
     $host_type = "internet";
     //客户端类型
     echo $_SERVER['REMOTE_ADDR'] . "\n";
     if ($_SERVER['REMOTE_ADDR'] == "127.0.0.1") {
         echo "内网登陆";
         $class_dir = __DIR__ . "/SysServices";
         $host_type = "localhost";
         //客户端类型
     }
     echo $_SESSION['UID'] . "\n";
     $statistic_address = 'udp://127.0.0.1:55656';
     // 判断数据是否正确
     if (empty($data['class']) || empty($data['method']) || !isset($data['param_array'])) {
         // 发送数据给客户端,请求包错误
         if ($host_type == "internet" && empty($_SESSION['UID'])) {
             $ret = Gateway::sendToCurrentClient(array('stat' => 100, 'text' => 'no login', 'data' => null));
             Gateway::closeCurrentClient();
         } else {
             $ret = Gateway::sendToCurrentClient(array('stat' => 400, 'text' => 'bad request', 'data' => null));
         }
         return $ret;
     }
     // 获得要调用的类、方法、及参数
     $class = $data['class'];
     $method = $data['method'];
     $param_array = $data['param_array'];
     //所有的调用一定要在登录后才可以
     if (!empty($_SESSION['UID']) || $class == "Device" && $method == "Login" || $host_type == "localhost") {
         StatisticClient::tick($class, $method);
         $success = false;
         // 判断类对应文件是否载入
         if (!class_exists($class)) {
             $include_file = $class_dir . "/{$class}.php";
             if (is_file($include_file)) {
                 require_once $include_file;
             }
             if (!class_exists($class)) {
                 $code = 404;
                 $msg = "class {$class} not found";
                 StatisticClient::report($class, $method, $success, $code, $msg, $statistic_address);
                 // 发送数据给客户端 类不存在
                 //var_dump($connection);
                 return Gateway::sendToCurrentClient(array('stat' => $code, 'text' => $msg, 'data' => null));
             }
         }
         // 调用类的方法
         try {
             $ret = call_user_func_array(array($class, $method), array($client_id, $param_array));
             StatisticClient::report($class, $method, 1, 0, '', $statistic_address);
             // 发送数据给客户端,调用成功,data下标对应的元素即为调用结果
             return Gateway::sendToCurrentClient(array('stat' => 0, 'text' => 'ok', 'data' => $ret));
         } catch (Exception $e) {
             // 发送数据给客户端,发生异常,调用失败
             $code = $e->getCode() ? $e->getCode() : 500;
             StatisticClient::report($class, $method, $success, $code, $e, $statistic_address);
             return Gateway::sendToCurrentClient(array('stat' => $code, 'text' => $e->getMessage(), 'data' => $e));
         }
     } else {
         $ret = Gateway::sendToCurrentClient(array('stat' => 400, 'text' => 'no login', 'data' => null));
         Gateway::closeCurrentClient();
         return $ret;
     }
 }
Exemple #12
0
 public static function report($serviceName, $method, $source_ip, $exception = null, $request_data = '')
 {
     $success = empty($exception);
     $code = 0;
     $msg = '';
     $success = true;
     if ($exception) {
         $success = false;
         $code = $exception->getCode();
         $msg = $exception;
         $msg .= "\nREQUEST_DATA:[" . bin2hex($request_data) . "]\n";
     }
     // 格式key[模块名,接口名] val[数量,耗时,是否成功,错误码]
     try {
         if (ThriftWorker::$rpcMNLogger) {
             ThriftWorker::$rpcMNLogger->log("RPC-Server," . ThriftWorker::$appName . "," . ($success ? 'Success' : 'Failed'), microtime(true) - self::$timeStart);
         }
     } catch (Exception $e) {
     }
     StatisticClient::report($serviceName, $method, $code, $msg, $success, $source_ip);
 }
Exemple #13
0
 public function callInterfaceCommon($apiurl, $type, $auth, $params, $token)
 {
     // 判断参数$params 是否为标准json
     try {
         $info = explode('/', ltrim($apiurl, '/'));
         $method_workman = current($info);
         $this->validate($token, current($info));
         // 验证权限
         $apiurl = $_SERVER['SERVER_NAME'] . '/api/restful/' . $apiurl;
         json_decode($params, true);
         if (json_last_error() !== JSON_ERROR_NONE) {
             throw new Exception('params非法的json格式', 555);
         }
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_URL, $apiurl);
         // 发贴地址
         curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json;charset="UTF-8"'));
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         switch (strtoupper($type)) {
             case "GET":
                 curl_setopt($ch, CURLOPT_HTTPGET, true);
                 break;
             case "POST":
                 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                 break;
             case "PUT":
                 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                 break;
             case "DELETE":
                 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                 break;
         }
         curl_setopt($ch, CURLOPT_USERPWD, $auth->username . ':' . $auth->password);
         $result = curl_exec($ch);
         // 获得返回值
         // file_put_contents("./up.log", 'data:' . var_export($result, true) . PHP_EOL, FILE_APPEND);
         json_decode($result, true);
         if (json_last_error() != JSON_ERROR_NONE) {
             $httpcode = 500;
         } else {
             $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
             $contenttype = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
             echo $res = json_encode(['code' => $httpcode, 'data' => json_decode($result, TRUE)]);
         }
         // 判断服务器是win还是linux
         if (PATH_SEPARATOR == ':') {
             require '/usr/local/nginx/html/workerman-statistics/Applications/Statistics/Clients/StatisticClient.php';
             // 统计开始
             StatisticClient::tick("Restful", $method_workman);
             // 统计的产生,接口调用是否成功、错误码、错误日志
             $success = true;
             $code = 0;
             $msg = '';
             // 假如有个User::getInfo方法要监控
             if (!in_array($httpcode, ['200', '201', '400', '404', '409'])) {
                 // 标记失败
                 $success = false;
                 // 获取错误码,假如getErrCode()获得
                 $code = $httpcode;
                 // 获取错误日志,假如getErrMsg()获得
                 $msg = 'apiurl:' . $apiurl . PHP_EOL . 'requset_type:' . $type . PHP_EOL . 'params:' . $params . PHP_EOL . 'code:' . $code . PHP_EOL . 'data:' . var_export($result, true);
             }
             // 上报结果
             StatisticClient::report('Restful', $method_workman, $success, $code, $msg);
         }
         // file_put_contents("./up.log", 'json:' . $res . PHP_EOL . "<hr/>" . PHP_EOL, FILE_APPEND);
         curl_close($ch);
     } catch (Exception $e) {
         echo json_encode(['code' => $e->getCode(), 'message' => $e->getMessage()]);
     }
 }
    // 判断类对应文件是否载入
    if (!class_exists($class)) {
        $include_file = __DIR__ . "/Services/{$class}.php";
        if (is_file($include_file)) {
            require_once $include_file;
        }
        if (!class_exists($class)) {
            $code = 404;
            $msg = "class {$class} not found";
            StatisticClient::report($class, $method, $success, $code, $msg, $statistic_address);
            // 发送数据给客户端 类不存在
            return $connection->send(array('code' => $code, 'msg' => $msg, 'data' => null));
        }
    }
    // 调用类的方法
    try {
        $ret = call_user_func_array(array($class, $method), $param_array);
        StatisticClient::report($class, $method, 1, 0, '', $statistic_address);
        // 发送数据给客户端,调用成功,data下标对应的元素即为调用结果
        return $connection->send(array('code' => 0, 'msg' => 'ok', 'data' => $ret));
    } catch (Exception $e) {
        // 发送数据给客户端,发生异常,调用失败
        $code = $e->getCode() ? $e->getCode() : 500;
        StatisticClient::report($class, $method, $success, $code, $e, $statistic_address);
        return $connection->send(array('code' => $code, 'msg' => $e->getMessage(), 'data' => $e));
    }
};
// 如果不是在根目录启动,则运行runAll方法
if (!defined('GLOBAL_START')) {
    Worker::runAll();
}