@@ -74,7 +74,14 @@ def get_sample_value(self, name, labels=None):
7474
7575
7676class Metric (object ):
77- '''A single metric and it's samples.'''
77+ '''A single metric family and its samples.
78+
79+ This is intended only for internal use by the instrumentation client.
80+
81+
82+ Custom collectors should use GaugeMetricFamily, CounterMetricFamily
83+ and SummaryMetricFamily instead.
84+ '''
7885 def __init__ (self , name , documentation , typ ):
7986 self ._name = name
8087 self ._documentation = documentation
@@ -83,11 +90,124 @@ def __init__(self, name, documentation, typ):
8390 self ._type = typ
8491 self ._samples = []
8592
86- '''Add a sample to the metric'''
8793 def add_sample (self , name , labels , value ):
94+ '''Add a sample to the metric.
95+
96+ Internal-only, do not use.'''
8897 self ._samples .append ((name , labels , value ))
8998
9099
100+ class GaugeMetricFamily (Metric ):
101+ '''A single gauge and its samples.
102+
103+ For use by custom collectors.
104+ '''
105+ def __init__ (self , name , documentation , value = None , labels = None ):
106+ Metric .__init__ (self , name , documentation , 'gauge' )
107+ if labels is not None and value is not None :
108+ raise ValueError ('Can only specify at most one of value and labels.' )
109+ if labels is None :
110+ labels = []
111+ self ._labelnames = labels
112+ if value is not None :
113+ self .add_metric ([], value )
114+
115+ def add_metric (self , labels , value ):
116+ '''Add a metric to the metric family.
117+
118+ Args:
119+ labels: A list of label values
120+ value: A float
121+ '''
122+ self ._samples .append ((self ._name , dict (zip (self ._labelnames , labels )), value ))
123+
124+
125+ class CounterMetricFamily (Metric ):
126+ '''A single counter and its samples.
127+
128+ For use by custom collectors.
129+ '''
130+ def __init__ (self , name , documentation , value = None , labels = None ):
131+ Metric .__init__ (self , name , documentation , 'counter' )
132+ if labels is not None and value is not None :
133+ raise ValueError ('Can only specify at most one of value and labels.' )
134+ if labels is None :
135+ labels = []
136+ self ._labelnames = labels
137+ if value is not None :
138+ self .add_metric ([], value )
139+
140+ def add_metric (self , labels , value ):
141+ '''Add a metric to the metric family.
142+
143+ Args:
144+ labels: A list of label values
145+ value: The value of the metric.
146+ '''
147+ self ._samples .append ((self ._name , dict (zip (self ._labelnames , labels )), value ))
148+
149+
150+ class SummaryMetricFamily (Metric ):
151+ '''A single summary and its samples.
152+
153+ For use by custom collectors.
154+ '''
155+ def __init__ (self , name , documentation , count_value = None , sum_value = None , labels = None ):
156+ Metric .__init__ (self , name , documentation , 'summary' )
157+ if sum_value is not None != count_value is not None :
158+ raise ValueError ('count_value and sum_value must be provided together.' )
159+ if labels is not None and count_value is not None :
160+ raise ValueError ('Can only specify at most one of value and labels.' )
161+ if labels is None :
162+ labels = []
163+ self ._labelnames = labels
164+ if value is not None :
165+ self .add_metric ([], count_value , sum_value )
166+
167+ def add_metric (self , labels , count_value , sum_value ):
168+ '''Add a metric to the metric family.
169+
170+ Args:
171+ labels: A list of label values
172+ count_value: The count value of the metric.
173+ sum_value: The sum value of the metric.
174+ '''
175+ self ._samples .append ((self ._name + u'_count' , dict (zip (self ._labelnames , labels )), count_value ))
176+ self ._samples .append ((self ._name + u'_sum' , dict (zip (self ._labelnames , labels )), sum_value ))
177+
178+
179+ class HistogramMetricFamily (Metric ):
180+ '''A single histogram and its samples.
181+
182+ For use by custom collectors.
183+ '''
184+ def __init__ (self , name , documentation , buckets = None , sum_value = None , labels = None ):
185+ Metric .__init__ (self , name , documentation , 'histogram' )
186+ if sum_value is not None != buckets is not None :
187+ raise ValueError ('buckets and sum_value must be provided together.' )
188+ if labels is not None and buckets is not None :
189+ raise ValueError ('Can only specify at most one of buckets and labels.' )
190+ if labels is None :
191+ labels = []
192+ self ._labelnames = labels
193+ if value is not None :
194+ self .add_metric ([], buckets , sum_value )
195+
196+ def add_metric (self , labels , buckets , sum_value ):
197+ '''Add a metric to the metric family.
198+
199+ Args:
200+ labels: A list of label values
201+ buckets: A dict of bucket names to values. The +Inf key must be present.
202+ sum_value: The sum value of the metric.
203+ '''
204+ for bucket , value in buckets .items :
205+ self ._samples .append ((self ._name + u'_bucket' , dict (zip (self ._labelnames , labels ) + (u'le' , bucket )), value ))
206+ self ._samples .append ((self ._name + u'_count' , dict (zip (self ._labelnames , labels )), buckets ['+Inf' ]))
207+ self ._samples .append ((self ._name + u'_sum' , dict (zip (self ._labelnames , labels )), sum_value ))
208+
209+
210+
91211class _MutexValue (object ):
92212 '''A float protected by a mutex.'''
93213
@@ -271,7 +391,7 @@ def _samples(self):
271391@_MetricWrapper
272392class Gauge (object ):
273393 '''Gauge metric, to report instantaneous values.
274-
394+
275395 Examples of Gauges include:
276396 Inprogress requests
277397 Number of items in a queue
0 commit comments