|
| 1 | +from __future__ import absolute_import |
| 2 | +import wrapt |
| 3 | + |
| 4 | +import opentracing as ot |
| 5 | +import opentracing.ext.tags as tags |
| 6 | + |
| 7 | +from ..log import logger |
| 8 | +from ..singletons import agent, tracer |
| 9 | +from ..util import strip_secrets |
| 10 | + |
| 11 | + |
| 12 | +try: |
| 13 | + import webapp2 |
| 14 | + |
| 15 | + logger.debug("Instrumenting webapp2") |
| 16 | + |
| 17 | + @wrapt.patch_function_wrapper('webapp2', 'WSGIApplication.__call__') |
| 18 | + def call_with_instana(wrapped, instance, argv, kwargs): |
| 19 | + env = argv[0] |
| 20 | + start_response = argv[1] |
| 21 | + |
| 22 | + def new_start_response(status, headers, exc_info=None): |
| 23 | + """Modified start response with additional headers.""" |
| 24 | + if 'stan_scope' in env: |
| 25 | + scope = env['stan_scope'] |
| 26 | + tracer.inject(scope.span.context, ot.Format.HTTP_HEADERS, headers) |
| 27 | + headers.append(('Server-Timing', "intid;desc=%s" % scope.span.context.trace_id)) |
| 28 | + |
| 29 | + res = start_response(status, headers, exc_info) |
| 30 | + |
| 31 | + sc = status.split(' ')[0] |
| 32 | + if 500 <= int(sc) <= 511: |
| 33 | + scope.span.set_tag("error", True) |
| 34 | + ec = scope.span.tags.get('ec', 0) |
| 35 | + scope.span.set_tag("ec", ec+1) |
| 36 | + |
| 37 | + scope.span.set_tag(tags.HTTP_STATUS_CODE, sc) |
| 38 | + scope.close() |
| 39 | + return res |
| 40 | + else: |
| 41 | + return start_response(status, headers, exc_info) |
| 42 | + |
| 43 | + ctx = tracer.extract(ot.Format.HTTP_HEADERS, env) |
| 44 | + scope = env['stan_scope'] = tracer.start_active_span("wsgi", child_of=ctx) |
| 45 | + |
| 46 | + if agent.extra_headers is not None: |
| 47 | + for custom_header in agent.extra_headers: |
| 48 | + # Headers are available in this format: HTTP_X_CAPTURE_THIS |
| 49 | + wsgi_header = ('HTTP_' + custom_header.upper()).replace('-', '_') |
| 50 | + if wsgi_header in env: |
| 51 | + scope.span.set_tag("http.%s" % custom_header, env[wsgi_header]) |
| 52 | + |
| 53 | + if 'PATH_INFO' in env: |
| 54 | + scope.span.set_tag('http.path', env['PATH_INFO']) |
| 55 | + if 'QUERY_STRING' in env and len(env['QUERY_STRING']): |
| 56 | + scrubbed_params = strip_secrets(env['QUERY_STRING'], agent.secrets_matcher, agent.secrets_list) |
| 57 | + scope.span.set_tag("http.params", scrubbed_params) |
| 58 | + if 'REQUEST_METHOD' in env: |
| 59 | + scope.span.set_tag(tags.HTTP_METHOD, env['REQUEST_METHOD']) |
| 60 | + if 'HTTP_HOST' in env: |
| 61 | + scope.span.set_tag("http.host", env['HTTP_HOST']) |
| 62 | + |
| 63 | + return wrapped(env, new_start_response) |
| 64 | +except ImportError: |
| 65 | + pass |
0 commit comments