def decorator(*args, **keywords): # The type of the returned instance depends on the url # but is typically urllib.addinfourl for the baked-in protocols if context.has_state('external'): # Avoid double counting nested calls. All metrics will be reported # relative to the outermost operation return f(*args, **keywords) url = get_parameter(1, 'fullurl', *args, **keywords) if hasattr(url, 'get_full_url'): url = url.get_full_url() scheme = url.split(':')[0] if ':' in url else 'unknown' Timing.push_timer() try: context.push_state('external') telemetry.count('external.{}.requests'.format(scheme)) a = f(*args, **keywords) if a.getcode(): # Not meaningful for ftp etc telemetry.count('external.{}.status.%ixx'.format(scheme) % floor(a.getcode() / 100)) except: telemetry.count('external.{}.errors'.format(scheme)) raise finally: context.pop_state('external') elapsed, _ = Timing.pop_timer() telemetry.record('external.{}.response.latency'.format(scheme), elapsed) # Return a wrapped object so we can time subsequent read, readline etc calls return _response_wrapper(scheme, a)
def decorator(*args, **keywords): method = get_parameter(0, 'method', *args, **keywords) url = get_parameter(1, 'url', *args, **keywords) with context.add_all_tags([('external.url', url), ('external.method', method)]): telemetry.count('external.http.requests') Timing.push_timer() try: a = f(*args, **keywords) telemetry.count('external.http.status.%ixx' % floor(a.status_code / 100)) return a except: telemetry.count('external.http.errors') raise finally: elapsed, _ = Timing.pop_timer() telemetry.record('external.http.response.latency', elapsed)
def _urllib_open_wrapper(func, *args, **keywords): """ Wraps urllib.request.url_open """ if not _should_be_instrumented( state='external', enable_if='web', disable_if='model'): return func(*args, **keywords) url = get_parameter(1, 'fullurl', *args, **keywords) if hasattr(url, 'get_full_url'): url = url.get_full_url() scheme = url.split(':')[0] if ':' in url else 'unknown' Timing.push_timer() try: context.push_state('external') telemetry.count('external.{}.requests'.format(scheme)) a = func(*args, **keywords) if a.getcode(): # Not meaningful for ftp etc telemetry.count('external.{}.status.%ixx'.format(scheme) % floor(a.getcode() / 100)) except: telemetry.count('external.{}.errors'.format(scheme)) raise finally: context.pop_state('external') elapsed, _ = Timing.pop_timer() telemetry.record('external.{}.response.latency'.format(scheme), elapsed) # Return a wrapped object so we can time subsequent read, readline etc calls return _response_wrapper(scheme, a)