8000 Merge pull request #45 from alexander-95/master · Syncano/client_python@0b7e85f · GitHub
[go: up one dir, main page]

Skip to content

Commit 0b7e85f

Browse files
committed
Merge pull request prometheus#45 from alexander-95/master
Allow for other ways for values to be managed.
2 parents f737c48 + 115e1f1 commit 0b7e85f

File tree

1 file changed

+72
-59
lines changed

1 file changed

+72
-59
lines changed

prometheus_client/core.py

Lines changed: 72 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,34 @@ def add_sample(self, name, labels, value):
8888
self._samples.append((name, labels, value))
8989

9090

91+
class _MutexValue(object):
92+
'''A float protected by a mutex.'''
93+
94+
def __init__(self, name, labelnames, labelvalues):
95+
self._value = 0.0
96+
self._lock = Lock()
97+
98+
def inc(self, amount):
99+
with self._lock:
100+
self._value += amount
101+
102+
def set(self, value):
103+
with self._lock:
104+
self._value = value
105+
106+
def get(self):
107+
with self._lock:
108+
return self._value
109+
110+
_ValueClass = _MutexValue
111+
112+
91113
class _LabelWrapper(object):
92114
'''Handles labels for the wrapped metric.'''
93-
def __init__(self, wrappedClass, labelnames, **kwargs):
115+
def __init__(self, wrappedClass, name, labelnames, **kwargs):
94116
self._wrappedClass = wrappedClass
95117
self._type = wrappedClass._type
118+
self._name = name
96119
self._labelnames = labelnames
97120
self._kwargs = kwargs
98121
self._lock = Lock()
@@ -122,7 +145,7 @@ def labels(self, *labelvalues):
122145
labelvalues = tuple([unicode(l) for l in labelvalues])
123146
with self._lock:
124147
if labelvalues not in self._metrics:
125-
self._metrics[labelvalues] = self._wrappedClass(**self._kwargs)
148+
self._metrics[labelvalues] = self._wrappedClass(self._name, self._labelnames, labelvalues, **self._kwargs)
126149
return self._metrics[labelvalues]
127150

128151
def remove(self, *labelvalues):
@@ -145,24 +168,25 @@ def _samples(self):
145168
def _MetricWrapper(cls):
146169
'''Provides common functionality for metrics.'''
147170
def init(name, documentation, labelnames=(), namespace='', subsystem='', registry=REGISTRY, **kwargs):
171+
full_name = ''
172+
if namespace:
173+
full_name += namespace + '_'
174+
if subsystem:
175+
full_name += subsystem + '_'
176+
full_name += name
177+
148178
if labelnames:
179+
labelnames = tuple(labelnames)
149180
for l in labelnames:
150181
if not _METRIC_LABEL_NAME_RE.match(l):
151182
raise ValueError('Invalid label metric name: ' + l)
152183
if _RESERVED_METRIC_LABEL_NAME_RE.match(l):
153184
raise ValueError('Reserved label metric name: ' + l)
154185
if l in cls._reserved_labelnames:
155186
raise ValueError('Reserved label metric name: ' + l)
156-
collector = _LabelWrapper(cls, labelnames, **kwargs)
187+
collector = _LabelWrapper(cls, name, labelnames, **kwargs)
157188
else:
158-
collector = cls(**kwargs)
159-
160-
full_name = ''
161-
if namespace:
162-
full_name += namespace + '_'
163-
if subsystem:
164-
full_name += subsystem + '_'
165-
full_name += name
189+
collector = cls(name, labelnames, (), **kwargs)
166190

167191
if not _METRIC_NAME_RE.match(full_name):
168192
raise ValueError('Invalid metric name: ' + full_name)
@@ -203,16 +227,14 @@ class Counter(object):
203227
_type = 'counter'
204228
_reserved_labelnames = []
205229

206-
def __init__(self):
207-
self._value = 0.0
208-
self._lock = Lock()
230+
def __init__(self, name, labelnames, labelvalues):
231+
self._value = _ValueClass(name, labelnames, labelvalues)
209232

210233
def inc(self, amount=1):
211234
'''Increment counter by the given amount.'''
212235
if amount < 0:
213236
raise ValueError('Counters can only be incremented by non-negative amounts.')
214-
with self._lock:
215-
self._value += amount
237+
self._value.inc(amount)
216238

217239
def count_exceptions(self, exception=Exception):
218240
'''Count exceptions in a block of code or function.
@@ -243,8 +265,7 @@ def wrapped(*args, **kwargs):
243265
return ExceptionCounter(self)
244266

245267
def _samples(self):
246-
with self._lock:
247-
return (('', {}, self._value), )
268+
return (('', {}, self._value.get()), )
248269

249270

250271
@_MetricWrapper
@@ -269,24 +290,20 @@ class Gauge(object):
269290
_type = 'gauge'
270291
_reserved_labelnames = []
271292

272-
def __init__(self):
273-
self._value = 0.0
274-
self._lock = Lock()
293+
def __init__(self, name, labelnames, labelvalues):
294+
self._value = _ValueClass(name, labelnames, labelvalues)
275295

276296
def inc(self, amount=1):
277297
'''Increment gauge by the given amount.'''
278-
with self._lock:
279-
self._value += amount
298+
self._value.inc(amount)
280299

281300
def dec(self, amount=1):
282301
'''Decrement gauge by the given amount.'''
283-
with self._lock:
284-
self._value -= amount
302+
self._value.inc(-amount)
285303

286304
def set(self, value):
287305
'''Set gauge to the given value.'''
288-
with self._lock:
289-
self._value = float(value)
306+
self._value.set(float(value))
290307

291308
def set_to_current_time(self):
292309
'''Set gauge to the current unixtime.'''
@@ -357,8 +374,7 @@ def samples(self):
357374
self._samples = types.MethodType(samples, self)
358375

359376
def _samples(self):
360-
with self._lock:
361-
return (('', {}, self._value), )
377+
return (('', {}, self._value.get()), )
362378

363379

364380
@_MetricWrapper
@@ -388,16 +404,14 @@ def create_response(request):
388404
_type = 'summary'
389405
_reserved_labelnames = ['quantile']
390406

391-
def __init__(self):
392-
self._count = 0.0
393-
self._sum = 0.0
394-
self._lock = Lock()
407+
def __init__(self, name, labelnames, labelvalues):
408+
self._count = _ValueClass(name + '_count', labelnames, labelvalues)
409+
self._sum = _ValueClass(name + '_sum', labelnames, labelvalues)
395410

396411
def observe(self, amount):
397412
'''Observe the given amount.'''
398-
with self._lock:
399-
self._count += 1
400-
self._sum += amount
413+
self._count.inc(1)
414+
self._sum.inc(amount)
401415

402416
def time(self):
403417
'''Time a block of code or function, and observe the duration in seconds.
@@ -426,10 +440,9 @@ def wrapped(*args, **kwargs):
426440
return Timer(self)
427441

428442
def _samples(self):
429-
with self._lock:
430-
return (
431-
('_count', {}, self._count),
432-
('_sum', {}, self._sum))
443+
return (
444+
('_count', {}, self._count.get()),
445+
('_sum', {}, self._sum.get()))
433446

434447

435448
def _floatToGoString(d):
@@ -473,9 +486,8 @@ def create_response(request):
473486
_type = 'histogram'
474487
_reserved_labelnames = ['histogram']
475488

476-
def __init__(self, buckets=(.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2.5, 5.0, 7.5, 10.0, _INF)):
477-
self._sum = 0.0
478-
self._lock = Lock()
489+
def __init__(self, name, labelnames, labelvalues, buckets=(.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2.5, 5.0, 7.5, 10.0, _INF)):
490+
self._sum = _ValueClass(name + '_sum', labelnames, labelvalues)
479491
buckets = [float(b) for b in buckets]
480492
if buckets != sorted(buckets):
481493
# This is probably an error on the part of the user,
@@ -486,16 +498,18 @@ def __init__(self, buckets=(.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2
486498
if len(buckets) < 2:
487499
raise ValueError('Must have at least two buckets')
488500
self._upper_bounds = buckets
489-
self._buckets = [0.0] * len(buckets)
501+
self._buckets = []
502+
bucket_labelnames = labelnames + ('le',)
503+
for b in buckets:
504+
self._buckets.append(_ValueClass(name + '_bucket', bucket_labelnames, labelvalues + (_floatToGoString(b),)))
490505

491506 F42D
def observe(self, amount):
492507
'''Observe the given amount.'''
493-
with self._lock:
494-
self._sum += amount
495-
for i, bound in enumerate(self._upper_bounds):
496-
if amount <= bound:
497-
self._buckets[i] += 1
498-
break
508+
self._sum.inc(amount)
509+
for i, bound in enumerate(self._upper_bounds):
510+
if amount <= bound:
511+
self._buckets[i].inc(1)
512+
break
499513

500514
def time(self):
501515
'''Time a block of code or function, and observe the duration in seconds.
@@ -524,13 +538,12 @@ def wrapped(*args, **kwargs):
524538
return Timer(self)
525539

526540
def _samples(self):
527-
with self._lock:
528-
samples = []
529-
acc = 0
530-
for i, bound in enumerate(self._upper_bounds):
531-
acc += self._buckets[i]
532-
samples.append(('_bucket', {'le': _floatToGoString(bound)}, acc))
533-
samples.append(('_count', {}, acc))
534-
samples.append(('_sum', {}, self._sum))
535-
return tuple(samples)
541+
samples = []
542+
acc = 0
543+
for i, bound in enumerate(self._upper_bounds):
544+
acc += self._buckets[i].get()
545+
samples.append(('_bucket', {'le': _floatToGoString(bound)}, acc))
546+
samples.append(('_count', {}, acc))
547+
samples.append(('_sum', {}, self._sum.get()))
548+
return tuple(samples)
536549

0 commit comments

Comments
 (0)
0