14

I wish to push a multi-labeled metric into Prometheus using the Pushgateway. The documentation offer a curl example but I need it sent via Python. In addition, I'd like to embed multiple labels into the metric.

Michael Doubez
  • 5,937
  • 25
  • 39
FuzzyAmi
  • 7,543
  • 6
  • 45
  • 79

6 Answers6

9

First step: Install the client:

pip install prometheus_client

Second step: Paste the following into a Python interpreter:

from prometheus_client import CollectorRegistry, Gauge, push_to_gateway

registry = CollectorRegistry()
g = Gauge('job_last_success_unixtime', 'Last time a batch job successfully finished', registry=registry)
g.set_to_current_time()
push_to_gateway('localhost:9091', job='batchA', registry=registry)
clemens
  • 16,716
  • 11
  • 50
  • 65
samuel161
  • 221
  • 3
  • 2
  • 1
    push_to_gateway('localhost:9091', job='batchA', registry=registry) Here localhost:9091 is it refering where prometheus is running? – user872274 May 11 '22 at 16:18
  • @user872274 No, 9091 refers to the port that is set to the pushgateway. you have to setup a pushgateway alongside your prometheus server, and config the server to scrape the metrics from it. – Ali Soltani Jul 28 '23 at 22:28
7

This is documented for the Python client: https://github.com/prometheus/client_python#exporting-to-a-pushgateway

brian-brazil
  • 31,678
  • 6
  • 93
  • 86
7

If you can't use prometheus_client, here is short version of requests:

import requests

headers = {'X-Requested-With': 'Python requests', 'Content-type': 'text/xml'}
url = "https://pushgateway.example.com/metrics/job/job_name/instance/instance_name"
data = "websites_offline{website=\"example.com\"} 0\n"
r = requests.post(url, headers=headers, data=data)
print(r.reason)
print(r.status_code)

More items can be added after \n (new line) in a data variable.

laimison
  • 1,409
  • 3
  • 17
  • 39
6

Here's what I ended up doing - it took a while to get right. While ideally I would have used the Prometheus python client designed specifically for this purpose, it appears that it doesn't support multiple labels in some cases and the documentation is virtually non-existent - so I went with a home-brewed solution.

The code below uses gevent and supports multiple (comma-delimited) pushgateway urls (like "pushgateway1.my.com:9092, pushgateway2.my.com:9092").

import gevent
import requests

def _submit_wrapper(urls, job_name, metric_name, metric_value, dimensions):
    dim = ''
    headers = {'X-Requested-With': 'Python requests', 'Content-type': 'text/xml'}
    for key, value in dimensions.iteritems():
        dim += '/%s/%s' % (key, value)
    for url in urls:
        requests.post('http://%s/metrics/job/%s%s' % (url, job_name, dim),
                      data='%s %s\n' % (metric_name, metric_value), headers=headers)


def submit_metrics(job_name, metric_name, metric_value, dimensions={}):
    from ..app import config
    cfg = config.init()
    urls = cfg['PUSHGATEWAY_URLS'].split(',')
    gevent.spawn(_submit_wrapper, urls, job_name, metric_name, metric_value, dimensions)
FuzzyAmi
  • 7,543
  • 6
  • 45
  • 79
  • the code above generates an untyped metric. To generate a typed metric, you need to prepend the payload with "# TYPE counter\n" (for a counter metric). – FuzzyAmi Dec 28 '16 at 13:05
0

In one command and without any scripts:

echo "some_metric 3.14" | curl --data-binary @- http://pushgateway.example.org:9091/metrics/job/some_job
Muzammil
  • 417
  • 1
  • 4
  • 20
0

You can use GaugeMetricFamily class. you can take the following steps:

  1. Install prometheus_client:
pip install prometheus_client
  1. Use the following python code to have expose your metrics:
from prometheus_client import CollectorRegistry, push_to_gateway
from prometheus_client.core import GaugeMetricFamily

class CustomCollector(object):
    # make sure you define collect method
    def collect():
        # float metric you want to push
        metric = "<some_float_value>"

        # create gauge metric, define label names
        metric_gauge = GaugeMetricFamily("metric_name", "metric_description", labels=["label1", "label2"])
        # add metric value and label values
        metric_gauge.add_metric(["label1_value", "label2_value"], metric)

        yield metric_gauge



registry = CollectorRegistry()
registry.register(CustomCollector())

# Push metrics to pushgateway (modify the url accordingly)
push_to_gateway('localhost:9091', job='job_name', registry=registry)

Amir nazary
  • 384
  • 1
  • 7