PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /opt/saltstack/salt/extras-3.10/mtrlib/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //opt/saltstack/salt/extras-3.10/mtrlib/graphite.py |
"""Functions for Retrieving data from graphite""" from typing import Union, List, Optional, Tuple from datetime import datetime import urllib.parse import requests from arrow.arrow import Arrow import arrow QUERY_FMT = '%H:%M_%Y%m%d' class GraphiteError(Exception): """Raised on error when fetching graphite data""" class Graphite: """Performs Graphite Queries""" def __init__( self, render_url: Optional[str] = 'https://graphite.imhadmin.net/render/', timeout: Optional[Union[float, Tuple[float]]] = 600, ): self.render_url = render_url self.timeout = timeout @staticmethod def _params( target: Union[str, List[str]], start: Optional[Union[datetime, Arrow, str, int]] = None, stop: Optional[Union[datetime, Arrow, str, int]] = None, tzname: Optional[str] = None, ) -> dict: # int -> arrow if isinstance(start, int): start = arrow.get(start) if isinstance(stop, int): stop = arrow.get(stop) # format datetimes if isinstance(start, (datetime, Arrow)): if tzname is None: # if tzname was not overridden tzname = start.tzname() start = start.strftime(QUERY_FMT) if isinstance(stop, (datetime, Arrow)): stop = stop.strftime(QUERY_FMT) # graphite's pytz may be old if tzname in ('PDT', 'PST'): tzname = 'America/Los_Angeles' if tzname in ('EST', 'EDT'): tzname = 'America/New_York' params = {'target': target} if start is not None: params['from'] = start if stop is not None: params['until'] = stop if tzname is not None: params['tz'] = tzname return params def query( self, target: Union[str, List[str]], start: Optional[Union[datetime, Arrow, str, int]] = None, stop: Optional[Union[datetime, Arrow, str, int]] = None, tzname: Optional[str] = None, ) -> list: """Query data from graphite Args: target (str or list): graphite bucket(s) to fetch data for start: start time to fetch data for. If not supplied, it'll be 24 hours ago **(see note)** stop: stop time to fetch data for. If not supplied, it'll be now **(see note)** tzname: timezone to use. If not supplied, the ``start`` arg's timezone will be used. If the ``start`` arg is not timezone aware, it'll use graphite defaults Raises: GraphiteError: on any error Note: ``start`` and ``stop`` will accept ``arrow`` objects, ``datetimes``, ``int`` for unix timestamps, and ``str``. If it's a ``str``, it'll be sent as a literal and handled per graphite's documentation https://graphite.readthedocs.io/en/latest/render_api.html """ params = self._params(target, start, stop, tzname) params['format'] = 'json' try: req = requests.get( self.render_url, timeout=self.timeout, params=params, ) except requests.RequestException as exc: raise GraphiteError(exc) from exc try: return req.json() except ValueError as exc: if req.status_code != 200: raise GraphiteError( f"{req.url}\nHTTP {req.status_code}: {req.reason}" ) from exc raise GraphiteError( f"{req.url}\n{type(exc).__name__}: {exc}" ) from exc def query_dict( self, target: Union[str, List[str]], start: Optional[Union[datetime, Arrow, str, int]] = None, stop: Optional[Union[datetime, Arrow, str, int]] = None, tzname: Optional[str] = None, ) -> dict: """Just like ``query`` except it converts the data to a dict Args: target (str or list): graphite bucket(s) to fetch data for start: start time to fetch data for. If not supplied, it'll be 24 hours ago **(see note)** stop: stop time to fetch data for. If not supplied, it'll be now **(see note)** tzname: timezone to use. If not supplied, the ``start`` arg's timezone will be used. If the ``start`` arg is not timezone aware, it'll use graphite defaults Raises: GraphiteError: on any error Note: ``start`` and ``stop`` will accept ``arrow`` objects, ``datetimes``, ``int`` for unix timestamps, and ``str``. If it's a ``str``, it'll be sent as a literal and handled per graphite's documentation https://graphite.readthedocs.io/en/latest/render_api.html """ return { x['target']: x['datapoints'] for x in self.query(target, start, stop, tzname) } def img_url( self, target: Union[str, List[str]], start: Optional[Union[datetime, Arrow, str, int]] = None, stop: Optional[Union[datetime, Arrow, str, int]] = None, tzname: Optional[str] = None, **kwargs, ) -> str: """Gets a graphite render URL for an image but does not fetch it Args: target (str or list): graphite bucket(s) to fetch data for start: start time to fetch data for. If not supplied, it'll be 24 hours ago **(see note)** stop: stop time to fetch data for. If not supplied, it'll be now **(see note)** tzname: timezone to use. If not supplied, the ``start`` arg's timezone will be used. If the ``start`` arg is not timezone aware, it'll use graphite defaults Raises: GraphiteError: on any error Note: ``start`` and ``stop`` will accept ``arrow`` objects, ``datetimes``, ``int`` for unix timestamps, and ``str``. If it's a ``str``, it'll be sent as a literal and handled per graphite's documentation https://graphite.readthedocs.io/en/latest/render_api.html """ params = self._params(target, start, stop, tzname) params.update(kwargs) args = urllib.parse.urlencode(query=params, doseq=True) return f'{self.render_url}?{args}'