o
    pix                     @   s   U d Z ddlZddl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mZmZmZmZm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mZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 ee4Z5ee'e)e(e*e+e,e-f Z6G dd deZ7G dd de7Z8G dd de7Z9eG dd dZ:G dd deZ;G dd de;Z<G dd de;Z=e/ Z>da?ee7 e@d< e9 ZA				d-deBdeBd ee7 d!eeB d"ee3 d#dfd$d%ZCd e7d&eDd#dfd'd(ZEd e7d#dfd)d*ZFd#e7fd+d,ZGdS ).a  
The OpenTelemetry metrics API  describes the classes used to generate
metrics.

The :class:`.MeterProvider` provides users access to the :class:`.Meter` which in
turn is used to create :class:`.Instrument` objects. The :class:`.Instrument` objects are
used to record measurements.

This module provides abstract (i.e. unimplemented) classes required for
metrics, and a concrete no-op implementation :class:`.NoOpMeter` that allows applications
to use the API package alone without a supporting implementation.

To get a meter, you need to provide the package name from which you are
calling the meter APIs to OpenTelemetry by calling `MeterProvider.get_meter`
with the calling instrumentation name and the version of your package.

The following code shows how to obtain a meter using the global :class:`.MeterProvider`::

    from opentelemetry.metrics import get_meter

    meter = get_meter("example-meter")
    counter = meter.create_counter("example-counter")

.. versionadded:: 1.10.0
    N)ABCabstractmethod)	dataclass)	getLogger)environ)Lock)DictListOptionalSequenceUnioncast)OTEL_PYTHON_METER_PROVIDER)	CallbackTCounterGauge	HistogramNoOpCounter	NoOpGaugeNoOpHistogramNoOpObservableCounterNoOpObservableGaugeNoOpObservableUpDownCounterNoOpUpDownCounterObservableCounterObservableGaugeObservableUpDownCounterUpDownCounter_MetricsHistogramAdvisory_ProxyCounter_ProxyGauge_ProxyHistogram_ProxyObservableCounter_ProxyObservableGauge_ProxyObservableUpDownCounter_ProxyUpDownCounter)Once)_load_provider)
Attributesc                   @   sF   e Zd ZdZe			ddedee dee dee ddf
d	d
ZdS )MeterProviderz_
    MeterProvider is the entry point of the API. It provides access to `Meter` instances.
    Nnameversion
schema_url
attributesreturnMeterc                 C      dS )aF  Returns a `Meter` for use by the given instrumentation library.

        For any two calls it is undefined whether the same or different
        `Meter` instances are returned, even for different library names.

        This function may return different `Meter` types (e.g. a no-op meter
        vs. a functional meter).

        Args:
            name: The name of the instrumenting module.
                ``__name__`` should be avoided as this can result in
                different meter names if the meters are in different files.
                It is better to use a fixed string that can be imported where
                needed and used consistently as the name of the meter.

                This should *not* be the name of the module that is
                instrumented but the name of the module doing the instrumentation.
                E.g., instead of ``"requests"``, use
                ``"opentelemetry.instrumentation.requests"``.

            version: Optional. The version string of the
                instrumenting library.  Usually this should be the same as
                ``importlib.metadata.version(instrumenting_library_name)``.

            schema_url: Optional. Specifies the Schema URL of the emitted telemetry.
            attributes: Optional. Attributes that are associated with the emitted telemetry.
        N selfr*   r+   r,   r-   r1   r1   \/home/ubuntu/.local/lib/python3.10/site-packages/opentelemetry/metrics/_internal/__init__.py	get_meterg       zMeterProvider.get_meterNNN)	__name__
__module____qualname____doc__r   strr
   r(   r5   r1   r1   r1   r4   r)   b   s"    r)   c                   @   sB   e Zd ZdZ			ddedee dee dee ddf
d	d
ZdS )NoOpMeterProviderzQThe default MeterProvider used when no MeterProvider implementation is available.Nr*   r+   r,   r-   r.   r/   c                 C   s   t |||dS )zReturns a NoOpMeter.r+   r,   )	NoOpMeterr2   r1   r1   r4   r5      s   zNoOpMeterProvider.get_meterr7   )r8   r9   r:   r;   r<   r
   r(   r5   r1   r1   r1   r4   r=      s     r=   c                   @   sZ   e Zd ZdddZ			ddedee dee dee dd	f
d
dZdeddfddZ	dS )_ProxyMeterProviderr.   Nc                 C   s   t  | _g | _d | _d S N)r   _lock_meters_real_meter_providerr3   r1   r1   r4   __init__   s   
z_ProxyMeterProvider.__init__r*   r+   r,   r-   r/   c                 C   sp   | j + | jd ur| j|||W  d    S t|||d}| j| |W  d    S 1 s1w   Y  d S Nr>   )rB   rD   r5   _ProxyMeterrC   append)r3   r*   r+   r,   r-   meterr1   r1   r4   r5      s   
$z_ProxyMeterProvider.get_metermeter_providerc                 C   sH   | j  || _| jD ]}|| q
W d    d S 1 sw   Y  d S rA   )rB   rD   rC   on_set_meter_provider)r3   rK   rJ   r1   r1   r4   rL      s   
"z)_ProxyMeterProvider.on_set_meter_providerr.   Nr7   )
r8   r9   r:   rF   r<   r
   r(   r5   r)   rL   r1   r1   r1   r4   r@      s"    

r@   c                   @   s2   e Zd ZU eed< eed< eed< ee ed< dS )_InstrumentRegistrationStatusinstrument_idalready_registeredconflictcurrent_advisoryN)r8   r9   r:   r<   __annotations__boolr
   r   r1   r1   r1   r4   rN      s
   
 rN   c                       s  e Zd ZdZ		d+dedee dee ddf fddZedefd	d
Zedee fddZ	edee fddZ
	d,dededededee defddZededededededdfddZe		d-dedededefddZe		d-dedededefddZe			d.dedeee  dededef
dd Ze		d-dd!dededed"eee  def
d#d$Z		d-dedededefd%d&Ze			d.dedeee  dededef
d'd(Z e			d.dedeee  dedede!f
d)d*Z"  Z#S )/r/   zHandles instrument creation.

    This class provides methods for creating instruments which are then
    used to produce measurements.
    Nr*   r+   r,   r.   c                    s.   t    || _|| _|| _i | _t | _d S rA   )superrF   _name_version_schema_url_instrument_idsr   _instrument_ids_lockr3   r*   r+   r,   	__class__r1   r4   rF      s   
zMeter.__init__c                 C      | j S )z7
        The name of the instrumenting module.
        )rV   rE   r1   r1   r4   r*         z
Meter.namec                 C   r^   )zB
        The version string of the instrumenting library.
        )rW   rE   r1   r1   r4   r+      r_   zMeter.versionc                 C   r^   )zC
        Specifies the Schema URL of the emitted telemetry
        )rX   rE   r1   r1   r4   r,      r_   zMeter.schema_urltype_unitdescriptionadvisoryc           
      C   s   d |  |j||g}d}d}d}	| j || jv }|r)| j| }	|	|k}n|| j|< W d   n1 s8w   Y  t||||	dS )a  
        Register an instrument with the name, type, unit and description as
        identifying keys and the advisory as value.

        Returns a tuple. The first value is the instrument id.
        The second value is an `_InstrumentRegistrationStatus` where
        `already_registered` is `True` if the instrument has been registered
        already.
        If `conflict` is set to True the `current_advisory` attribute contains
        the registered instrument advisory.
        ,FN)rO   rP   rQ   rR   )joinstriplowerr8   rZ   rY   rN   )
r3   r*   r`   ra   rb   rc   rO   rP   rQ   rR   r1   r1   r4   _register_instrument   s(   



	zMeter._register_instrumentinstrumentation_typestatusc                 C   s   t d| ||||j d S )NzAn instrument with name %s, type %s, unit %s and description %s has been created already with a different advisory value %s and will be used instead.)_loggerwarningrR   )r*   ri   ra   rb   rj   r1   r1   r4   %_log_instrument_registration_conflict  s   z+Meter._log_instrument_registration_conflict c                 C   r0   )aR  Creates a `Counter` instrument

        Args:
            name: The name of the instrument to be created
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        Nr1   r3   r*   ra   rb   r1   r1   r4   create_counter*  r6   zMeter.create_counterc                 C   r0   )aY  Creates an `UpDownCounter` instrument

        Args:
            name: The name of the instrument to be created
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        Nr1   ro   r1   r1   r4   create_up_down_counter:  r6   zMeter.create_up_down_counter	callbacksc                 C   r0   )a  Creates an `ObservableCounter` instrument

        An observable counter observes a monotonically increasing count by calling provided
        callbacks which accept a :class:`~opentelemetry.metrics.CallbackOptions` and return
        multiple :class:`~opentelemetry.metrics.Observation`.

        For example, an observable counter could be used to report system CPU
        time periodically. Here is a basic implementation::

            def cpu_time_callback(options: CallbackOptions) -> Iterable[Observation]:
                observations = []
                with open("/proc/stat") as procstat:
                    procstat.readline()  # skip the first line
                    for line in procstat:
                        if not line.startswith("cpu"): break
                        cpu, *states = line.split()
                        observations.append(Observation(int(states[0]) // 100, {"cpu": cpu, "state": "user"}))
                        observations.append(Observation(int(states[1]) // 100, {"cpu": cpu, "state": "nice"}))
                        observations.append(Observation(int(states[2]) // 100, {"cpu": cpu, "state": "system"}))
                        # ... other states
                return observations

            meter.create_observable_counter(
                "system.cpu.time",
                callbacks=[cpu_time_callback],
                unit="s",
                description="CPU time"
            )

        To reduce memory usage, you can use generator callbacks instead of
        building the full list::

            def cpu_time_callback(options: CallbackOptions) -> Iterable[Observation]:
                with open("/proc/stat") as procstat:
                    procstat.readline()  # skip the first line
                    for line in procstat:
                        if not line.startswith("cpu"): break
                        cpu, *states = line.split()
                        yield Observation(int(states[0]) // 100, {"cpu": cpu, "state": "user"})
                        yield Observation(int(states[1]) // 100, {"cpu": cpu, "state": "nice"})
                        # ... other states

        Alternatively, you can pass a sequence of generators directly instead of a sequence of
        callbacks, which each should return iterables of :class:`~opentelemetry.metrics.Observation`::

            def cpu_time_callback(states_to_include: set[str]) -> Iterable[Iterable[Observation]]:
                # accept options sent in from OpenTelemetry
                options = yield
                while True:
                    observations = []
                    with open("/proc/stat") as procstat:
                        procstat.readline()  # skip the first line
                        for line in procstat:
                            if not line.startswith("cpu"): break
                            cpu, *states = line.split()
                            if "user" in states_to_include:
                                observations.append(Observation(int(states[0]) // 100, {"cpu": cpu, "state": "user"}))
                            if "nice" in states_to_include:
                                observations.append(Observation(int(states[1]) // 100, {"cpu": cpu, "state": "nice"}))
                            # ... other states
                    # yield the observations and receive the options for next iteration
                    options = yield observations

            meter.create_observable_counter(
                "system.cpu.time",
                callbacks=[cpu_time_callback({"user", "system"})],
                unit="s",
                description="CPU time"
            )

        The :class:`~opentelemetry.metrics.CallbackOptions` contain a timeout which the
        callback should respect. For example if the callback does asynchronous work, like
        making HTTP requests, it should respect the timeout::

            def scrape_http_callback(options: CallbackOptions) -> Iterable[Observation]:
                r = requests.get('http://scrapethis.com', timeout=options.timeout_millis / 10**3)
                for value in r.json():
                    yield Observation(value)

        Args:
            name: The name of the instrument to be created
            callbacks: A sequence of callbacks that return an iterable of
                :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a sequence of generators that each
                yields iterables of :class:`~opentelemetry.metrics.Observation`.
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        Nr1   r3   r*   rr   ra   rb   r1   r1   r4   create_observable_counterJ  r6   zMeter.create_observable_counter#explicit_bucket_boundaries_advisoryrv   c                C   r0   )ar  Creates a :class:`~opentelemetry.metrics.Histogram` instrument

        Args:
            name: The name of the instrument to be created
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        Nr1   )r3   r*   ra   rb   rv   r1   r1   r4   create_histogram  r6   zMeter.create_histogramc                 C   s   t d dS )aR  Creates a ``Gauge`` instrument

        Args:
            name: The name of the instrument to be created
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        z5create_gauge() is not implemented and will be a no-opN)warningswarnro   r1   r1   r4   create_gauge  s   zMeter.create_gaugec                 C   r0   )aZ  Creates an `ObservableGauge` instrument

        Args:
            name: The name of the instrument to be created
            callbacks: A sequence of callbacks that return an iterable of
                :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a generator that yields iterables
                of :class:`~opentelemetry.metrics.Observation`.
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        Nr1   rs   r1   r1   r4   create_observable_gauge  r6   zMeter.create_observable_gaugec                 C   r0   )ab  Creates an `ObservableUpDownCounter` instrument

        Args:
            name: The name of the instrument to be created
            callbacks: A sequence of callbacks that return an iterable of
                :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a generator that yields iterables
                of :class:`~opentelemetry.metrics.Observation`.
            unit: The unit for observations this instrument reports. For
                example, ``By`` for bytes. UCUM units are recommended.
            description: A description for this instrument and what it measures.
        Nr1   rs   r1   r1   r4   !create_observable_up_down_counter  r6   z'Meter.create_observable_up_down_counterNNrA   rn   rn   Nrn   rn   )$r8   r9   r:   r;   r<   r
   rF   propertyr*   r+   r,   typer   rN   rh   staticmethodrm   r   r   rp   r   rq   r   r   r   rt   floatr   rw   r   rz   r   r{   r   r|   __classcell__r1   r1   r\   r4   r/      s   	
,
`



r/   c                       sj  e Zd Z		ddedee dee ddf fddZdeddfd	d
Z		d dedededefddZ			d dededede
fddZ			d!dedeee  dededef
ddZ		d dddedededeee  def
ddZ		d dedededefddZ			d!dedeee  dededef
ddZ			d!dedeee  dededef
ddZ  ZS )"rH   Nr*   r+   r,   r.   c                    s*   t  j|||d t | _g | _d | _d S rG   )rU   rF   r   rB   _instruments_real_meterr[   r\   r1   r4   rF     s   
z_ProxyMeter.__init__rK   c                 C   s\   | | j| j| j}| j || _| jD ]}|| qW d   dS 1 s'w   Y  dS )zCalled when a real meter provider is set on the creating _ProxyMeterProvider

        Creates a real backing meter for this instance and notifies all created
        instruments so they can create real backing instruments.
        N)r5   rV   rW   rX   rB   r   r   on_meter_set)r3   rK   
real_meter
instrumentr1   r1   r4   rL     s   
"z!_ProxyMeter.on_set_meter_providerrn   ra   rb   c                 C   j   | j ( | jr| j|||W  d    S t|||}| j| |W  d    S 1 s.w   Y  d S rA   )rB   r   rp   r   r   rI   r3   r*   ra   rb   proxyr1   r1   r4   rp        $z_ProxyMeter.create_counterc                 C   r   rA   )rB   r   rq   r%   r   rI   r   r1   r1   r4   rq      s   $z"_ProxyMeter.create_up_down_counterrr   c                 C   p   | j + | jr| j||||W  d    S t||||d}| j| |W  d    S 1 s1w   Y  d S Nra   rb   )rB   r   rt   r"   r   rI   r3   r*   rr   ra   rb   r   r1   r1   r4   rt   /     $z%_ProxyMeter.create_observable_counterru   rv   c                C   sp   | j + | jr| jj||||dW  d    S t||||}| j| |W  d    S 1 s1w   Y  d S )Nru   )rB   r   rw   r!   r   rI   )r3   r*   ra   rb   rv   r   r1   r1   r4   rw   A  s   $z_ProxyMeter.create_histogramc                 C   r   rA   )rB   r   rz   r    r   rI   r   r1   r1   r4   rz   W  r   z_ProxyMeter.create_gaugec                 C   r   r   )rB   r   r{   r#   r   rI   r   r1   r1   r4   r{   d  r   z#_ProxyMeter.create_observable_gaugec                 C   r   r   )rB   r   r|   r$   r   rI   r   r1   r1   r4   r|   v  s   $z-_ProxyMeter.create_observable_up_down_counterr}   r~   r   )r8   r9   r:   r<   r
   rF   r)   rL   r   rp   r   rq   r   r   r   rt   r   r   rw   r   rz   r   r{   r   r|   r   r1   r1   r\   r4   rH     s    









rH   c                   @   s,  e Zd ZdZ		ddedededefddZ		ddedededefd	d
Z		ddededede	fddZ
			ddedeee  dededef
ddZ		ddddedededeee  def
ddZ			ddedeee  dededef
ddZ			ddedeee  dededef
ddZdS )r?   zeThe default Meter used when no Meter implementation is available.

    All operations are no-op.
    rn   r*   ra   rb   r.   c                 C   8   |  |t||}|jr| |tj||| t|||dS )zReturns a no-op Counter.r   )rh   r   rQ   rm   r   r8   r3   r*   ra   rb   rj   r1   r1   r4   rp     s   zNoOpMeter.create_counterc                 C   r   )zReturns a no-op Gauge.r   )rh   r   rQ   rm   r   r8   r   r1   r1   r4   rz     s   zNoOpMeter.create_gaugec                 C   r   )zReturns a no-op UpDownCounter.r   )rh   r   rQ   rm   r   r8   r   r1   r1   r4   rq     s   z NoOpMeter.create_up_down_counterNrr   c                 C   :   |  |t||}|jr| |tj||| t||||dS )z"Returns a no-op ObservableCounter.r   )rh   r   rQ   rm   r   r8   r3   r*   rr   ra   rb   rj   r1   r1   r4   rt     "   z#NoOpMeter.create_observable_counterru   rv   c             	   C   sB   |  |t||t|d}|jr| |tj||| t||||dS )zReturns a no-op Histogram.)explicit_bucket_boundaries)ra   rb   rv   )rh   r   r   rQ   rm   r   r8   )r3   r*   ra   rb   rv   rj   r1   r1   r4   rw     s.   		zNoOpMeter.create_histogramc                 C   r   )z Returns a no-op ObservableGauge.r   )rh   r   rQ   rm   r   r8   r   r1   r1   r4   r{     r   z!NoOpMeter.create_observable_gaugec                 C   r   )z(Returns a no-op ObservableUpDownCounter.r   )rh   r   rQ   rm   r   r8   r   r1   r1   r4   r|   "  r   z+NoOpMeter.create_observable_up_down_counterr~   r   )r8   r9   r:   r;   r<   r   rp   r   rz   r   rq   r
   r   r   r   rt   r   r   rw   r   r{   r   r|   r1   r1   r1   r4   r?     s    






$


r?   _METER_PROVIDERrn   r*   r+   rK   r,   r-   r.   c                 C   s   |du rt  }|| |||S )zReturns a `Meter` for use by the given instrumentation library.

    This function is a convenience wrapper for
    `opentelemetry.metrics.MeterProvider.get_meter`.

    If meter_provider is omitted the current configured one is used.
    N)get_meter_providerr5   )r*   r+   rK   r,   r-   r1   r1   r4   r5   B  s   r5   logc                    s6   d fdd}t |}|r|std d S d S d S )Nr.   c                      s    a t  d S rA   )r   _PROXY_METER_PROVIDERrL   r1   rK   r1   r4   set_mpV  s   z#_set_meter_provider.<locals>.set_mpz2Overriding of current MeterProvider is not allowedrM   )_METER_PROVIDER_SET_ONCEdo_oncerk   rl   )rK   r   r   did_setr1   r   r4   _set_meter_providerU  s
   
r   c                 C   s   t | dd dS )zSets the current global :class:`~.MeterProvider` object.

    This can only be done once, a warning will be logged if any further attempt
    is made.
    Tr   N)r   r   r1   r1   r4   set_meter_providerc  s   r   c                  C   s4   t du rttvr
tS ttd} t| dd tdt S )z8Gets the current global :class:`~.MeterProvider` object.NrK   Fr   r)   )r   r   r   r   r'   r   r   r   r1   r1   r4   r   l  s   
r   )rn   NNN)Hr;   rx   abcr   r   dataclassesr   loggingr   osr   	threadingr   typingr   r	   r
   r   r   r   #opentelemetry.environment_variablesr   *opentelemetry.metrics._internal.instrumentr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   opentelemetry.util._oncer&   opentelemetry.util._providersr'   opentelemetry.util.typesr(   r8   rk   _ProxyInstrumentTr)   r=   r@   rN   r/   rH   r?   r   r   rS   r   r<   r5   rT   r   r   r   r1   r1   r1   r4   <module>   sv    d*  8  2
	