Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions 9 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,13 @@ c.labels('get', '/').inc()
c.labels('post', '/submit').inc()
```

Labels can also be provided as a dict:
Labels can also be passed as keyword-arguments:

```python
from prometheus_client import Counter
c = Counter('my_requests_total', 'HTTP Failures', ['method', 'endpoint'])
c.labels({'method': 'get', 'endpoint': '/'}).inc()
c.labels({'method': 'post', 'endpoint': '/submit'}).inc()
c.labels(method='get', endpoint='/').inc()
c.labels(method='post', endpoint='/submit').inc()
```

### Process Collector
Expand Down Expand Up @@ -369,7 +369,7 @@ REGISTRY.register(CustomCollector())
## Parser

The Python client supports parsing the Promeheus text format.
This is intended for advanced use cases where you have servers
This is intended for advanced use cases where you have servers
exposing Prometheus metrics and need to get them into some other
system.

Expand All @@ -379,4 +379,3 @@ for family in text_string_to_metric_families("my_gauge 1.0\n"):
for sample in family.samples:
print("Name: {0} Labels: {1} Value: {2}".format(*sample))
```

11 changes: 7 additions & 4 deletions 11 prometheus_client/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def __init__(self, wrappedClass, name, labelnames, **kwargs):
if l.startswith('__'):
raise ValueError('Invalid label metric name: ' + l)

def labels(self, *labelvalues):
def labels(self, *labelvalues, **labelkwargs):
'''Return the child for the given labelset.

All metrics can have labels, allowing grouping of related time series.
Expand All @@ -276,10 +276,13 @@ def labels(self, *labelvalues):
See the best practices on [naming](http://prometheus.io/docs/practices/naming/)
and [labels](http://prometheus.io/docs/practices/instrumentation/#use-labels).
'''
if len(labelvalues) == 1 and type(labelvalues[0]) == dict:
if sorted(labelvalues[0].keys()) != sorted(self._labelnames):
if labelvalues and labelkwargs:
raise ValueError("Can't pass both *args and **kwargs")

if labelkwargs:
if sorted(labelkwargs) != sorted(self._labelnames):
raise ValueError('Incorrect label names')
labelvalues = tuple([unicode(labelvalues[0][l]) for l in self._labelnames])
labelvalues = tuple([unicode(labelkwargs[l]) for l in self._labelnames])
else:
if len(labelvalues) != len(self._labelnames):
raise ValueError('Incorrect label count')
Expand Down
27 changes: 14 additions & 13 deletions 27 tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def test_incorrect_label_count_raises(self):

def test_labels_coerced_to_string(self):
self.counter.labels(None).inc()
self.counter.labels({'l': None}).inc()
self.counter.labels(l=None).inc()
self.assertEqual(2, self.registry.get_sample_value('c', {'l': 'None'}))

self.counter.remove(None)
Expand All @@ -259,26 +259,27 @@ def test_non_string_labels_raises(self):
class Test(object):
__str__ = None
self.assertRaises(TypeError, self.counter.labels, Test())
self.assertRaises(TypeError, self.counter.labels, {'l': Test()})
self.assertRaises(TypeError, self.counter.labels, l=Test())

def test_namespace_subsystem_concatenated(self):
c = Counter('c', 'help', namespace='a', subsystem='b', registry=self.registry)
c.inc()
self.assertEqual(1, self.registry.get_sample_value('a_b_c'))

def test_labels_by_dict(self):
self.counter.labels({'l': 'x'}).inc()
def test_labels_by_kwarg(self):
self.counter.labels(l='x').inc()
self.assertEqual(1, self.registry.get_sample_value('c', {'l': 'x'}))
self.assertRaises(ValueError, self.counter.labels, {'l': 'x', 'm': 'y'})
self.assertRaises(ValueError, self.counter.labels, {'m': 'y'})
self.assertRaises(ValueError, self.counter.labels, {})
self.two_labels.labels({'a': 'x', 'b': 'y'}).inc()
self.assertRaises(ValueError, self.counter.labels, l='x', m='y')
self.assertRaises(ValueError, self.counter.labels, m='y')
self.assertRaises(ValueError, self.counter.labels)
self.two_labels.labels(a='x', b='y').inc()
self.assertEqual(1, self.registry.get_sample_value('two', {'a': 'x', 'b': 'y'}))
self.assertRaises(ValueError, self.two_labels.labels, {'a': 'x', 'b': 'y', 'c': 'z'})
self.assertRaises(ValueError, self.two_labels.labels, {'a': 'x', 'c': 'z'})
self.assertRaises(ValueError, self.two_labels.labels, {'b': 'y', 'c': 'z'})
self.assertRaises(ValueError, self.two_labels.labels, {'c': 'z'})
self.assertRaises(ValueError, self.two_labels.labels, {})
self.assertRaises(ValueError, self.two_labels.labels, a='x', b='y', c='z')
self.assertRaises(ValueError, self.two_labels.labels, a='x', c='z')
self.assertRaises(ValueError, self.two_labels.labels, b='y', c='z')
self.assertRaises(ValueError, self.two_labels.labels, c='z')
self.assertRaises(ValueError, self.two_labels.labels)
self.assertRaises(ValueError, self.two_labels.labels, {'a': 'x'}, b='y')

def test_invalid_names_raise(self):
self.assertRaises(ValueError, Counter, '', 'help')
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.