def test_default():
    app = create_app()
    Instrumentator().add(metrics.default()).instrument(app).expose(app)
    client = TestClient(app)

    client.get("/", data="fefeef")
    client.get("/")

    _ = get_response(client, "/metrics")

    assert (REGISTRY.get_sample_value(
        "http_requests_total",
        {
            "handler": "/",
            "method": "GET",
            "status": "2xx"
        },
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_request_size_bytes_sum",
        {"handler": "/"},
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_response_size_bytes_sum",
        {"handler": "/"},
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_request_duration_highr_seconds_sum",
        {},
    ) > 0)
    assert (REGISTRY.get_sample_value(
        "http_request_duration_seconds_sum",
        {"handler": "/"},
    ) > 0)
def test_default_should_only_respect_2xx_for_highr():
    app = create_app()
    Instrumentator(excluded_handlers=["/metrics"]).add(
        metrics.default(should_only_respect_2xx_for_highr=True)).instrument(
            app).expose(app)
    client = TestClient(app)

    client.get("/efefewffe", data="fefeef")
    client.get("/ffe04904nfiuo-ni")

    response = get_response(client, "/metrics")

    assert b"http_request_duration_highr_seconds_count 0.0" in response.content
示例#3
0
    def instrument(self, app: FastAPI):
        """Performs the instrumentation by adding middleware.

        The middleware iterates through all `instrumentations` and execute them.

        Args:
            app: FastAPI app instance.

        Raises:
            e: Only raised if FastAPI itself throws an exception.

        Returns:
            self: Instrumentator. Builder Pattern.
        """

        if (self.should_respect_env_var
                and os.environ.get(self.env_var_name, "false") != "true"):
            return self

        if len(self.instrumentations) == 0:
            self.instrumentations.append(metrics.default())

        self.inprogress = None
        if self.should_instrument_requests_inprogress:
            labels = ((
                "method",
                "handler",
            ) if self.inprogress_labels else ())
            self.inprogress = Gauge(
                name=self.inprogress_name,
                documentation="Number of HTTP requests in progress.",
                labelnames=labels,
                multiprocess_mode="livesum",
            )

        @app.middleware("http")
        async def dispatch_middleware(request: Request, call_next) -> Response:
            start_time = default_timer()

            handler, is_templated = self._get_handler(request)
            is_excluded = self._is_handler_excluded(handler, is_templated)
            handler = ("none" if not is_templated
                       and self.should_group_untemplated else handler)

            if not is_excluded and self.should_instrument_requests_inprogress:
                if self.inprogress_labels:
                    inprogress = self.inprogress.labels(
                        request.method, handler)
                else:
                    inprogress = self.inprogress
                inprogress.inc()

            try:
                response = None
                response = await call_next(request)
                status = str(response.status_code)
            except Exception as e:
                if response is None:
                    status = "500"
                raise e from None
            finally:
                if not is_excluded:
                    duration = max(default_timer() - start_time, 0)

                    if self.should_instrument_requests_inprogress:
                        inprogress.dec()

                    if self.should_round_latency_decimals:
                        duration = round(duration, self.round_latency_decimals)

                    if self.should_group_status_codes:
                        status = status[0] + "xx"

                    info = metrics.Info(
                        request=request,
                        response=response,
                        method=request.method,
                        modified_handler=handler,
                        modified_status=status,
                        modified_duration=duration,
                    )

                    for instrumentation in self.instrumentations:
                        instrumentation(info)

            return response

        return self
    def instrument(self, app: FastAPI) -> "self":
        """Performs the instrumentation by adding middleware.

        The middleware iterates through all `instrumentations` and execute them.

        Args:
            app: FastAPI app instance.

        Raises:
            e: Only raised if FastAPI itself throws an exception.

        Returns:
            self: Instrumentator. Builder Pattern.
        """

        if (
            self.should_respect_env_var
            and os.environ.get(self.env_var_name, "false") != "true"
        ):
            return self

        if len(self.instrumentations) == 0:
            self.instrumentations.append(metrics.default())

        @app.middleware("http")
        async def dispatch_middleware(request: Request, call_next) -> Response:
            start_time = default_timer()

            try:
                response = None
                response = await call_next(request)
                status = str(response.status_code)
            except Exception as e:
                if response is None:
                    status = "500"
                raise e from None
            finally:
                handler, is_templated = self._get_handler(request)

                if not self._is_handler_excluded(handler, is_templated):
                    duration = max(default_timer() - start_time, 0)

                    if self.should_round_latency_decimals:
                        duration = round(duration, self.round_latency_decimals)

                    if is_templated is False and self.should_group_untemplated:
                        handler = "none"

                    if self.should_group_status_codes:
                        status = status[0] + "xx"

                    info = metrics.Info(
                        request=request,
                        response=response,
                        method=request.method,
                        modified_handler=handler,
                        modified_status=status,
                        modified_duration=duration,
                    )

                    for instrumentation in self.instrumentations:
                        instrumentation(info)

            return response

        return self