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

metrics.py (4131B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\datadog\threadstats\metrics.py
      2 from collections import defaultdict
      3 import random
      4 import itertools
      5 from datadog.util.compat import iternext
      6 
      7 class Metric(object):
      8 
      9     def add_point(self, value):
     10         raise NotImplementedError()
     11 
     12     def flush(self, timestamp):
     13         raise NotImplementedError()
     14 
     15 
     16 class Gauge(Metric):
     17     stats_tag = 'g'
     18 
     19     def __init__(self, name, tags, host):
     20         self.name = name
     21         self.tags = tags
     22         self.host = host
     23         self.value = None
     24 
     25     def add_point(self, value):
     26         self.value = value
     27 
     28     def flush(self, timestamp):
     29         return [(timestamp,
     30           self.value,
     31           self.name,
     32           self.tags,
     33           self.host)]
     34 
     35 
     36 class Counter(Metric):
     37     stats_tag = 'c'
     38 
     39     def __init__(self, name, tags, host):
     40         self.name = name
     41         self.tags = tags
     42         self.host = host
     43         self.count = []
     44 
     45     def add_point(self, value):
     46         self.count.append(value)
     47 
     48     def flush(self, timestamp):
     49         count = sum(self.count, 0)
     50         return [(timestamp,
     51           count,
     52           self.name,
     53           self.tags,
     54           self.host)]
     55 
     56 
     57 class Histogram(Metric):
     58     stats_tag = 'h'
     59 
     60     def __init__(self, name, tags, host):
     61         self.name = name
     62         self.tags = tags
     63         self.host = host
     64         self.max = float('-inf')
     65         self.min = float('inf')
     66         self.sum = []
     67         self.iter_counter = itertools.count()
     68         self.count = iternext(self.iter_counter)
     69         self.sample_size = 1000
     70         self.samples = []
     71         self.percentiles = [0.75,
     72          0.85,
     73          0.95,
     74          0.99]
     75 
     76     def add_point(self, value):
     77         self.max = self.max if self.max > value else value
     78         self.min = self.min if self.min < value else value
     79         self.sum.append(value)
     80         if self.count < self.sample_size:
     81             self.samples.append(value)
     82         else:
     83             self.samples[random.randrange(0, self.sample_size)] = value
     84         self.count = iternext(self.iter_counter)
     85 
     86     def flush(self, timestamp):
     87         if not self.count:
     88             return []
     89         metrics = [(timestamp,
     90           self.min,
     91           '%s.min' % self.name,
     92           self.tags,
     93           self.host),
     94          (timestamp,
     95           self.max,
     96           '%s.max' % self.name,
     97           self.tags,
     98           self.host),
     99          (timestamp,
    100           self.count,
    101           '%s.count' % self.name,
    102           self.tags,
    103           self.host),
    104          (timestamp,
    105           self.average(),
    106           '%s.avg' % self.name,
    107           self.tags,
    108           self.host)]
    109         length = len(self.samples)
    110         self.samples.sort()
    111         for p in self.percentiles:
    112             val = self.samples[int(round(p * length - 1))]
    113             name = '%s.%spercentile' % (self.name, int(p * 100))
    114             metrics.append((timestamp,
    115              val,
    116              name,
    117              self.tags,
    118              self.host))
    119 
    120         return metrics
    121 
    122     def average(self):
    123         sum_metrics = sum(self.sum, 0)
    124         return float(sum_metrics) / self.count
    125 
    126 
    127 class Timing(Histogram):
    128     stats_tag = 'ms'
    129 
    130 
    131 class MetricsAggregator(object):
    132 
    133     def __init__(self, roll_up_interval = 10):
    134         self._metrics = defaultdict(lambda : {})
    135         self._roll_up_interval = roll_up_interval
    136 
    137     def add_point(self, metric, tags, timestamp, value, metric_class, sample_rate = 1, host = None):
    138         interval = timestamp - timestamp % self._roll_up_interval
    139         key = (metric, host, tuple(sorted(tags)) if tags else None)
    140         if key not in self._metrics[interval]:
    141             self._metrics[interval][key] = metric_class(metric, tags, host)
    142         self._metrics[interval][key].add_point(value)
    143 
    144     def flush(self, timestamp):
    145         interval = timestamp - timestamp % self._roll_up_interval
    146         past_intervals = [ i for i in self._metrics.keys() if i < interval ]
    147         metrics = []
    148         for i in past_intervals:
    149             for m in list(self._metrics.pop(i).values()):
    150                 metrics += m.flush(i)
    151 
    152         return metrics