Skip to content
This repository was archived by the owner on Jul 11, 2022. It is now read-only.

Commit 5da7d0e

Browse files
eundoosongyurishkuro
authored andcommitted
Add PrometheusMetricsFactory (#142)
* Add PrometheusMetricsFactory Signed-off-by: Eundoo Song <[email protected]>
1 parent 58173eb commit 5da7d0e

File tree

4 files changed

+127
-1
lines changed

4 files changed

+127
-1
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,23 @@ def init_jaeger_tracer(service_name='your-app-name'):
8181

8282
Note that the call `initialize_tracer()` also sets the `opentracing.tracer` global variable.
8383

84+
#### Prometheus metrics
85+
86+
This module brings a [Prometheus](https://github.com/prometheus/client_python) integration to the internal Jaeger metrics.
87+
The way to initialize the tracer with Prometheus metrics:
88+
89+
```python
90+
from jaeger_client.metrics.prometheus import PrometheusMetricsFactory
91+
92+
config = Config(
93+
config={},
94+
service_name='your-app-name',
95+
validate=True,
96+
metrics_factory=PrometheusMetricsFactory(namespace='your-app-name')
97+
)
98+
tracer = config.initialize_tracer()
99+
```
100+
84101
### Development
85102

86103
For development, some parameters can be passed via `config` dictionary, as in the Getting Started example above. For more details please see the [Config class](jaeger_client/config.py).
@@ -138,7 +155,6 @@ The B3 codec assumes it will receive lowercase HTTP headers, as this seems
138155
to be the standard in the popular frameworks like Flask and Django.
139156
Please make sure your framework does the same.
140157

141-
142158
## License
143159

144160
[Apache 2.0 License](./LICENSE).
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright (c) 2018, The Jaeger Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from jaeger_client.metrics import MetricsFactory
16+
from collections import defaultdict
17+
from prometheus_client import Counter, Gauge
18+
19+
20+
class PrometheusMetricsFactory(MetricsFactory):
21+
"""
22+
Provides metrics backed by Prometheus
23+
"""
24+
def __init__(self, namespace=''):
25+
self._cache = defaultdict(object)
26+
self._namespace = namespace
27+
28+
def _get_tag_name_list(self, tags):
29+
if tags is None:
30+
return []
31+
tag_name_list = []
32+
for key in tags.keys():
33+
tag_name_list.append(key)
34+
return tag_name_list
35+
36+
def _get_metric(self, metric, name, label_name_list):
37+
cache_key = name + ''.join(label_name_list)
38+
if self._cache.get(cache_key) is None:
39+
self._cache[cache_key] = metric(name=name, documentation=name,
40+
labelnames=label_name_list, namespace=self._namespace)
41+
return self._cache[cache_key]
42+
43+
def create_counter(self, name, tags=None):
44+
label_name_list = self._get_tag_name_list(tags)
45+
counter = self._get_metric(Counter, name, label_name_list)
46+
if tags is not None and len(tags) > 0:
47+
counter = counter.labels(**tags)
48+
49+
def increment(value):
50+
counter.inc(value)
51+
return increment
52+
53+
def create_gauge(self, name, tags=None):
54+
label_name_list = self._get_tag_name_list(tags)
55+
gauge = self._get_metric(Gauge, name, label_name_list)
56+
if tags is not None and len(tags) > 0:
57+
gauge = gauge.labels(**tags)
58+
59+
def update(value):
60+
gauge.set(value)
61+
return update

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
'coveralls',
6363
'tchannel>=0.27;python_version<"3"',
6464
'opentracing_instrumentation>=2,<3',
65+
'prometheus_client',
6566
]
6667
},
6768
)

tests/test_prometheus.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) 2018, The Jaeger Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from jaeger_client.metrics.prometheus \
16+
import PrometheusMetricsFactory
17+
from prometheus_client import REGISTRY
18+
19+
20+
def test_prometheus_metrics_counter():
21+
metrics = PrometheusMetricsFactory(namespace='test')
22+
counter1 = metrics.create_counter(name='jaeger:test_counter', tags={'result': 'ok'})
23+
counter1(1)
24+
counter2 = metrics.create_counter(name='jaeger:test_counter', tags={'result': 'ok'})
25+
counter2(1)
26+
after = REGISTRY.get_sample_value('test_jaeger:test_counter', {'result': 'ok'})
27+
assert 2 == after
28+
29+
def test_prometheus_metrics_counter_without_tags():
30+
metrics = PrometheusMetricsFactory()
31+
counter = metrics.create_counter(name='jaeger:test_counter_no_tags')
32+
counter(1)
33+
after = REGISTRY.get_sample_value('jaeger:test_counter_no_tags')
34+
assert 1 == after
35+
36+
def test_prometheus_metrics_guage():
37+
metrics = PrometheusMetricsFactory(namespace='test')
38+
gauge = metrics.create_gauge(name='jaeger:test_gauge', tags={'result': 'ok'})
39+
gauge(1)
40+
after = REGISTRY.get_sample_value('test_jaeger:test_gauge', {'result': 'ok'})
41+
assert 1 == after
42+
43+
def test_prometheus_metrics_gauge_without_tags():
44+
metrics = PrometheusMetricsFactory()
45+
gauge = metrics.create_gauge(name='jaeger:test_gauge_no_tags')
46+
gauge(1)
47+
after = REGISTRY.get_sample_value('jaeger:test_gauge_no_tags')
48+
assert 1 == after

0 commit comments

Comments
 (0)