Example #1
0
    def __start_server_thread_fun(self, tid):
        """
        启动服务处理主线程,本线程结束就代表服务停止

        @param {int} tid - 线程id

        """
        _result = CResult(code='00000')  # 成功
        with ExceptionTool.ignored_cresult(
                result_obj=_result,
                logger=self._logger,
                self_log_msg='[%s-STARTING][NAME:%s]%s: ' %
            (self._server_log_prefix, self._server_name,
             _('start service error'))):
            # 统一的异常处理
            self._logger.log(
                self._log_level, '[%s-STARTING][NAME:%s]%s' %
                (self._server_log_prefix, self._server_name,
                 _('service starting')))

            # 执行服务启动处理,执行通过则代表启动成功tid
            start_result = self._start_server_self(tid)
            self.__last_start_result = start_result

            if start_result.code != '00000':
                # 启动失败,登记了日志,修改状态为未启动,退出
                self._logger.log(
                    logging.ERROR,
                    ('[%s-STARTING][NAME:%s][USE:%ss]%s: %s - %s' %
                     (self._server_log_prefix, self._server_name,
                      str((datetime.datetime.now() - self.__server_begin_time
                           ).total_seconds()), _('start service error'),
                      start_result.code, start_result.msg)))

                self._server_status_change(EnumServerRunStatus.Stop,
                                           start_result)
                return

            # 启动成功,更新状态
            self._logger.log(
                self._log_level, '[%s-STARTED][NAME:%s][USE:%ss]%s' %
                (self._server_log_prefix, self._server_name,
                 str((datetime.datetime.now() - self.__server_begin_time
                      ).total_seconds()), _('start service sucess')))
            self._server_status_change(EnumServerRunStatus.Running, _result)

            # 开始进入循环处理
            while True:
                if self.__server_run_status == EnumServerRunStatus.WaitStop:
                    # 收到指令等待停止
                    while True:
                        if self.__server_run_status == EnumServerRunStatus.ForceStop:
                            # 过程中又被要求强制退出
                            break

                        # 执行预停止处理函数,例如关闭已打开的子线程
                        stop_predeal_result = self._stop_server_predeal_self(
                            tid, start_result.server_info)
                        if stop_predeal_result.code == '00000' and not stop_predeal_result.is_finished:
                            # 预处理未完成,需要循环处理
                            RunTool.sleep(0.1)
                            continue
                        else:
                            # 预处理已完成,退出
                            break
                    break
                elif self.__server_run_status == EnumServerRunStatus.ForceStop:
                    # 收到指令马上停止
                    break
                else:
                    # 正常执行一次服务处理函数
                    run_result = self._server_run_self(
                        tid, start_result.server_info)

                    # 继续下一个循环处理
                    if not run_result.is_finished:
                        continue

        # 线程结束就代表服务已关闭,执行结束处理函数
        self._stop_server_end_self(tid)
        self._server_status_change(EnumServerRunStatus.Stop, _result)
        self._logger.log(
            self._log_level, '[%s-STOPED][NAME:%s][USE:%ss]%s' %
            (self._server_log_prefix, self._server_name,
             str((datetime.datetime.now() - self.__server_stop_time
                  ).total_seconds()), _('service stoped')))
Example #2
0
    def __server_connect_thread_fun(self, thread_id, server_opts, net_info):
        """
        调用外围传入的网络连接处理线程的封装函数
        该函数的主要目的是屏蔽调用程序的网络连接处理函数的异常

        @param {int} thread_id - 线程ID
        @param {object} server_opts - 网络服务的启动参数
        @param {object} net_info - 网络的接入参数(例如socket对象)

        """
        with ExceptionTool.ignored_all(
            logger=self._logger,
            self_log_msg='[%s][NAME:%s]%s: ' % (self._server_log_prefix, self._server_name, _(
                'net service connect deal threading error')),
            force_log_level=logging.ERROR
        ):
            self.__server_connect_deal_fun(thread_id, server_opts, net_info, self.self_tag)
        # 结束处理
        self.__server_connect_thread_end(thread_id)
Example #3
0
    def stop_server(self, is_wait=True, overtime=0):
        """
        关闭服务,设置服务为WaitStop-等待停止状态或ForceStop-强制停止状态

        @param {bool} is_wait=True - 是否等待服务器所有线程都处理完成后再关闭,True-等待所有线程完成处理,False-强制关闭
        @param {float} overtime=0 - 等待超时时间,单位为秒,0代表一直等待

        @returns {CResult} - 停止结果,result.code:'00000'-成功,'21402'-服务停止失败-服务已关闭,
            '31005'-执行超时,29999'-其他系统失败

        """
        _result = CResult(code='00000')  # 成功
        with ExceptionTool.ignored_cresult(
                _result,
                logger=self._logger,
                self_log_msg='[%s-STOPING][NAME:%s]%s: ' %
            (self._server_log_prefix, self._server_name,
             _('stop service error')),
                force_log_level=logging.ERROR):
            self.__server_run_status_lock.acquire()
            try:
                _status = EnumServerRunStatus.WaitStop
                if not is_wait:
                    _status = EnumServerRunStatus.ForceStop

                self.__server_stop_time = datetime.datetime.now()
                if self.__server_run_status == EnumServerRunStatus.Running:
                    # 运行状态,处理设置等待关闭状态
                    self._logger.log(
                        self._log_level, '[%s-STOPING][NAME:%s]%s' %
                        (self._server_log_prefix, self._server_name,
                         _('service stoping')))
                    self._server_status_change(_status, _result)
                elif self.__server_run_status == EnumServerRunStatus.WaitStop \
                        and _status == EnumServerRunStatus.ForceStop:
                    self._logger.log(
                        self._log_level, '[%s-STOPING][NAME:%s]%s' %
                        (self._server_log_prefix, self._server_name,
                         _('service force stoping')))
                    self._server_status_change(_status, _result)
                else:
                    # 不属于运行状态,不能处理
                    _temp_result = CResult(code='21402')  # 服务停止失败-服务已关闭
                    self._logger.log(
                        self._log_level, '[%s-STOPING][NAME:%s]%s' %
                        (self._server_log_prefix, self._server_name,
                         _temp_result.msg))
                    return _temp_result
            finally:
                self.__server_run_status_lock.release()

        # 等待服务关闭
        _begin_time = datetime.datetime.now()  # 记录等待开始时间
        while is_wait:
            if self.__server_run_status == EnumServerRunStatus.Stop:
                break
            if overtime > 0 and (datetime.datetime.now() -
                                 _begin_time).total_seconds() > overtime:
                _result = CResult(code='31005')  # 执行超时
                break
            RunTool.sleep(0.1)

        # 返回结果
        return _result
Example #4
0
    def _graph_cmd_dealfun(self, message='', cmd='', cmd_para='', prompt_obj=None, **kwargs):
        """
        生成APP网络关系图

        @param {string} message='' - prompt提示信息
        @param {string} cmd - 执行的命令key值
        @param {string} cmd_para - 传入的命令参数(命令后的字符串,去掉第一个空格)
        @param {PromptPlus} prompt_obj=None - 传入调用函数的PromptPlus对象,可以通过该对象的一些方法控制输出显示
        @param {kwargs} - 传入的主进程的初始化kwargs对象

        @returns {CResult} - 命令执行结果,可通过返回错误码10101通知框架退出命令行, 同时也可以通过CResult对象的
            print_str属性要求框架进行打印处理
        """
        _ok_result = CResult(code='00000')
        try:
            # 获取参数及处理参数
            _execute_path = self._console_global_para['execute_file_path']
            _run_para = {
                'file': '',
                'formatter': 'col-list',
                'comment': 'graph',
                'outformat': 'pdf',
                'direction': 'forward',
                'trace_id': '',
                'display_no_trace': 'false',
                'down_flow_first': 'true',
                'trace_relations': None,
                'save': '',
                'temp': os.path.join(_execute_path, 'temp'),
                'view': 'true',
                'cleanup': 'false',
                'graph_config': os.path.join(_execute_path, 'conf/graph_config.xml'),
                'template': 'default'
            }
            _in_para = self._cmd_para_to_dict(cmd_para, name_with_sign=False)
            _run_para.update(_in_para)
            if '{para}1' not in _run_para.keys():
                prompt_obj.prompt_print(_('you must give the $1 para!', 'file'))
                return CResult(code='20999')

            _run_para['file'] = _run_para['{para}1']
            if _run_para['save'] == '':
                _run_para['save'] = 'graph.pdf'

            # 样式模板信息处理
            _style_xml = SimpleXml(_run_para['graph_config'], encoding='utf-8')
            _style_dict = _style_xml.to_dict()['graphviz']['templates'].get(
                _run_para['template'], {
                    'graph': {},
                    'node': {},
                    'edge': {},
                    'edge_color': {},
                    'trace': {}
                }
            )
            # 关联关系线颜色
            _name_mapping = _style_dict['edge_color'].get('name_mapping', {})
            _use_round_color = _style_dict['edge_color'].get('use_round_color', False)
            _round_color = _style_dict['edge_color'].get(
                'round_color', '').replace(' ', '').split(',')

            # 生成关系字典
            _graph_json = self._formatter_col_list(_run_para['file'], prompt_obj=prompt_obj)

            # 处理生成调用链的情况
            _display_no_trace = _run_para['display_no_trace'] == 'true'
            if _run_para['trace_id'] != '':
                # 参与追踪的关系名
                if _run_para['trace_relations'] is None:
                    # 全部关系
                    _run_para['trace_relations'] = _graph_json['relation_name']
                else:
                    _run_para['trace_relations'] = _run_para['trace_relations'].split(',')

                # 获取追踪信息字典
                _trace_info = self._get_trace_info(
                    _graph_json, _run_para['trace_id'], _run_para['down_flow_first'] == 'true',
                    _run_para['direction'], _run_para['trace_relations']
                )
            else:
                _trace_info = {
                    'trace_id': '',
                    'up_nodes': list(),
                    'down_nodes': list(),
                    'up_edges': list(),
                    'down_edges': list()
                }

            # 调用链的颜色配置
            _attr_center_node = _style_dict.get('trace', {}).get('center_node', {})
            _attr_up_node = _style_dict.get('trace', {}).get('up_node', {})
            _attr_down_node = _style_dict.get('trace', {}).get('down_node', {})
            _attr_up_edge = _style_dict.get('trace', {}).get('up_edge', {})
            _attr_down_edge = _style_dict.get('trace', {}).get('down_edge', {})

            # 处理关系线条的颜色映射
            _relation_color = dict()
            _index = 0
            for _relation_name in _graph_json['relation_name']:
                if _relation_name in _name_mapping:
                    _relation_color[_relation_name] = _name_mapping[_relation_name]
                elif _use_round_color:
                    _color_index = _index % len(_round_color)
                    _relation_color[_relation_name] = _round_color[_color_index]
                    _index += 1
                else:
                    _relation_color[_relation_name] = ''

            # 开始处理画图
            _dot = Digraph(
                comment=_run_para['comment'], format=_run_para['outformat'], encoding='utf-8',
                directory=_run_para['temp'],
                graph_attr=_style_dict['graph'],
                node_attr=_style_dict['node'],
                edge_attr=_style_dict['edge']
            )

            # 开始画节点
            _added_rank = list()  # 已添加的分组
            for _id, _info in _graph_json['list'].items():
                if _info['rank'] != '':
                    # 有分组处理
                    if _info['rank'] not in _added_rank:
                        _added_rank.append(_info['rank'])
                        with _dot.subgraph() as _sub_dot:
                            _sub_dot.attr(rank='same')
                            for _sub_id in _graph_json['rank'][_info['rank']]:
                                # 节点颜色设置
                                if _sub_id == _trace_info['trace_id']:
                                    # 中心节点
                                    _attr = _attr_center_node
                                elif _sub_id in _trace_info['up_nodes']:
                                    _attr = _attr_up_node
                                elif _sub_id in _trace_info['down_nodes']:
                                    _attr = _attr_down_node
                                elif _display_no_trace and _trace_info['trace_id'] != '':
                                    # 不在链中且不应显示
                                    continue
                                else:
                                    _attr = {}
                                _sub_dot.node(
                                    _sub_id, label=_graph_json['list'][_sub_id]['name'], **_attr
                                )
                else:
                    # 节点颜色设置
                    if _id == _trace_info['trace_id']:
                        # 中心节点
                        _attr = _attr_center_node
                    elif _id in _trace_info['up_nodes']:
                        _attr = _attr_up_node
                    elif _id in _trace_info['down_nodes']:
                        _attr = _attr_down_node
                    elif _display_no_trace and _trace_info['trace_id'] != '':
                        # 不在链中且不应显示
                        continue
                    else:
                        _attr = {}

                    _dot.node(_id, label=_info['name'], **_attr)

            # 开始画关联线
            for _id, _info in _graph_json['list'].items():
                for _key, _list in _info.items():
                    if _key in ('name', 'rank'):
                        continue

                    # 判断颜色
                    _edge_color = _relation_color[_key]

                    for _temp_id in _list:
                        if _temp_id == '':
                            continue

                        if _run_para['direction'] == 'reverse':
                            _head_id = _temp_id
                            _tail_id = _id
                        else:
                            _head_id = _id
                            _tail_id = _temp_id

                        # 处理颜色
                        _findstr = '%s&&%s' % (_head_id, _tail_id)
                        if _findstr in _trace_info['up_edges']:
                            _attr = _attr_up_edge
                        elif _findstr in _trace_info['down_edges']:
                            _attr = _attr_down_edge
                        elif _display_no_trace and _trace_info['trace_id'] != '':
                            continue
                        else:
                            _attr = {'color': _edge_color}

                        _dot.edge(_head_id, _tail_id, **_attr)

            # 保存图片
            _dir, _filename = os.path.split(os.path.abspath(_run_para['save']))
            _filename = FileTool.get_file_name_no_ext(_filename)
            _dot.render(
                filename=_filename, directory=_dir,
                format=_run_para['outformat'], view=(_run_para['view'] == 'true'),
                cleanup=(_run_para['cleanup'] == 'true')
            )
        except Exception as e:
            _prin_str = '%s (%s):\n%s' % (
                _('execution exception'), str(e), traceback.format_exc()
            )
            prompt_obj.prompt_print(_prin_str)
            return CResult(code='20999')

        # 结束
        return _ok_result
Example #5
0
    def _formatter_col_list(self, file: str, prompt_obj=None, **kwargs) -> dict:
        """
        col-list格式化文档

        @param {str} file - 要处理的文件路径
        @param {PromptPlus} prompt_obj=None - 传入调用函数的PromptPlus对象,可以通过该对象的一些方法控制输出显示

        @returns {dict} - 返回的关系字典, list为以id为key的系统清单, rank为分组清单(显示在同一行)
            具体格式如下:
            {
                'list': {
                    'id': {
                        'name': '系统或模块名',
                        'rank': '分组名',
                        '关系名1': ['id1', 'id2', 'id3', ...],
                        '关系名2': [...],
                        ...
                    },
                    ...
                },
                'relation_name': ['关系名1', '关系名2', ...],
                'rank': {
                    'rank_name1': ['id1', 'id2', ...],
                    ...
                }
            }

        """
        _default_key = ('id', 'name', 'rank')
        # 打开文件开始逐个处理
        _wb = xlrd.open_workbook(filename=file)
        _sheet = _wb.sheets()[0]
        _nrows = _sheet.nrows  # 总行数
        _ncols = _sheet.ncols  # 总列数

        # 处理标题行
        _head = dict()  # 标题行字典,key为标题名, value为位置
        for _index in range(0, _ncols):
            _head[str(_sheet.cell(0, _index).value)] = _index

        # 处理关系名
        _relation_name = list()  # 关系名列表
        for _name in _head.keys():
            if _name not in _default_key:
                _relation_name.append(_name)

        # 遍历每行生成id和name的对照字典
        _name_dict = dict()  # key为name, value为id
        _relation = dict()  # 系统清单字典
        _rank = dict()  # 分组清单字典
        for _row in range(1, _nrows):
            _id = str(_sheet.cell(_row, _head['id']).value).strip()
            _name = _id
            if 'name' in _head:
                _name = str(_sheet.cell(_row, _head['name']).value).strip()
            _rank_name = ''
            if 'rank' in _head:
                _rank_name = str(_sheet.cell(_row, _head['rank']).value).strip()

            # 处理分组
            if _rank_name != '':
                if _rank_name in _rank:
                    _rank[_rank_name].append(_id)
                else:
                    _rank[_rank_name] = [_id, ]

            # 处理系统清单
            _name_dict[_name] = _id
            _relation[_id] = {'name': _name, 'rank': _rank_name}
            for _head_str, _index in _head.items():
                if _head_str not in _default_key:
                    _list_str = str(_sheet.cell(_row, _index).value).strip()
                    if _list_str != '':
                        _relation[_id][_head_str] = _list_str.split(',')

        # 处理关系数组中的name映射
        for _id, _para in _relation.items():
            for _key, _value in _para.items():
                if _key not in _default_key:
                    try:
                        for _index in range(len(_value)):
                            _item = _value[_index].strip()
                            if _item != '' and _item not in _relation:
                                # 需要通过name转换为id
                                _value[_index] = _name_dict[_item]
                            else:
                                _value[_index] = _item
                    except:
                        _prin_str = _(
                            'System [$1] relationship [$2] with not define system name [$3]!', _id, _key, _item
                        ) + '\n'
                        prompt_obj.prompt_print(_prin_str)
                        # 重新抛出异常
                        raise

        # 返回处理后的标准字典
        return {
            'list': _relation, 'relation_name': _relation_name, 'rank': _rank
        }
Example #6
0
    def ignored_cresult(result_obj=None,
                        error_map={},
                        expect=(),
                        expect_no_log=False,
                        expect_use_error_map=True,
                        logger=None,
                        self_log_msg='',
                        force_log_level=None,
                        i18n_obj=None,
                        i18n_msg_paras=(),
                        debug=False):
        """
        忽略异常并设置CResult对象,简化异常捕获代码,利用该函数忽略指定的异常,并设置传入的通用结果对象,详细说明如下:
            1、对于指定忽略的异常,忽略不处理,结果为成功(如果指定logger则会进行日志输出,使用WARNING级别)
            2、对于非指定的异常,不抛出异常,结果为失败(如果指定logger则会进行日志输出,使用ERROR级别)
            3、输出的日志为self_log_msg+'\n'+trace_str
            4、根据error_map的映射关系设置错误码和错误信息

        @param {CResult} result_obj=None - 需要设置的错误类对象(对象值会被修改)
        @param {dict} error_map={} - 用来设置错误类对象的映射表,具体说明如下:
            1、key为异常类,value为(code, msg)的错误码、错误描述二元组,如果msg=None代表使用标准错误码
            2、应有一个'DEFAULT'的key,代表没有匹配上的异常映射,默认value为('29999', None)
            3、应有一个'SUCESS'的key,代表成功的映射,默认value为('00000', None)
            注:value也可以为(code, msg, i18n_msg_paras)的错误码、错误描述、国际化替换参数三元组,
                i18n_msg_paras为tuple类型, 使用该模式支持CResult的国际化处理
        @param {tuple} expect=() - 需要忽略的异常列表,例如(ZeroDivisionError, ValueError)
        @param {bool} expect_no_log=False - 忽略异常列表是否不打印日志
        @param {bool} expect_use_error_map=True - 忽略异常列表所匹配到的异常,所返回错误码是否使用错误码映射表:
            如果在映射表中匹配上则返回映射表的错误码;匹配不上则返回成功
        @param {object} logger=None - 日志对象,如果为None代表不需要输出日志,传入对象需满足:
            1、标准logging的logger对象
            2、自定义的日志类对象,但应实现warning、error的标准方法
        @param {string} self_log_msg='' - 需要输出的自定义日志信息
        @param {int} force_log_level=None - 强制遇到所有异常统一按指定的日志级别输出(logging.INFO/...)
        @param {object} i18n_obj=None - 国际化类的实例对象,该对象需实现translate方法
        @param {tuple} i18n_msg_paras=() - 与self_log_msg配套使用,当使用国际化时,可以传入变量,用于替换self_log_msg中的$1占位符
        @param {bool} - debug=False - 是否调试模式,如果是调试模式,当没有logger时使用print输出堆栈信息

        @example
            result = CResult()
            with ExceptionTools.ignored_CResult(result_obj=result, error_map={},expect=(),logger=None,self_log_msg=''):
                i = 1/0
                i = i + 1000
            print(str(result))

        """
        _error_map = copy.deepcopy(error_map)
        try:
            # 初始化对象
            if result_obj is None:
                result_obj = CResult(code='00000', msg=None, i18n_obj=i18n_obj)

            # 确保映射表中有默认值
            if 'SUCESS' not in _error_map.keys():
                _error_map['SUCESS'] = ('00000', None, i18n_msg_paras)
            if 'DEFAULT' not in _error_map.keys():
                _error_map['DEFAULT'] = ('29999', None, i18n_msg_paras)
            # 执行with对应的脚本
            yield
        except expect as ex:
            # 匹配到指定异常,输出日志
            if not expect_no_log:
                _log_level = logging.WARNING
                if force_log_level is not None:
                    _log_level = force_log_level
                _self_log_msg = ''
                if i18n_obj is not None:
                    _self_log_msg = i18n_obj.translate(
                        self_log_msg, replace_para=i18n_msg_paras)
                else:
                    _self_log_msg = _(self_log_msg, *i18n_msg_paras)
                ExceptionTool.__print_log(logger=logger,
                                          self_log_msg='[EX:%s]%s' %
                                          (str(type(ex)), _self_log_msg),
                                          trace_str=traceback.format_exc(),
                                          log_level=_log_level,
                                          debug=debug)
            # 按成功处理
            _error = sys.exc_info()
            _trace_str = traceback.format_exc()
            if expect_use_error_map and _error[0] in _error_map.keys():
                if len(_error_map[_error[0]]) < 3:
                    result_obj.change_code(code=_error_map[_error[0]][0],
                                           msg=_error_map[_error[0]][1])
                else:
                    result_obj.change_code(
                        code=_error_map[_error[0]][0],
                        msg=_error_map[_error[0]][1],
                        i18n_msg_paras=_error_map[_error[0]][2])
                result_obj.error = str(_error[0])
                result_obj.trace_str = _trace_str
            else:
                # 按成功处理
                pass
        except Exception as e:
            # 其他异常,输出日志,获取失败信息
            _error = sys.exc_info()
            _trace_str = traceback.format_exc()
            if _error[0] in _error_map.keys():
                if len(_error_map[_error[0]]) < 3:
                    result_obj.change_code(code=_error_map[_error[0]][0],
                                           msg=_error_map[_error[0]][1])
                else:
                    result_obj.change_code(
                        code=_error_map[_error[0]][0],
                        msg=_error_map[_error[0]][1],
                        i18n_msg_paras=_error_map[_error[0]][2])
                result_obj.error = str(_error[0])
                result_obj.trace_str = _trace_str
            else:
                # 其他失败
                if len(_error_map['DEFAULT']) < 3:
                    result_obj.change_code(code=_error_map['DEFAULT'][0],
                                           msg=_error_map['DEFAULT'][1])
                else:
                    result_obj.change_code(
                        code=_error_map['DEFAULT'][0],
                        msg=_error_map['DEFAULT'][1],
                        i18n_msg_paras=_error_map['DEFAULT'][2])
                result_obj.error = str(_error[0])
                result_obj.trace_str = _trace_str

            _log_level = logging.ERROR
            if force_log_level is not None:
                _log_level = force_log_level
            _self_log_msg = ''
            if i18n_obj is not None:
                _self_log_msg = i18n_obj.translate(self_log_msg,
                                                   replace_para=i18n_msg_paras)
            else:
                _self_log_msg = _(self_log_msg, *i18n_msg_paras)
            ExceptionTool.__print_log(logger=logger,
                                      self_log_msg='[EX:%s]%s' %
                                      (str(type(e)), _self_log_msg),
                                      trace_str=result_obj.trace_str,
                                      log_level=_log_level,
                                      debug=debug)
Example #7
0
    def __server_connect_deal_fun_http(self, thread_id, server_opts, net_info, self_tag):
        """
        Http服务自有的服务处理函数,当server_http_deal_fun被传入的时候使用

        @param {[type]} thread_id - 线程ID
        @param {[type]} server_opts - 服务的启动参数
        @param {[type]} net_info - 具体实现的连接信息(例如Socket对象)
        @param {[type]} self_tag - 用于发起端传入自身的识别标识

        """
        while True:
            # 判断是否要断开服务器
            if self.server_run_status != EnumServerRunStatus.Running:
                # 服务器状态不是运行,直接断开连接
                self._logger.log(
                    self._log_level,
                    '[LIS-HTTP][NAME:%s][IP:%s][PORT:%s]%s' % (
                        self_tag, str(net_info.raddr[0]), str(net_info.raddr[1]),
                        _('close remote connection because servie shutdown')
                    )
                )
                self.close_connect(net_info)
                return

            # 获取报文信息
            _result = self.recv_data(net_info, {})
            if not _result.is_success():
                self._logger.log(
                    logging.ERROR,
                    '[LIS-HTTP][NAME:%s][IP:%s][PORT:%s][EX:%s]%s: %s - %s\n%s' % (
                        self_tag, str(net_info.raddr[0]), str(net_info.raddr[1]),
                        str(type(_result.error)), _('recv data from remote error'),
                        _result.code, _result.msg, _result.trace_str
                    )
                )
                self.close_connect(net_info)
                return

            _proto_msg = _result.data[0]
            _msg = _result.data[1]

            # 写日志
            if self._is_print_msg_log:
                self._logger.log(
                    self._log_level,
                    '[INF-RECV][NAME:%s][IP:%s][PORT:%s]\n%s' % (
                        self_tag, str(net_info.raddr[0]), str(net_info.raddr[1]),
                        self.get_print_str(_proto_msg, _msg)
                    )
                )

            _is_close = True
            _rproto_msg = None
            _rmsg = None
            try:
                (_is_close, _rproto_msg, _rmsg) = self._server_http_deal_fun(net_info, _proto_msg, _msg)
            except Exception as e:
                self._logger.log(
                    logging.ERROR,
                    '[LIS-HTTP][NAME:%s][IP:%s][PORT:%s][EX:%s]%s\n%s' % (
                        self_tag, str(net_info.raddr[0]), str(net_info.raddr[1]),
                        str(type(e)), _('execute server_http_deal_fun error'),
                        traceback.format_exc()
                    )
                )
                # 组织一个异常的返回报文
                _rproto_msg = MsgHTTP('%s 500 Internal Server Error' % (_proto_msg.ver),
                                      obj_type=EnumMsgObjType.String)

            # 组织回包
            if _rproto_msg is not None:
                _result = self.send_data(net_info, (_rproto_msg, _rmsg), {})
                if not _result.is_success():
                    self._logger.log(
                        logging.ERROR,
                        '[LIS-HTTP][NAME:%s][IP:%s][PORT:%s][EX:%s]%s: %s - %s\n%s' % (
                            self_tag, str(net_info.raddr[0]), str(net_info.raddr[1]),
                            str(type(_result.error)), _('send data to remote error'),
                            _result.code, _result.msg, _result.trace_str
                        )
                    )
                    self.close_connect(net_info)
                    return
                # 写日志
                if self._is_print_msg_log:
                    self._logger.log(
                        self._log_level,
                        '[INF-RET][NAME:%s][IP:%s][PORT:%s]\n%s' % (
                            self_tag, str(net_info.raddr[0]), str(net_info.raddr[1]),
                            self.get_print_str(_rproto_msg, _rmsg)
                        )
                    )

            # 判断是否断开连接
            if _is_close:
                self.close_connect(net_info)
                return

            # 睡眠一下,继续处理下一个请求
            RunTool.sleep(0.001)