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)
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)
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)
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
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)
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)
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)
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)
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)
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
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
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
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)
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
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)
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)
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
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
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)
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)
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)
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 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__()
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)
def _do_method_trace(wrapped, instance, args, kwargs): tracker = current_tracker() with FunctionTracker(tracker, name=callable_name(wrapped)): return wrapped(*args, **kwargs)
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