o
    QDi                     @   s   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 d dlmZ zd dl	m
Z
 W n ey9   d dlm
Z
 Y nw e eZdddZG d	d
 d
ejZdddZdd Zdd ZdS )    N)settings)HttpResponse)multiprocess)
HTTPServer c                 C   s*   t jddksJ dtj| |d dS )a  Exports Prometheus metrics on an HTTPServer running in its own thread.

    The server runs on the given port and is by default listenning on
    all interfaces. This HTTPServer is fully independent of Django and
    its stack. This offers the advantage that even if Django becomes
    unable to respond, the HTTPServer will continue to function and
    export metrics. However, this also means that the features
    offered by Django (like middlewares or WSGI) can't be used.

    Now here's the really weird part. When Django runs with the
    auto-reloader enabled (which is the default, you can disable it
    with `manage.py runserver --noreload`), it forks and executes
    manage.py twice. That's wasteful but usually OK. It starts being a
    problem when you try to open a port, like we do. We can detect
    that we're running under an autoreloader through the presence of
    the RUN_MAIN environment variable, so we abort if we're trying to
    export under an autoreloader and trying to open a port.
    RUN_MAINtrueThe thread-based exporter can't be safely used when django's autoreloader is active. Use the URL exporter, or start django with --noreload. See documentation/exports.md.)addrN)osenvirongetprometheus_clientstart_http_server)portr
    r   R/var/www/Datamplify/venv/lib/python3.10/site-packages/django_prometheus/exports.pySetupPrometheusEndpointOnPort   s   r   c                       s(   e Zd ZdZ fddZdd Z  ZS )PrometheusEndpointServerz?A thread class that holds an http and makes it serve_forever().c                    s   || _ t j|i | d S N)httpdsuper__init__)selfr   argskwargs	__class__r   r   r   3   s   z!PrometheusEndpointServer.__init__c                 C   s   | j   d S r   )r   serve_forever)r   r   r   r   run7   s   zPrometheusEndpointServer.run)__name__
__module____qualname____doc__r   r   __classcell__r   r   r   r   r   0   s    r   c              	   C   s   t jddksJ d| D ],}z
t||ftj}W n	 ty#   Y qw t|}d|_|	  t
d|  |  S t
d dS )a  Like SetupPrometheusEndpointOnPort, but tries several ports.

    This is useful when you're running Django as a WSGI application
    with multiple processes and you want Prometheus to discover all
    workers. Each worker will grab a port and you can use Prometheus
    to aggregate across workers.

    port_range may be any iterable object that contains a list of
    ports. Typically this would be a `range` of contiguous ports.

    As soon as one port is found that can serve, use this one and stop
    trying.

    Returns the port chosen (an `int`), or `None` if no port in the
    supplied range was available.

    The same caveats regarding autoreload apply. Do not use this when
    Django's autoreloader is active.
    r   r   r	   Tz'Exporting Prometheus /metrics/ on port zICannot export Prometheus /metrics/ - no available ports in supplied rangeN)r   r   r   r   r   MetricsHandlerOSErrorr   daemonstartloggerinfowarning)
port_ranger
   r   r   threadr   r   r   "SetupPrometheusEndpointOnPortRange;   s    
r.   c                  C   sL   t tdd} t tdd}t tdd}|rt|| dS | r$t| | dS dS )z/Exports metrics so Prometheus can collect them.PROMETHEUS_METRICS_EXPORT_PORTN$PROMETHEUS_METRICS_EXPORT_PORT_RANGE!PROMETHEUS_METRICS_EXPORT_ADDRESSr   )getattrr   r.   r   )r   r,   r
   r   r   r    SetupPrometheusExportsFromConfigd   s   r3   c                 C   sF   dt jv s
dt jv rt }t| ntj}t|}t|tj	dS )zmExports /metrics as a Django view.

    You can use django_prometheus.urls to map /metrics to this view.
    PROMETHEUS_MULTIPROC_DIRprometheus_multiproc_dir)content_type)
r   r   r   CollectorRegistryr   MultiProcessCollectorREGISTRYgenerate_latestr   CONTENT_TYPE_LATEST)requestregistrymetrics_pager   r   r   ExportToDjangoViewo   s   
r?   )r   )loggingr   	threadingr   django.confr   django.httpr   r   BaseHTTPServerr   ImportErrorhttp.server	getLoggerr    r)   r   Threadr   r.   r3   r?   r   r   r   r   <module>   s$    


)