import logging import traceback import inspect import json import sys import raven from django.conf import settings import gm_logging import gm_logging.utils from gm_rpcd.all import context from gm_rpcd.features.raven import get_raven_client from gm_rpcd.internals.dynamic_scopes import DynamicVariableUnboundError from gm_logging.utils import get_exception_logging_func from engine.network import get_client_ip info_logger = logging.getLogger('info_logger') error_logger = logging.getLogger('error_logger') profile_logger = logging.getLogger('profile_logger') exception_logger = logging.getLogger('exception_logger') cpc_click_consumer_logger = logging.getLogger('cpc_click_consumer_logger') auth_logger = logging.getLogger('auth_logger') wechat_logger = logging.getLogger('wechat_logger') sensitive_logger = logging.getLogger('sensitive_logger') def debug(view_func): """将POST请求数据存到log :param view_func: :return: """ def wrap(request): info_logger.info(request.POST.dict()) return view_func(request) return wrap def _build_json_format(result): """ 创建json格式输出 """ return json.dumps(result, ensure_ascii=True, indent=2) def _get_exception_info(): """ 获取stacktrace """ try: exc_type, exc_value, exc_traceback = sys.exc_info() exc = traceback.format_exception(exc_type, exc_value, exc_traceback) info = {'exception': exc} return info except: logging.error('_get_exception_info error') return {} def _build_func_args_item(stack_info): """ 创建单调函数调用记录 """ try: func_name = stack_info[3] args_info = inspect.getargvalues(stack_info[0]) frame = stack_info[0] item = {'function': func_name, 'object': '%s' % frame.f_locals.get('self'), 'arguments': inspect.formatargvalues(args_info.args, args_info.varargs, args_info.keywords, args_info.locals)} return item except: logging.error('_build_func_args_item error') return {} def _get_func_args(): """ 获取外层函数调用参数,注意调用栈顺序,最多取最后3层调用 """ try: stacks = inspect.stack()[:3] result = [] for stack in stacks: item = _build_func_args_item(stack) result.append(item) return result except: logging.error('_get_func_args error') return [] def print_exception(): """ 直接输出异常信息 """ print(_build_json_format(_get_exception_info())) _sentry_client = None try: _sentry_client = get_raven_client() except: pass if _sentry_client is None: _sentry_client = raven.Client(settings.SENTRY_CELERY_ENDPOINT) # 从gm-logging中取得通用的logging_exception方法,logging_excepiton的原型如下: # logging_exception(exception_logger, sentry_client=None, send_to_sentry=True, **kwargs) logging_exception = get_exception_logging_func(exception_logger, _sentry_client) def get_logging_exception_json(): func_args = _get_func_args() exc = _get_exception_info() error_json = _build_json_format({'stacktrace': exc, 'func_args': func_args}) return error_json class RequestInfoExtractor(gm_logging.RequestInfoExtractor): __cl_type_map = { 'iPhone': 'ios', 'android': 'android', } @classmethod def __get_cl_type(cls, cl_type): return cls.__cl_type_map.get(cl_type, cl_type) def __init__(self): self.__local_ip = gm_logging.utils.get_local_ip() self.__hostname = gm_logging.utils.get_hostname() def get_request_info(self, request): request_info = gm_logging.RequestInfo.create( log_host=self.__local_ip, hostname=self.__hostname, module='saturn', cl_type=self.__get_cl_type(request.GET.get('platform')), cl_ver=request.GET.get('version'), cl_os_ver=request.GET.get('os_version'), phone_model=request.GET.get('model'), cl_id=request.GET.get('device_id') or request.GET.get('idfa'), cl_ios_idfv=request.GET.get('idfv'), channel=request.GET.get('channel'), session_id=request.session.session_key, user_ip=get_client_ip(request), gm_request_id=request.META.get('HTTP_X_GM_REQUEST_ID'), http_verb=request.method, action=request.path, ) extra = { 'cl_longitude': request.GET.get('lng'), 'cl_latitude': request.GET.get('lat'), 'cl_city_id': request.GET.get('current_city_id'), 'phone_id': request.GET.get('phone_id'), } try: # 兼容旧版 gm-logging request_info.update(**extra) except Exception: pass return request_info