Ejemplo n.º 1
0
        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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    def literal_wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()

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

        _name = name or callable_name(wrapped)

        with FunctionTracker(tracker, _name, group, label, params):
            return wrapped(*args, **kwargs)
Ejemplo n.º 4
0
def trace_wrap(wrapped, instance, args, kwargs):
    """
    """
    def _fxn_arg_extractor(fn, *args, **kwargs):
        return fn

    unwrapped_fxn = _fxn_arg_extractor(*args, **kwargs)
    wrapped_fxn = wrapped(*args, **kwargs)
    should_trace = callable_name(unwrapped_fxn) not in fxn_cache
    if should_trace:
        fxn_cache.append(callable_name(unwrapped_fxn))

    tracker_aware_fxn = create_tracker_aware_fxn(wrapped_fxn, fxn_for_name=unwrapped_fxn, should_trace=should_trace)

    if tracker_aware_fxn is None:
        return wrapped_fxn

    tracker_aware_fxn._wrapped = True
    tracker_aware_fxn._self_tracker = obtain_current_tracker()

    return tracker_aware_fxn
Ejemplo n.º 5
0
    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
    def literal_wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()

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

        _name = name or callable_name(wrapped)

        with FunctionTracker(tracker, _name, group, label, params) as ft:
            try:
                return wrapped(*args, **kwargs)
            except:
                ft.exception.append(tracker.record_exception(is_error=False))
                raise
Ejemplo n.º 7
0
def trace_handler_execute(wrapped, instance, args, kwargs):
    """
    """
    handler = instance
    request = handler.request

    if not request:
        console.warning(
            "No request instance got from handler. this maybe agent potential design issues. "
            "if this continue, please report to us.")
        return wrapped(*args, **kwargs)

    tracker = obtain_tracker_from_request(request)
    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 TrackerTransferContext(tracker):
        return wrapped(*args, **kwargs)
Ejemplo n.º 8
0
    def view_dispatch_name(instance, request, *args, **kwargs):
        """The following params in django.views.generic.base.View.dispatch
        :param instance:
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        if request.method.lower() in instance.http_method_names:
            handler = getattr(instance, request.method.lower(),
                              instance.http_method_not_allowed)
        else:
            handler = instance.http_method_not_allowed

        name = callable_name(handler)
        return name
Ejemplo n.º 9
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._self_recorded_exception = True
                    raise

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

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

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

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

        return ret
Ejemplo n.º 10
0
def trace_server_request_init_(wrapped, request, args, kwargs):
    """agent tracer entrance in tornado, will be called  after header but body. Three situations will be called.
        1. a common web.Application instance.
        2.instance passed into httpserver.HTTPServer is a not tornado application.
        3. In wsgi module. some WSGI applications.

    :param request: a `request` Instance of current user request.
    """
    result = wrapped(*args, **kwargs)

    tracker = None if is_websocket(request) else generate_tracer(request)
    if tracker:
        tracker.set_tracker_name(callable_name(wrapped), priority=1)
        tracker.start_time = getattr(request, "_start_time", int(time.time()))

    request._self_tracker = tracker
    return result
Ejemplo n.º 11
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
Ejemplo n.º 12
0
    def wrapper(wrapped):
        name = callable_name(wrapped)

        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)

        return FunctionWrapper(wrapped, wrapper)
Ejemplo n.º 13
0
def trace_urlresolvers_resolve_xxx(wrapped, priority):
    """
    :param wrapped:
    :param priority:
    :return:
    """
    name = callable_name(wrapped)

    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

    return FunctionWrapper(wrapped, wrapper)
Ejemplo n.º 14
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)
Ejemplo n.º 15
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)
Ejemplo n.º 16
0
def trace_django_urlresolvers(wrapped):
    """
    :param wrapped:
    :return:
    """
    name = callable_name(wrapped)

    def wrapper(wrapped, instance, args, kwargs):
        tracker = current_tracker()

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

        if hasattr(tracker, '_self_django_url_resolver_wrapped'):
            return wrapped(*args, **kwargs)

        # mark the top level(views maybe has inline local url resolver operate) url resolver. and use it as the
        tracker._self_django_url_resolver_wrapped = True

        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

        try:
            return _wrapped(*args, **kwargs)
        finally:
            del tracker._self_django_url_resolver_wrapped

    return FunctionWrapper(wrapped, wrapper)
Ejemplo n.º 17
0
 def _coroutine_name(func):
     return '%s %s' % (callable_name(func), '(coroutine)')
Ejemplo n.º 18
0
    def wrapper(wrapped, adapter, args, kwargs):
        """
        :param wrapped: the wrapped function `HTTPConnection._on_headers`
        :param adapter: the instance of the `HTTPConnection`
        :param args: args for `HTTPConnection._on_headers`
        :param kwargs: kwargs for `HTTPConnection._on_headers`
        :return: return of `HTTPConnection._on_headers` method
        """
        # add some ensurance for potential error, if this occurred, that indicate some wrong with last trace.
        # Then we drop the last trace and ignore this trace now.
        tracer = current_tracker()
        if tracer:
            console.warning(
                "Unexpected situation arise, but no side effect to use the agent. That's only indicate "
                "some illogicality tracker in tracer. if this continue, please report to us, thank u."
            )
            tracer.drop_tracker()
            return wrapped(*args, **kwargs)

        ret = wrapped(*args, **kwargs)

        # for version3.x.x
        if (hasattr(adapter, "stream") and adapter.stream.closed()) or \
           (hasattr(adapter, "_request_finished") and adapter._request_finished):

            # console.debug("stream closed(%s). in version 3", adapter.stream.closed())
            # console.debug("request finished. %s in version 3", adapter._request_finished)
            return ret

        # for version4.x.x
        if hasattr(adapter,
                   "connection") and adapter.connection.stream.closed():
            # console.debug("stream closed(%s). .in version 4", adapter.stream.closed())
            return ret

        # Because of the asynchronous and single thread feature. we store the tracer in the request.
        # we use _self_ to prevent conflict to the wrapped func namespace.
        # request maybe empty.
        if hasattr(adapter, "connection"):
            request = adapter.request
        else:
            request = adapter._request

        if not request or hasattr(request, '_self_tracer'):
            # console.debug("request(%s) or has _self_tracer(%s)", request, hasattr(request, '_self_tracer'))
            return ret

        # when request with no body, the wrapped function will call Application.__call__, so the tracer maybe create
        # then we should skip.
        if hasattr(request, '_self_tracer'):
            # console.info("on-header returned with request has tracer before")
            return ret

        tracer = generate_tracer(request)
        if not tracer or not tracer.enabled:
            return ret

        # iostream can not fetch the _request object, so we just set a callback to the stream associate with the request
        # with closure
        def _stream_close_callback():
            if finish_async_func_trace(request, ""):
                return

            stop_request_tracer(request, segment='stream-close-callback')

        # version 4
        if hasattr(adapter, "connection"):
            adapter.connection.stream._self_stream_close_callback = _stream_close_callback
        else:
            adapter.stream._self_stream_close_callback = _stream_close_callback

        tracer.set_tracker_name(callable_name(wrapped))
        # at the start beginning, we set the track to the request object for next call-step use
        setup_func_for_async_trace(request, "connection.header-to-body")
        return ret
Ejemplo n.º 19
0
def _do_method_trace(wrapped, instance, args, kwargs):
    tracker = current_tracker()

    with FunctionTracker(tracker, name=callable_name(wrapped)):
        return wrapped(*args, **kwargs)
Ejemplo n.º 20
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
Ejemplo n.º 21
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)