NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

api_client.py (5710B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\datadog\api\api_client.py
      2 import logging
      3 import time
      4 from datadog.api import _api_version, _max_timeouts, _backoff_period
      5 from datadog.api.exceptions import ClientError, ApiError, HttpBackoff, HttpTimeout, HTTPError, ApiNotInitialized
      6 from datadog.api.http_client import resolve_http_client
      7 from datadog.util.compat import json, is_p3k
      8 from eveprefs import boot
      9 log = logging.getLogger('datadog.api')
     10 
     11 class APIClient(object):
     12     _backoff_period = _backoff_period
     13     _max_timeouts = _max_timeouts
     14     _backoff_timestamp = None
     15     _timeout_counter = 0
     16     _api_version = _api_version
     17     _http_client = None
     18 
     19     @classmethod
     20     def _get_http_client(cls):
     21         if not cls._http_client:
     22             cls._http_client = resolve_http_client()
     23         return cls._http_client
     24 
     25     @classmethod
     26     def submit(cls, method, path, body = None, attach_host_name = False, response_formatter = None, error_formatter = None, **params):
     27         try:
     28             if not cls._should_submit():
     29                 _, backoff_time_left = cls._backoff_status()
     30                 raise HttpBackoff(backoff_time_left)
     31             from datadog.api import _api_key, _application_key, _api_host, _mute, _host_name, _proxies, _max_retries, _timeout, _cacert
     32             if _api_key is None:
     33                 raise ApiNotInitialized("API key is not set. Please run 'initialize' method first.")
     34             params['api_key'] = _api_key
     35             if _application_key:
     36                 params['application_key'] = _application_key
     37             if attach_host_name and body:
     38                 if 'series' in body:
     39                     for obj_params in body['series']:
     40                         if obj_params.get('host', '') == '':
     41                             obj_params['host'] = _host_name
     42 
     43                 elif body.get('host', '') == '':
     44                     body['host'] = _host_name
     45             if 'tags' in params and isinstance(params['tags'], list):
     46                 params['tags'] = ','.join(params['tags'])
     47             headers = {}
     48             if isinstance(body, dict):
     49                 body = json.dumps(body)
     50                 headers['Content-Type'] = 'application/json'
     51             url = '{api_host}/api/{api_version}/{path}'.format(api_host=_api_host, api_version=cls._api_version, path=path.lstrip('/'))
     52             start_time = time.time()
     53             result = cls._get_http_client().request(method=method, url=url, headers=headers, params=params, data=body, timeout=_timeout, max_retries=_max_retries, proxies=_proxies, verify=_cacert)
     54             duration = round((time.time() - start_time) * 1000.0, 4)
     55             log.info('%s %s %s (%sms)' % (result.status_code,
     56              method,
     57              url,
     58              duration))
     59             cls._timeout_counter = 0
     60             content = result.content
     61             if content:
     62                 try:
     63                     if is_p3k():
     64                         response_obj = json.loads(content.decode('utf-8'))
     65                     else:
     66                         response_obj = json.loads(content)
     67                 except ValueError:
     68                     raise ValueError('Invalid JSON response: {0}'.format(content))
     69 
     70                 if response_obj and 'errors' in response_obj:
     71                     raise ApiError(response_obj)
     72             else:
     73                 response_obj = None
     74             if response_formatter is None:
     75                 return response_obj
     76             return response_formatter(response_obj)
     77         except HTTPError as e:
     78             if e.status_code == 408 and boot.region == 'optic':
     79                 pass
     80             else:
     81                 raise
     82         except HttpTimeout:
     83             cls._timeout_counter += 1
     84             raise
     85         except ClientError as e:
     86             if _mute:
     87                 log.error(str(e))
     88                 if error_formatter is None:
     89                     return {'errors': e.args[0]}
     90                 else:
     91                     return error_formatter({'errors': e.args[0]})
     92             else:
     93                 raise
     94         except ApiError as e:
     95             if _mute:
     96                 for error in e.args[0]['errors']:
     97                     log.error(str(error))
     98 
     99                 if error_formatter is None:
    100                     return e.args[0]
    101                 else:
    102                     return error_formatter(e.args[0])
    103             else:
    104                 raise
    105 
    106     @classmethod
    107     def _should_submit(cls):
    108         now = time.time()
    109         should_submit = False
    110         if not cls._backoff_timestamp and cls._timeout_counter >= cls._max_timeouts:
    111             log.info('Max number of datadog timeouts exceeded, backing off for {0} seconds'.format(cls._backoff_period))
    112             cls._backoff_timestamp = now
    113             should_submit = False
    114         elif cls._backoff_timestamp:
    115             backed_off_time, backoff_time_left = cls._backoff_status()
    116             if backoff_time_left < 0:
    117                 log.info('Exiting backoff state after {0} seconds, will try to submit metrics again'.format(backed_off_time))
    118                 cls._backoff_timestamp = None
    119                 cls._timeout_counter = 0
    120                 should_submit = True
    121             else:
    122                 log.info("In backoff state, won't submit metrics for another {0} seconds".format(backoff_time_left))
    123                 should_submit = False
    124         else:
    125             should_submit = True
    126         return should_submit
    127 
    128     @classmethod
    129     def _backoff_status(cls):
    130         now = time.time()
    131         backed_off_time = now - cls._backoff_timestamp
    132         backoff_time_left = cls._backoff_period - backed_off_time
    133         return (round(backed_off_time, 2), round(backoff_time_left, 2))