add exporter for uWSGI metrics (#54609)

This commit is contained in:
Frédéric Péters 2021-06-06 08:47:47 +02:00
parent e0975b8d27
commit 0ea21c0960
5 changed files with 104 additions and 0 deletions

View File

@ -1 +1,2 @@
prometheus-entrouvert-exporter/prometheus-system-exporter.py usr/bin
prometheus-entrouvert-exporter/prometheus-uwsgi-exporter.py usr/bin

View File

@ -0,0 +1,6 @@
[Unit]
Description=Collect uWSGI metrics
[Service]
Type=oneshot
ExecStart=/usr/bin/prometheus-uwsgi-exporter.py

View File

@ -0,0 +1,9 @@
[Unit]
Description=Run uWSGI metrics collection every minute
[Timer]
OnBootSec=0
OnUnitActiveSec=1min
[Install]
WantedBy=timers.target

1
debian/rules vendored
View File

@ -9,3 +9,4 @@ override_dh_auto_build:
override_dh_installsystemd:
dh_installsystemd --name=prometheus-system-exporter
dh_installsystemd --name=prometheus-uwsgi-exporter

View File

@ -0,0 +1,87 @@
#! /usr/bin/python3
import collections
import glob
import json
import os
import socket
import statistics
from prometheus_client import CollectorRegistry, Gauge, write_to_textfile
registry = CollectorRegistry()
uwsgi_workers_rss_avg = Gauge(
'uwsgi_workers_rss_avg', 'Average RSS of uwsgi workers', ['app'], registry=registry
)
uwsgi_workers_rss_med = Gauge(
'uwsgi_workers_rss_med', 'Median RSS of uwsgi workers', ['app'], registry=registry
)
uwsgi_workers_rss_max = Gauge(
'uwsgi_workers_rss_max', 'Maximum RSS of uwsgi workers', ['app'], registry=registry
)
uwsgi_workers_vsz_avg = Gauge(
'uwsgi_workers_vsz_avg', 'Average VSZ of uwsgi workers', ['app'], registry=registry
)
uwsgi_workers_vsz_med = Gauge(
'uwsgi_workers_vsz_med', 'Median VSZ of uwsgi workers', ['app'], registry=registry
)
uwsgi_workers_vsz_max = Gauge(
'uwsgi_workers_vsz_max', 'Maximum VSZ of uwsgi workers', ['app'], registry=registry
)
uwsgi_workers_status = Gauge(
'uwsgi_workers_status', 'uwsgi workers status', ['app', 'status'], registry=registry
)
app_name = None
for stats_sock in glob.glob('/run/*/stats.sock'):
app_name = stats_sock.split('/')[2]
app_name = app_name.replace('authentic2-multitenant', 'authentic')
stats_json = ''
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
s.connect(stats_sock)
while True:
data = s.recv(4096)
if not data:
break
stats_json += data.decode('utf8', 'ignore')
stats_data = json.loads(stats_json)
listen_queue = stats_data['listen_queue']
workers_rss = []
workers_vsz = []
workers_status = collections.defaultdict(int)
workers_status['idle'] = 0
workers_status['busy'] = 0
for worker in stats_data['workers']:
if worker['status'] == 'cheap':
continue
workers_status[worker['status']] += 1
workers_rss.append(worker['rss'])
workers_vsz.append(worker['vsz'])
uwsgi_workers_rss_max.labels(app=app_name).set(max(workers_rss))
uwsgi_workers_rss_avg.labels(app=app_name).set(statistics.mean(workers_rss))
uwsgi_workers_rss_med.labels(app=app_name).set(statistics.median(workers_rss))
uwsgi_workers_vsz_max.labels(app=app_name).set(max(workers_vsz))
uwsgi_workers_vsz_avg.labels(app=app_name).set(statistics.mean(workers_vsz))
uwsgi_workers_vsz_med.labels(app=app_name).set(statistics.median(workers_vsz))
for k in workers_status:
uwsgi_workers_status.labels(app=app_name, status=k).set(workers_status[k])
if app_name:
write_to_textfile('/var/lib/prometheus/node-exporter/uwsgi.prom', registry)
else:
# host for containers?
content = ''
for machine_stat in glob.glob('/var/lib/machines/*/var/lib/prometheus/node-exporter/uwsgi.prom'):
with open(machine_stat) as fd:
content += fd.read()
if content:
with open('/var/lib/prometheus/node-exporter/uwsgi.prom.tmp', 'w') as fd:
fd.write(content)
os.rename(
'/var/lib/prometheus/node-exporter/uwsgi.prom.tmp', '/var/lib/prometheus/node-exporter/uwsgi.prom'
)