o
    ^۷i5                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
mZmZmZmZmZmZmZ d dlmZmZmZmZmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	l m!Z! G d
d dZ"dS )    N)Enum)Any	AwaitableCallableListOptionalSequenceUnioncast)CONTENT_TYPE_LATESTREGISTRYCollectorRegistrygenerate_latestmultiprocess)	Starlette)Request)Response)metrics)"PrometheusInstrumentatorMiddlewarec                   @   sF  e Zd Zdddddddg g dddddfdeded	ed
ededededee dee dededededeedf ddfddZ						d0de
dedededeeeef  d eeeef  dd fd!d"Z		#		d1de
d$ed%ed&ed'eeeeef   d(edd fd)d*Zd+eeejgeded f f  dd fd,d-Zdefd.d/ZdS )2PrometheusFastApiInstrumentatorTF   ENABLE_METRICShttp_requests_inprogressNshould_group_status_codesshould_ignore_untemplatedshould_group_untemplatedshould_round_latency_decimalsshould_respect_env_var%should_instrument_requests_inprogress!should_exclude_streaming_durationexcluded_handlersbody_handlersround_latency_decimalsenv_var_nameinprogress_nameinprogress_labelsregistryreturnc                 C   s   || _ || _|| _|| _|| _|| _|| _|
| _|| _|| _	|| _
dd |D | _dd |	D | _g | _g | _dtjv rOdtjvrOtjd tjd< tdt |rU|| _nt| _dtjv rptjd }tj|srtd| dd	S d	S )
a  Create a Prometheus FastAPI (and Starlette) Instrumentator.

        Args:
            should_group_status_codes (bool): Should status codes be grouped into
                `2xx`, `3xx` and so on? Defaults to `True`.

            should_ignore_untemplated (bool): Should requests without a matching
                template be ignored? Defaults to `False`. This means that by
                default a request like `curl -X GET localhost:80/doesnotexist`
                will be ignored.

            should_group_untemplated (bool): Should requests without a matching
                template be grouped to handler `none`? Defaults to `True`.

            should_round_latency_decimals: Should recorded latencies be
                rounded to a certain number of decimals?

            should_respect_env_var (bool): Should the instrumentator only work - for
                example the methods `instrument()` and `expose()` - if a
                certain environment variable is set to `true`? Usecase: A base
                FastAPI app that is used by multiple distinct apps. The apps
                only have to set the variable to be instrumented. Defaults to
                `False`.

            should_instrument_requests_inprogress (bool): Enables a gauge that shows
                the inprogress requests. See also the related args starting
                with `inprogress`. Defaults to `False`.

            should_exclude_streaming_duration: Should the streaming duration be
                excluded? Only relevant if default metrics are used. Defaults
                to `False`.

            excluded_handlers (List[str]): List of strings that will be compiled
                to regex patterns. All matches will be skipped and not
                instrumented. Defaults to `[]`.

            body_handlers (List[str]): List of strings that will be compiled
                to regex patterns to match handlers for the middleware to
                pass through response bodies to instrumentations. So only
                relevant for instrumentations that access `info.response.body`.
                Note that this has a noticeable negative impact on performance
                with responses larger than a few MBs. Defaults to `[]`.

            round_latency_decimals (int): Number of decimals latencies should be
                rounded to. Ignored unless `should_round_latency_decimals` is
                `True`. Defaults to `4`.

            env_var_name (str): Any valid os environment variable name that will
                be checked for existence before instrumentation. Ignored unless
                `should_respect_env_var` is `True`. Defaults to `"ENABLE_METRICS"`.

            inprogress_name (str): Name of the gauge. Defaults to
                `http_requests_inprogress`. Ignored unless
                `should_instrument_requests_inprogress` is `True`.

            inprogress_labels (bool): Should labels `method` and `handler` be
                part of the inprogress label? Ignored unless
                `should_instrument_requests_inprogress` is `True`. Defaults to `False`.

            registry (CollectorRegistry): A custom Prometheus registry to use. If not
                provided, the default `REGISTRY` will be used. This can be useful if
                you need to run multiple apps at the same time, with their own
                registries, for example during testing.

        Raises:
            ValueError: If `PROMETHEUS_MULTIPROC_DIR` env var is found but
                doesn't point to a valid directory.
        c                 S      g | ]}t |qS  recompile.0pathr)   r)   g/home/ubuntu/vllm_env/lib/python3.10/site-packages/prometheus_fastapi_instrumentator/instrumentation.py
<listcomp>       z<PrometheusFastApiInstrumentator.__init__.<locals>.<listcomp>c                 S   r(   r)   r*   r-   r)   r)   r0   r1      r2   prometheus_multiproc_dirPROMETHEUS_MULTIPROC_DIRzpprometheus_multiproc_dir variable has been deprecated in favor of the upper case naming PROMETHEUS_MULTIPROC_DIRz"Env var PROMETHEUS_MULTIPROC_DIR='z' not a directory.N)r   r   r   r   r   r   r   r"   r#   r$   r%   r    r!   instrumentationsasync_instrumentationsosenvironwarningswarnDeprecationWarningr&   r   r/   isdir
ValueError)selfr   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   pmdr)   r)   r0   __init__   sF   V





z(PrometheusFastApiInstrumentator.__init__ g{Gz?g?g?g333333?皙?g      ?      ?g      ?   g      ?   g      @   g      @r   g      @   g      @
      <   rC   rD   rE   appmetric_namespacemetric_subsystem!should_only_respect_2xx_for_highrlatency_highr_bucketslatency_lowr_bucketsc                 C   s   | j r	|  s	| S |jtfi d| jd| jd| jd| jd| j d| jd| j	d| j
d	| jd
| jd| jd| jd| jd| jd| jd|d|d|d|d|d| j | S )a  Performs the instrumentation by adding middleware.

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

        Args:
            app: Starlette app instance. Note that every FastAPI app is a
                Starlette app.

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

        Returns:
            self: Instrumentator. Builder Pattern.
        r   r   r   r   r   r   r   r"   r#   r$   r%   r5   r6   r    r!   rN   rO   rP   rQ   rR   r&   )r   _should_instrumentateadd_middlewarer   r   r   r   r   r   r   r"   r#   r$   r%   r5   r6   r    r!   r&   )r>   rM   rN   rO   rP   rQ   rR   r)   r)   r0   
instrument   s`   .	
z*PrometheusFastApiInstrumentator.instrument/metricsshould_gzipendpointinclude_in_schematagskwargsc                    s    j r	  s	 S dtdtf fdd}d}tjdr:ddlm}	 t	||	r:|}
|
j
|f||d	|| d
}|sD|j|||d  S )a  Exposes endpoint for metrics.

        Args:
            app: App instance. Endpoint will be added to this app. This can be
            a Starlette app or a FastAPI app. If it is a Starlette app, `tags`
            `kwargs` will be ignored.

            should_gzip: Should the endpoint return compressed data? It will
                also check for `gzip` in the `Accept-Encoding` header.
                Compression consumes more CPU cycles. In most cases it's best
                to just leave this option off since network bandwidth is usually
                cheaper than CPU cycles. Defaults to `False`.

            endpoint: Endpoint on which metrics should be exposed.

            include_in_schema: Should the endpoint show up in the documentation?

            tags (List[str], optional): If you manage your routes with tags.
                Defaults to None. Only passed to FastAPI app.

            kwargs: Will be passed to app. Only passed to FastAPI app.

        Returns:
            self: Instrumentator. Builder Pattern.
        requestr'   c                    s~    j }dtjv rt }t| r1d| jddv r1tt	
t|d}t|jd< d|jd< |S tt|d}t|jd< |S )z(Endpoint that serves Prometheus metrics.r4   gzipzAccept-EncodingrA   )contentzContent-TypezContent-Encoding)r&   r7   r8   r   r   MultiProcessCollectorheadersgetr   r]   compressr   r   )r\   ephemeral_registryrespr>   rW   r)   r0   r     s   




z7PrometheusFastApiInstrumentator.expose.<locals>.metricsFfastapir   )FastAPI)rY   rZ   T)r/   routerY   )r   rS   r   r   	importlibutil	find_specrf   rg   
isinstancera   	add_route)r>   rM   rW   rX   rY   rZ   r[   r   route_configuredrg   fastapi_appr)   re   r0   expose   s.   #
z&PrometheusFastApiInstrumentator.exposeinstrumentation_functionc                 G   s^   |D ]*}|r,t |r| jtttjgtd f | q| j	tttjgdf | q| S )av  Adds function to list of instrumentations.

        Args:
            instrumentation_function: Function
                that will be executed during every request handler call (if
                not excluded). See above for detailed information on the
                interface of the function.

        Returns:
            self: Instrumentator. Builder Pattern.
        N)
asyncioiscoroutinefunctionr6   appendr
   r   r   Infor   r5   )r>   rq   funcr)   r)   r0   add3  s   
z#PrometheusFastApiInstrumentator.addc                 C   s   t | jd dv S )z?Checks if instrumentation should be performed based on env var.False)true1)r7   getenvr#   lower)r>   r)   r)   r0   rS   U  s   z5PrometheusFastApiInstrumentator._should_instrumentate)rA   rA   FrB   rL   )FrV   TN)__name__
__module____qualname__boolr   strintr	   r   r@   r   r   floatrU   r   r   r   rp   r   r   ru   r   rw   rS   r)   r)   r)   r0   r      s    	


 
N
K
"r   )#rr   r]   importlib.utilri   r7   r+   r9   enumr   typingr   r   r   r   r   r   r	   r
   prometheus_clientr   r   r   r   r   starlette.applicationsr   starlette.requestsr   starlette.responsesr   !prometheus_fastapi_instrumentatorr   ,prometheus_fastapi_instrumentator.middlewarer   r   r)   r)   r)   r0   <module>   s    (