예제 #1
0
    def instrument_stdlib_urllib(self, module):
        def wrapper(wrapped, instance, args, kwargs):
            http_class, req = args
            status = None
            if ((capture_hosts.get("*", False)
                 or capture_hosts.get(req.host.lower(), False))
                    and not ignore_hosts.get(req.host.lower(), False)):
                with self.span("http") as span:
                    try:
                        response = wrapped(*args, **kwargs)
                        return response
                    finally:
                        if response:
                            status = response.code
                            span.set_tag("requestHostname", req.host.lower())
                            span.set_tag("requestPath",
                                         urlparse(req.get_full_url()).path)
                            span.set_tag("httpMethod", req.get_method())
                            span.set_tag("httpStatus", status)
            else:
                return wrapped(*args, **kwargs)

        try:
            wrapt.wrap_function_wrapper(module, "AbstractHTTPHandler.do_open",
                                        wrapper)
        except ImportError:
            pass
예제 #2
0
    def instrument_botocore(self):
        def wrapper(wrapped, instance, args, kwargs):
            with self.span("aws") as span:
                try:
                    response = wrapped(*args, **kwargs)
                    return response
                except Exception as error:
                    response = error.response
                    raise error
                finally:
                    span.set_tag("requestHostname",
                                 instance._endpoint.host.split("://")[1])
                    span.set_tag(
                        "aws",
                        {
                            "region":
                            instance.meta.region_name,
                            "service":
                            instance._service_model.service_name,
                            "operation":
                            args[0],
                            "requestId":
                            response.get("ResponseMetadata",
                                         {}).get("RequestId"),
                            "errorCode":
                            response.get("Error", {}).get("Code"),
                        },
                    )

        try:
            wrapt.wrap_function_wrapper("botocore.client",
                                        "BaseClient._make_api_call", wrapper)
        except ImportError:
            pass
예제 #3
0
    def instrument_urllib3(self):
        def wrapper(wrapped, instance, args, kwargs):
            if "method" in kwargs:
                method = kwargs["method"]
            else:
                method = args[0]
            if "url" in kwargs:
                path = kwargs["url"]
            else:
                path = args[1]
            user_agent = kwargs.get("headers", {}).get("User-Agent", "")
            # sometimes ua is binary string sometimes a normal string :/
            if hasattr(user_agent, "decode"):
                user_agent = user_agent.decode()
            status = None
            if (
                (
                    # Ignore http calls from boto
                    not user_agent.startswith("Boto3")
                    or os.environ.get(
                        "SERVERLESS_ENTERPRISE_SPANS_CAPTURE_AWS_SDK_HTTP"
                    )
                )
                and (
                    capture_hosts.get("*", False)
                    or capture_hosts.get(instance.host.lower(), False)
                )
                and not ignore_hosts.get(instance.host.lower(), False)
            ):
                with self.span("http") as span:
                    span.set_tag("requestHostname", instance.host)
                    span.set_tag("requestPath", path)
                    span.set_tag("httpMethod", method)
                    try:
                        response = wrapped(*args, **kwargs)
                        return response
                    except Exception as e:
                        response = None
                        span.set_tag("httpStatus", "Exc")
                        raise e
                    finally:
                        if response:
                            span.set_tag("httpStatus", response.status)
            else:
                return wrapped(*args, **kwargs)

        try:
            wrapt.wrap_function_wrapper(
                "urllib3.connectionpool", "HTTPConnectionPool.urlopen", wrapper
            )
        except ImportError:
            pass
        try:
            wrapt.wrap_function_wrapper(
                "botocore.vendored.requests.packages.urllib3.connectionpool",
                "HTTPConnectionPool.urlopen",
                wrapper,
            )
        except ImportError:
            pass
예제 #4
0
    def instrument_flask(self, module):
        def wrap_add_url_rule(wrapped, app, args, kwargs):
            args = list(args)
            rule = args.pop(0)
            try:
                endpoint = kwargs.pop('endpoint')
            except KeyError:
                endpoint = args.pop(0)
            try:
                view_func = kwargs.pop('view_func')
            except KeyError:
                view_func = args.pop(0)

            def wrap_view_func(**req_args):
                try:
                    return view_func(**req_args)
                finally:
                    try:
                        from flask import request
                        set_endpoint(rule,
                                     http_method=request.method,
                                     meta={"mechanism": "flask-middleware"})
                    except:
                        pass

            wrap_view_func.__name__ = view_func.__name__
            return wrapped(rule, endpoint, wrap_view_func, *args, **kwargs)

        def wrap_init(wrapped, app, args, kwargs):
            wrapped(*args, **kwargs)
            try:

                def after(response):
                    try:
                        from flask import request
                        try:
                            status = response.status_code.value  # http.HTTPStatus?
                        except:
                            status = response.status_code or response.default_status
                        path = request.path if status == 404 or status >= 500 else None
                        set_endpoint(path,
                                     http_method=request.method,
                                     http_status_code=status,
                                     meta={"mechanism": "flask-middleware"})
                    except:
                        pass
                    return response

                app.after_request(after)
            except:
                pass

        try:
            wrapt.wrap_function_wrapper(module, "Flask.add_url_rule",
                                        wrap_add_url_rule)
            wrapt.wrap_function_wrapper(module, "Flask.__init__", wrap_init)
        except ImportError:
            pass
예제 #5
0
    def instrument_botocore(self):
        def wrapper(wrapped, instance, args, kwargs):
            start_isoformat = datetime.utcnow().isoformat() + 'Z'
            start = time.time()
            try:
                response = wrapped(*args, **kwargs)
                return response
            except Exception as error:
                response = error.response
                raise error
            finally:
                end_isoformat = datetime.utcnow().isoformat() + 'Z'
                self.spans.append({
                    "tags": {
                        "type": "aws",
                        "requestHostname":
                        instance._endpoint.host.split("://")[1],
                        "aws": {
                            "region":
                            instance.meta.region_name,
                            "service":
                            instance._service_model.service_name,
                            "operation":
                            args[0],
                            "requestId":
                            response.get("ResponseMetadata",
                                         {}).get("RequestId"),
                            "errorCode":
                            response.get("Error", {}).get("Code"),
                        },
                    },
                    "startTime":
                    start_isoformat,
                    "endTime":
                    end_isoformat,
                    "duration":
                    int((time.time() - start) * 1000),
                })

        wrapt.wrap_function_wrapper(
            'botocore.client',
            'BaseClient._make_api_call',
            wrapper,
        )
예제 #6
0
    def instrument_flask(self, module):
        def wrap_init(wrapped, app, args, kwargs):
            wrapped(*args, **kwargs)
            app_dispatch_request = app.dispatch_request

            def dispatch_request(self):
                try:
                    from flask import _request_ctx_stack
                    req = _request_ctx_stack.top.request
                    set_endpoint(endpoint=req.url_rule.rule,
                                 meta={"mechanism": "flask-middleware"})
                except:
                    pass
                return app_dispatch_request()

            from types import MethodType
            app.dispatch_request = MethodType(dispatch_request, app)

            try:

                def after(response):
                    try:
                        from flask import request
                        try:
                            status = response.status_code.value  # http.HTTPStatus?
                        except:
                            status = response.status_code or response.default_status
                        set_endpoint(endpoint=None,
                                     http_method=request.method,
                                     http_status_code=status,
                                     meta={"mechanism": "flask-middleware"})
                    except:
                        pass
                    return response

                app.after_request(after)
            except:
                pass

        try:
            wrapt.wrap_function_wrapper(module, "Flask.__init__", wrap_init)
        except ImportError:
            pass