Skip to content

Commit ba935cd

Browse files
committed
statsd format first try, statsd udp tests, http transport, vic+http basic tests
1 parent 5fadebc commit ba935cd

File tree

22 files changed

+498
-112
lines changed

22 files changed

+498
-112
lines changed

.coveragerc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[run]
2+
branch = True
3+
include =
4+
prometheus_push_client/**
5+
omit =
6+
test/**
7+
8+
[report]
9+
exclude_lines =
10+
pragma: no cover
11+
raise NotImplementedError
12+
if __name__ == .__main__.:

.github/workflows/tests.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,25 @@ jobs:
1212
name: run all tests
1313
runs-on: ubuntu-20.04
1414
strategy:
15+
fail-fast: false
1516
matrix:
1617
python-version: [3.6, 3.7, 3.8, 3.9, 'pypy3']
1718
services:
1819
victoria:
1920
image: victoriametrics/victoria-metrics:v1.59.0
20-
#options: >-
21-
# --entrypoint "/victoria-metrics-prod", "--envflag.enable"]
2221
env:
2322
httpListenAddr: 8429
2423
influxListenAddr: 8491
25-
graphiteListenAddr: 8492
2624
ports:
2725
- 8428:8428
2826
- 8491:8491
29-
- 8492:8492
27+
- 8491:8491/udp
28+
statsd-exporter:
29+
image: prom/statsd-exporter:v0.20.2
30+
ports:
31+
- 9102:9102
32+
- 9125:9125
33+
- 9125:9125/udp
3034
steps:
3135
- name: checkout
3236
uses: actions/checkout@v2
@@ -37,14 +41,15 @@ jobs:
3741
- name: pip-requirements
3842
run: pip install --upgrade -e .[test]
3943
- name: run-test
40-
run: pytest -svvv --continue-on-collection-errors --cov=./prometheus_push_client --cov-report=xml:coverage.xml
44+
run: pytest
4145
env:
4246
VM_HOST: localhost
4347
VM_API_PORT: 8428
4448
VM_INFLUX_PORT: 8491
45-
VM_GRAPHITE_PORT: 8492
49+
STATSD_HOST: localhost
50+
STATSD_API_PORT: 9102
51+
STATSD_UDP_PORT: 9125
4652
- name: upload-cov
4753
uses: codecov/codecov-action@v1
4854
with:
4955
files: coverage.xml
50-
verbose: true

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# prometheus-push-client
1+
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/gistart/prometheus-push-client/test-all)](https://github.com/gistart/prometheus-push-client/actions)
2+
[![Codecov](https://img.shields.io/codecov/c/github/gistart/prometheus-push-client)](https://codecov.io/gh/gistart/prometheus-push-client)
23

3-
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/gistart/prometheus-push-client/test-all)
4-
![Codecov](https://img.shields.io/codecov/c/github/gistart/prometheus-push-client)
4+
# prometheus-push-client
55

66
## Default labelvalues
77

prometheus_push_client/__init__.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
# TODO: clients.fg
33
from .decorators import (
44
influx_udp_async,
5-
graphite_udp_async,
5+
statsd_udp_async,
66
influx_udp_thread,
7-
graphite_udp_thread,
7+
statsd_udp_thread,
8+
influx_http_async,
9+
influx_http_thread,
810
)
911
from .formats.influx import InfluxFormat
10-
from .formats.graphite import GraphiteFormat
11-
from .formats.prometheus import PrometheusFormat
12+
from .formats.statsd import StatsdFormat
13+
from .formats.openmetrics import OpenMetricsFormat
1214
from .metrics import Counter, Gauge, Summary, Histogram, Info, Enum
1315
from .registry import PUSH_REGISTRY
16+
from .transports.http import SyncHttpTransport, AioHttpTransport
1417
from .transports.udp import SyncUdpTransport, AioUdpTransport
15-
# TODO: transports.http
18+
from .version import __version__

prometheus_push_client/clients/bg.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ def start(self):
3333

3434
def stop(self):
3535
self.stop_event.set()
36-
self.join()
37-
self.transport.stop()
36+
try:
37+
self.join()
38+
finally:
39+
self.transport.stop()
3840

3941
def run(self):
4042
period = self.period
@@ -62,8 +64,10 @@ async def start(self):
6264

6365
async def stop(self):
6466
self.stop_event.set()
65-
await asyncio.wait([self._runner]) # TODO timeout, catch errors
66-
self.transport.stop()
67+
try:
68+
await asyncio.wait([self._runner])
69+
finally:
70+
await self.transport.stop()
6771

6872
async def run(self):
6973
period = self.period

prometheus_push_client/decorators.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,36 @@ def influx_udp_thread(host, port, period=15.0):
4747
return _thread_bg(client)
4848

4949

50-
def graphite_udp_async(host, port, period=15.0):
50+
def influx_http_async(url, period=15.0):
5151
client = ppc.AsyncioBGClient(
52-
format=ppc.GraphiteFormat(),
52+
format=ppc.InfluxFormat(),
53+
transport=ppc.AioHttpTransport(url),
54+
period=period,
55+
)
56+
return _async_bg(client)
57+
58+
59+
def influx_http_thread(url, period=15.0):
60+
client = ppc.ThreadBGClient(
61+
format=ppc.InfluxFormat(),
62+
transport=ppc.SyncHttpTransport(url),
63+
period=period,
64+
)
65+
return _thread_bg(client)
66+
67+
68+
def statsd_udp_async(host, port, period=15.0):
69+
client = ppc.AsyncioBGClient(
70+
format=ppc.StatsdFormat(),
5371
transport=ppc.AioUdpTransport(host, port),
5472
period=period,
5573
)
5674
return _async_bg(client)
5775

5876

59-
def graphite_udp_thread(host, port, period=15.0):
77+
def statsd_udp_thread(host, port, period=15.0):
6078
client = ppc.ThreadBGClient(
61-
format=ppc.GraphiteFormat(),
79+
format=ppc.StatsdFormat(),
6280
transport=ppc.SyncUdpTransport(host, port),
6381
period=period,
6482
)

prometheus_push_client/formats/graphite.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

prometheus_push_client/formats/influx.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ def validate_metric_names(self, registry):
2525
def format_sample(self, sample, *_):
2626
sample_name, measurement_name = sample.name.rsplit("_", 1)
2727

28-
tags = ""
28+
tag_set = ""
2929
if sample.labels:
30-
tags = ",".join(f"{k}={v}" for k,v in sample.labels.items())
31-
tags = f",{tags}"
30+
tags = ["", *(f"{k}={v}" for k, v in sample.labels.items())]
31+
tag_set = ",".join(tags)
3232

3333
ts = ""
3434
if sample.timestamp:
3535
ts = f" {int(sample.timestamp * 1e9)}" # to nanoseconds
3636

3737
return self.FMT_SAMPLE.format(
3838
sample_name=sample_name,
39-
tag_set=tags,
39+
tag_set=tag_set,
4040
measurement_name=measurement_name,
4141
value=sample.value,
4242
timestamp=ts,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import prometheus_client as pc
2+
3+
from prometheus_push_client.formats.base import BaseFormat
4+
5+
6+
class OpenMetricsFormat(BaseFormat):
7+
"""
8+
As described at:
9+
https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md
10+
"""
11+
12+
FMT_DATAPOINT = "%(measurement)s%(tag_set)s %(value)s%(timestamp)s"
13+
14+
ESCAPING = str.maketrans({
15+
'"': r'\"',
16+
'\\': r'\\',
17+
'\n': r'\n',
18+
})
19+
20+
21+
def format_sample(self, sample, metric):
22+
tag_set = ""
23+
if sample.labels:
24+
tags = (f'{k}="{v.translate(self.ESCAPING)}"' for k, v in sample.labels.items())
25+
tag_set = "{%s}" % ",".join(tags)
26+
27+
ts = ""
28+
if sample.timestamp:
29+
ts = " %s" % sample.timestamp
30+
31+
# TODO: TYPE string?
32+
return self.FMT_DATAPOINT % dict(
33+
measurement=sample.name,
34+
tag_set=tag_set,
35+
value=sample.value,
36+
timestamp=ts,
37+
)

prometheus_push_client/formats/prometheus.py

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)