|
3 | 3 |
|
4 | 4 | # prometheus-push-client
|
5 | 5 |
|
| 6 | +Push metrics from your regular and/or long-running jobs into existing Prometheus/VictoriaMetrics monitoring system. |
| 7 | + |
| 8 | +:no-entry: not tested in real environment yet! |
| 9 | + |
| 10 | +Currently supports pushes directly into VictoriaMetrics via UDP and HTTP using InfluxDB line protocol as [described here](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html?highlight=telegraf#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf), and into StatsD/statsd-exporter in StatsD format via UDP ([not ideal](https://github.com/prometheus/statsd_exporter#with-statsd)). |
| 11 | + |
6 | 12 | ## Default labelvalues
|
7 | 13 |
|
8 |
| -! host AND victoria account id |
| 14 | +With regular prometheus_client we can define defaults for either none or all our labels with `labelvalues`, but that's not enough. |
| 15 | + |
| 16 | +We probably want to define some defaults, like `hostname`, or more importantly, **if we use VictoriaMetrics cluster** we need to push label `VictoriaMetrics_AccountID=<int>` (usually 1) or else our metrics will be ignored! |
| 17 | + |
| 18 | +Following example shows how to use defaults, and how to override them if necessary. |
| 19 | + |
| 20 | +```python |
| 21 | +counter1 = ppc.Counter( |
| 22 | + name="c1", |
| 23 | + labelnames=["VictoriaMetrics_AccountID", "host", "event_type"], |
| 24 | + default_labelvalues={ |
| 25 | + "VictoriaMetrics_AccountID": 1, |
| 26 | + "host": socket.gethostname(), |
| 27 | + } |
| 28 | +) |
| 29 | + |
| 30 | + |
| 31 | +# regular usage |
| 32 | +counter1.labels(event_type="login").inc() |
| 33 | + |
| 34 | +# overriding defaults |
| 35 | +counter1.labels(host="non-default", event_type="login").inc() |
| 36 | +# same effect as above: defaults are applied in `labelvalues` |
| 37 | +# order for "missing" labels in the beginning |
| 38 | +counter1.labels("non-default", "login").inc() |
| 39 | +``` |
| 40 | + |
| 41 | +Metrics with no labels are initialized at creation time. This can have unpleasant side-effect: if we initialize lots of metrics not used in currently running job, background clients will have to push their non-changing values in every synchronization session. |
| 42 | + |
| 43 | +To avoid that we'll have to properly isolate each task's metrics, which can be impossible or rather tricky, or we can create metrics with default, non-changing labels (like `hostname`). Such metrics will initialize on fisrt use (inc), and we'll be pusing only metrics we actually used! |
| 44 | + |
| 45 | + |
| 46 | +## Background clients |
| 47 | + |
| 48 | +Background clients spawn synchronization jobs "in background" (meaning in thread or asyncio task) to periodially send all metrics from `ppc.PUSH_REGISTRY` to the destination. |
| 49 | + |
| 50 | +:warning: background clients will attempt to stop gracefully, syncronizing registry "for the last time" after our job exits or crashes. This _may_ mess up aggregation with sampling, I'm not sure yet. |
| 51 | + |
| 52 | +Best way to use them -- via decorators. These clients are intended to be used with long running, but finite tasks, that could be spawned anywhere, therefor not easily accessible by the scraper. If that's not the case -- just use "passive mode" w/ the scaper) |
| 53 | + |
| 54 | +``` python |
| 55 | +def influx_udp_async(host, port, period=15.0): |
| 56 | +def influx_udp_thread(host, port, period=15.0): |
| 57 | +def influx_http_async(url, period=15.0): |
| 58 | +def influx_http_thread(url, period=15.0): |
| 59 | +def statsd_udp_async(host, port, period=15.0): |
| 60 | +def statsd_udp_thread(host, port, period=15.0): |
| 61 | +``` |
| 62 | + |
| 63 | +Usage example: |
| 64 | +```python |
| 65 | +import priometheus_push_client as ppc |
| 66 | + |
| 67 | + |
| 68 | +req_hist = ppc.Histogram( |
| 69 | + name="external_requests", |
| 70 | + namespace="acme" |
| 71 | + subsystem="job123", |
| 72 | + unit="seconds", |
| 73 | + labelnames=["service"] |
| 74 | +) |
| 75 | + |
| 76 | + |
9 | 77 |
|
10 |
| -! side-effect: does not register labelled metrics at creation time, so you report only metrics that you used! |
| 78 | +@ppc.influx_udp_async("victoria.acme.inc.net", 9876, period=15) |
| 79 | +async def main(urls): |
| 80 | + # the job ... |
| 81 | + req_hist.labels(gethostname(url)).observe(response.elapsed) |
| 82 | + # ... |
| 83 | +``` |
0 commit comments