예제 #1
0
def trace_resource_call(wrapped, instance, args, kwargs):
    """
    :param wrapped:
    :param instance:
    :param args:
    :param kwargs:
    :return:
    """
    method_mapping = {
        'GET': 'read',
        'POST': 'create',
        'PUT': 'update',
        'DELETE': 'delete'
    }

    def parse_request(request, *args, **kwargs):
        return request

    tracker = current_tracker()
    if not tracker:
        return wrapped(*args, **kwargs)

    request = parse_request(*args, **kwargs)
    method = request.method.upper()

    # if invalid request method, use the origin request method
    # And using high priority to set the metric name.
    name = "%s.%s" % (callable_name(
        instance.handler), method_mapping.get(method, method))
    tracker.set_tracker_name(name=name, priority=5)
    with FunctionTracker(tracker, name):
        return wrapped(*args, **kwargs)
예제 #2
0
def _do_method_trace(wrapped, instance, args, kwargs):

    tracker = obtain_tracker_from_request(instance.request)
    if not tracker:
        return wrapped(*args, **kwargs)

    with FunctionTracker(tracker, name=object_name(wrapped)):
        return wrapped(*args, **kwargs)
예제 #3
0
파일: web.py 프로젝트: xuning992/tfty
        def user_func_wrapper(wrapped, instance, args, kwargs):
            tracer = getattr(instance.request, "_self_tracer", None)
            if not tracer:
                # console.info("ignore trace func %s", callable_name(wrapped))
                return wrapped(*args, **kwargs)

            with FunctionTracker(tracer, callable_name(wrapped)):
                # console.info("---------------trace func %s", callable_name(wrapped))
                return wrapped(*args, **kwargs)
예제 #4
0
    def wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()

        if tracker is None:
            return wrapped(*args, **kwargs)

        with FunctionTracker(tracker, name=name):
            callback, param_dict = wrapped(*args, **kwargs)
            return wrap_view_handler(callback, priority=priority), param_dict
예제 #5
0
파일: gen.py 프로젝트: xuning992/tfty
def _do_wrap_decorated(wrapped, instance, args, kwargs):
    """
    """
    tracker = obtain_current_tracker()

    if tracker is None:
        return wrapped(*args, **kwargs)

    with FunctionTracker(tracker, name=callable_name(wrapped)):
        return wrapped(*args, **kwargs)
예제 #6
0
        def fetchmany(self, *args, **kwargs):
            """we do not capture the metric of execute result. this is small time used
            :args:
            :kwargs:
            :return:
            """
            tracker = current_tracker()

            with FunctionTracker(tracker, callable(self.cursor.fetchone)):
                return self.cursor.fetchmany(*args, **kwargs)
예제 #7
0
def _do_http_method_trace(wrapped, instance, args, kwargs):
    """所有从用户代码开始的性能采集要从内存中获取tracker对象,而不是request对象中获取,
    后续所有的性能捕获,都需要上下文管理器修饰
    """
    tracker = obtain_tracker_from_request(instance.request)
    if not tracker:
        return wrapped(*args, **kwargs)

    tracker.set_tracker_name(object_name(wrapped), priority=3)
    with FunctionTracker(tracker, name=object_name(wrapped)):
        return wrapped(*args, **kwargs)
예제 #8
0
def _do_comon_callback_wrap(wrapped, instance, args, kwargs):
    """
    :return:
    """
    tracker = current_tracker()
    if not tracker:
        console.debug("No tracker found for tracing %s", callable_name(wrapped))
        return wrapped(*args, **kwargs)

    with FunctionTracker(tracker, callable_name(wrapped)):
        return wrapped(*args, **kwargs)
예제 #9
0
        def fetchall(self, *args, **kwargs):
            """this operation maybe spend more time. this is small time used
            and the sql was executed. we can not take it
            :args:
            :kwargs:
            :return:
            """
            tracker = current_tracker()

            with FunctionTracker(tracker, callable(self.cursor.fetchone)):
                return self.cursor.fetchall(*args, **kwargs)
예제 #10
0
    def wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()
        if not tracker:
            return wrapped(*args, **kwargs)

        tracker.set_tracker_name(callable_name(wrapped), priority=3)
        with FunctionTracker(tracker, callable_name(wrapped)):
            try:
                return wrapped(*args, **kwargs)
            except Exception as _:
                tracker.record_exception()
                raise
예제 #11
0
        def _wrapped(path):
            with FunctionTracker(tracker, name=name, label=path):
                result = wrapped(path)

                if isinstance(type(result), tuple):
                    callback, callback_args, callback_kwargs = result
                    result = (wrap_view_handler(callback, priority=4),
                              callback_args, callback_kwargs)
                else:
                    result.func = wrap_view_handler(result.func, priority=4)

                return result
예제 #12
0
    def __iter__(self):

        try:
            with FunctionTracker(self.tracer,
                                 name='Response',
                                 group='Python.WSGI'):
                for item in self.generator:
                    yield item
        except GeneratorExit:
            raise
        except:  # Catch all
            self.tracer.record_exception(*sys.exc_info())
            raise
예제 #13
0
        def wrapper(wrapped, instance, args, kwargs):
            tracker = current_tracker()
            if tracker is None:
                return wrapped(*args, **kwargs)

            before_name = "%s.%s" % (tracker.name, tracker.group)
            with FunctionTracker(tracker, name=name):
                try:
                    return wrapped(*args, **kwargs)
                finally:
                    after_name = "%s.%s" % (tracker.name, tracker.group)
                    if before_name == after_name and detect_name:
                        tracker.set_tracker_name(name, priority=2)
예제 #14
0
    def wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()

        if tracker is None:
            return wrapped(*args, **kwargs)

        tracker.set_tracker_name(name, priority=priority)
        with FunctionTracker(tracker, name=name):
            try:
                return wrapped(*args, **kwargs)
            except:  # Catch all
                tracker.record_exception(ignore_errors=should_ignore)
                raise
예제 #15
0
def _do_method_trace(wrapped, instance, args, kwargs):
    tracker = obtain_tracker_from_request(instance.request)
    if not tracker:
        return wrapped(*args, **kwargs)

    # 用户可能会重写RequestHandler中的_excute方法, 导致无法正确抓取metricName
    name = object_name(wrapped)
    http_methods = name.split(".")
    if len(http_methods) >= 2 and http_methods[-1] == instance.request.method.lower():
        tracker.set_tracker_name(name, priority=3)

    with FunctionTracker(tracker, name=name):
        return wrapped(*args, **kwargs)
예제 #16
0
    def _wrapper(wrapped, instance, args, kwargs):
        """
        :param wrapped:
        :param instance:
        :param args:
        :param kwargs:
        :return:
        """
        tracker = current_tracker()
        if not tracker:
            return wrapped(*args, **kwargs)

        tracker.set_tracker_name(callable_name(wrapped), priority=priority)
        with FunctionTracker(tracker, callable_name(wrapped)):
            return wrapped(*args, **kwargs)
예제 #17
0
    def tracker_aware(wrapped, instance, args, kwargs):
        # Variables from the outer scope are not assignable in a closure, so we use a mutable object to hold the
        # tracker, so we can change it if we need to.
        inner_tracker = tracker[0]

        if inner_tracker is not None:
            # Callback run outside the main thread must not affect the cache
            if inner_tracker.thread_id != current_thread_id():
                return fxn(*args, **kwargs)

        if inner_tracker is not None and inner_tracker._is_finalized:
            inner_tracker = None
            tracker[0] = None

        with TrackerTransferContext(inner_tracker):
            if inner_tracker is None:
                # A tracker will be None for fxns scheduled on the ioloop not associated with a tracker.
                ret = fxn(*args, **kwargs)
            elif should_trace is False:
                try:
                    ret = fxn(*args, **kwargs)
                except:
                    record_exception(sys.exc_info())
                    wrapped._nb_recorded_exception = True
                    raise

            else:
                name = object_name(fxn_for_name)
                with FunctionTracker(inner_tracker, name=name) as ft:

                    try:
                        ret = fxn(*args, **kwargs)
                    except:
                        record_exception(sys.exc_info())
                        wrapped._nb_recorded_exception = True
                        raise
                    if ft is not None and ret is not None and hasattr(
                            ret, '_nb_coroutine_name'):
                        ft.name = ret._nb_coroutine_name

                        if type(ret) == NoneProxy:
                            ret = None

        if inner_tracker and inner_tracker._ref_count == 0:
            finish_tracker(inner_tracker)

        return ret
예제 #18
0
    def wrapper(wrapped, instance, args, kwargs):
        f, fvars, fargs = args
        tracker = current_tracker()
        if not tracker:
            return wrapped(f, fvars, fargs)

        if isinstance(f, six.string_types):
            name = f
        else:
            name = callable_name(f)

        tracker.set_tracker_name(name, 2)
        with FunctionTracker(tracker, name):
            try:
                return wrapped(*args, **kwargs)
            except Exception:
                tracker.record_exception(*sys.exc_info())
                raise
예제 #19
0
def trace_handler_execute(wrapped, instance, args, kwargs):
    """
    """
    handler = instance
    request = handler.request

    tracker = current_tracker()
    if not tracker:
        return wrapped(*args, **kwargs)

    if request.method not in handler.SUPPORTED_METHODS:
        name = callable_name(wrapped)
    else:
        name = callable_name(getattr(handler, request.method.lower()))

    tracker.set_tracker_name(name, priority=3)
    with FunctionTracker(tracker, name=callable_name(wrapped)):
        return wrapped(*args, **kwargs)
예제 #20
0
    def wrapper(wrapped, instance, args, kwargs):
        name = callable_name(wrapped)
        tracker = current_tracker()

        if tracker is None:
            return wrapped(*args, **kwargs)

        def _wrapped(request, resolver, exc_info):
            tracker.set_tracker_name(name, priority=1)
            tracker.record_exception(*exc_info)

            try:
                return wrapped(request, resolver, exc_info)
            except:  # Catch all
                tracker.record_exception(*sys.exc_info())
                raise

        with FunctionTracker(tracker, name=name):
            return _wrapped(*args, **kwargs)
예제 #21
0
    def wrapper(wrapped, instance, args, kwargs):
        """More detail about the argument, read the wrapper doc
        """
        tracker = current_tracker()
        if tracker:
            return wrapped(*args, **kwargs)

        environ, start_response = parse_wsgi_protocol(target, *args, **kwargs)
        disable_agent = environ.get(AGENT_REQUEST_SWITCH, None)
        if disable_agent:
            console.debug(
                "Current trace is disabled with http request environment. %s",
                environ)
            return wrapped(*args, **kwargs)

        tracker = Tracer(proxy_instance(), environ, framework)
        tracker.start_work()

        # respect the wsgi protocol
        def _start_response(status, response_headers, *args):
            # deal the response header/data
            process_header(tracker, response_headers)
            tracker.deal_response(status, response_headers, *args)
            _write = start_response(status, response_headers, *args)

            return _write

        result = []
        try:
            tracker.set_tracker_name(callable_name(wrapped), priority=1)
            application = function_trace_wrapper(wrapped)
            with FunctionTracker(tracker,
                                 name='Application',
                                 group='Python.WSGI'):
                result = TingYunWSGIBrowserRumMiddleware(
                    tracker, application, _start_response, environ)()
                # result = application(environ, start_response)
        except:
            tracker.finish_work(*sys.exc_info())
            raise

        return WSGIApplicationResponse(tracker, result)
예제 #22
0
파일: web.py 프로젝트: xuning992/tfty
    def wrapper(wrapped, instance, args, kwargs):
        """
        """
        request = instance.request
        tracer = getattr(request, "_self_tracer", None)
        if not tracer:
            return wrapped(*args, **kwargs)

        name = callable_name(getattr(instance,
                                     instance.request.method.lower()))
        tracer.set_tracker_name(name, priority=3)

        with FunctionTracker(tracer, callable_name(wrapped)):
            thread_tracer = current_tracker()
            if thread_tracer:
                console.info(
                    "Ignore user code metric trace for current request, this will maybe cause lack of some "
                    "metric data. if this continues, please report to us, thank u."
                )
                return wrapped(*args, **kwargs)

            # at here, we get the user code. we just put the tracer to the thread for non-framework plugin use.after
            # this, we drop it again. and ignore all of the errors occurred.
            try:
                tracer.save_tracker()
            except Exception as _:
                console.error(
                    "Errors, when the tracer put into the thread, this should not occurred, if this "
                    "continues, please report to us, thank u")
            ret = wrapped(*args, **kwargs)
            try:
                tracer.drop_tracker()
            except Exception as _:
                console.error(
                    "Errors, when the tracer dropped from the thread, this should not occurred, if this "
                    "continues, please report to us, thank u")

            return ret
예제 #23
0
def setup_func_for_async_trace(request, name, group='async.wait'):
    """used to suspend function between async call with function
    thread_mode: this indicate, relate the tracer to the thread.this should be used with resume_async_trace func

    request: the HTTPRequest for connection
    """
    tracer = getattr(request, '_self_tracer', None)
    if not tracer:
        console.warning(
            "tracker lost when trace the request call chain with async, this trace for function time"
            " metric will be interrupted. %s",
            ''.join(traceback.format_stack()[:-1]))
        return

    if getattr(request, "_self_async_function_tracker", None):
        console.warning(
            "The last tracker for time metric not finished, but this should not happened."
            "this maybe some logical error in agent. %s",
            ''.join(traceback.format_stack()[:-1]))
        return

    # console.info("set func for async trace with name %s", name)
    request._self_async_function_tracker = FunctionTracker(tracer, name, group)
    request._self_async_function_tracker.__enter__()
예제 #24
0
    def dynamic_wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()
        vendor = 'RabbitMQ'
        name_type = 'Exchange'
        publish_headers = {}
        role = 'Produce'

        if not tracker:
            return wrapped(*args, **kwargs)

        def parse_server(instance,
                         exchange,
                         routing_key,
                         body,
                         properties=None,
                         *_args,
                         **_kwargs):
            """ 获取publish的一些必要信息,优先获取exchange作为metric名字
            :return:
            """
            global publish_headers
            host, port, byte, name = "Unknown", 0, 0, "Unknown"

            try:
                # blocking  和 其他异步生产者,
                connection = getattr(instance, 'connection', None) or getattr(
                    instance, '_connection', None)
                impl = getattr(connection, '_impl', None) or connection
                host = impl.params.host
                port = impl.params.port

                publish_headers = getattr(properties, "headers", {}) or {}
                ty_headers, _external_id = process_cross_trace(
                    None, msg_type='TingyunID')
                if ty_headers:
                    from pika.spec import BasicProperties

                    if not properties:
                        properties = BasicProperties(headers=ty_headers)
                    else:
                        if not getattr(properties, "headers", None):
                            setattr(properties, "headers", ty_headers)
                        elif isinstance(properties.headers, dict):
                            properties.headers.update(ty_headers)

            except Exception as err:
                console.info("Parse RabbitMQ host & port with error %s", err)
                _external_id = None

            _server = (host, port, sys.getsizeof(body), exchange
                       or routing_key, _external_id)
            return _server, exchange, routing_key, body, properties, _args, _kwargs

        server, exchange, routing_key, body, properties, _args, _kwargs = parse_server(
            instance, *args, **kwargs)
        host, port, byte, name, external_id = server
        name_type = 'Queue' if not exchange else name_type

        with MQTrace(tracker, vendor, name_type, host, port, byte, name,
                     publish_headers, role, ('BlockingChannel', 'publish'),
                     external_id):
            with FunctionTracker(tracker, callable_name(wrapped)):
                return wrapped(exchange, routing_key, body, properties, *_args,
                               **_kwargs)
예제 #25
0
def _do_method_trace(wrapped, instance, args, kwargs):
    tracker = current_tracker()

    with FunctionTracker(tracker, name=callable_name(wrapped)):
        return wrapped(*args, **kwargs)
예제 #26
0
def callback_wrapper(wrapped, instance, args, kwargs):
    """
    :return:
    """
    def parse_callback_params(_channel, _method, _properties, _body, *_args,
                              **_kwarg):
        """细节参考pika官方文档http://pika.readthedocs.io/en/0.10.0/examples/blocking_consumer_generator.html
        :return:
        """
        return _channel, _method, _properties, _body, _args, _kwarg

    def parse_server_info(ch):
        """
        :return:
        """
        try:
            connection = getattr(ch, 'connection', None) or getattr(
                ch, '_connection', None)
            impl = getattr(connection, '_impl', None) or connection
            _host = impl.params.host
            _port = impl.params.port
        except Exception as err:
            _host, _port = "Unknown", 0
            console.debug(
                "Parsing host & port failed when trace consume callback. %s, %s",
                wrapped, err)

        return _host, _port

    _ch, method, properties, body, _args, _kwarg = parse_callback_params(
        *args, **kwargs)
    tracker, is_web = retrieve_tracker(getattr(properties, "headers", {}))
    if not tracker:
        return wrapped(*args, **kwargs)

    vendor = 'RabbitMQ'
    name_type = 'Exchange' if method.exchange else "Queue"
    role = 'Consume'

    receive_headers = dict()
    receive_headers["message"] = {}
    receive_headers["message"]["message.byte"] = sys.getsizeof(body)
    receive_headers["message"]["message.queue"] = ''
    receive_headers["message"]["message.exchange"] = method.exchange
    receive_headers["message"]["message.routingkey"] = method.routing_key

    request_params = getattr(properties, "headers", {})
    receive_headers.update(request_params or {})
    host, port = parse_server_info(_ch)

    exceptions = None
    with MQTrace(tracker, vendor, name_type, host, port, sys.getsizeof(body),
                 method.exchange or method.routing_key, receive_headers, role,
                 ('', wrapped.__name__), None):
        with FunctionTracker(tracker, callable_name(wrapped)):
            try:
                result = wrapped(*args, **kwargs)
                tracker.deal_response("200 ok", {})
            except Exception as err:  # Catch all
                tracker.record_exception(*sys.exc_info())
                tracker.deal_response("500 error", {})
                exceptions = err

    # 不在web应用内
    if not is_web:
        tracker._parse_request_params(receive_headers)
        tracker.set_tracker_name(
            "%s%%2F%s" % (name_type, method.exchange or method.routing_key),
            priority=2)
        tracker.finish_work(*sys.exc_info())
    if exceptions:
        raise exceptions

    return result