110 lines
4.1 KiB
Python
Executable File
110 lines
4.1 KiB
Python
Executable File
#! /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_rss_total = Gauge(
|
|
'uwsgi_workers_rss_total', 'Total 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_vsz_total = Gauge(
|
|
'uwsgi_workers_vsz_total', 'Total VSZ of uwsgi workers', ['app'], registry=registry
|
|
)
|
|
uwsgi_workers_status = Gauge(
|
|
'uwsgi_workers_status', 'uwsgi workers status', ['app', 'status'], registry=registry
|
|
)
|
|
uwsgi_spooler_count = Gauge('uwsgi_spooler_count', 'uwsgi spooler count', ['app'], registry=registry)
|
|
|
|
|
|
app_name = None
|
|
|
|
for stats_sock in glob.glob('/run/*/stats.sock'):
|
|
uwsgi_app_name = stats_sock.split('/')[2]
|
|
app_name = uwsgi_app_name.replace('authentic2-multitenant', 'authentic')
|
|
|
|
with open('/etc/machine-id') as fd:
|
|
machine_id = fd.read().strip()
|
|
|
|
spooler_dir = f'/var/lib/{uwsgi_app_name}/spooler/{machine_id}'
|
|
if os.path.exists(spooler_dir):
|
|
uwsgi_spooler_count.labels(app=app_name).set(len(os.listdir(spooler_dir)))
|
|
|
|
if app_name == 'authentic':
|
|
# do not collect authentic data as it triggers some uwsgi bug
|
|
# https://dev.entrouvert.org/issues/54624
|
|
continue
|
|
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_total.labels(app=app_name).set(sum(workers_rss))
|
|
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_total.labels(app=app_name).set(sum(workers_vsz))
|
|
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_lines = []
|
|
for machine_stat in glob.glob('/var/lib/machines/*/var/lib/prometheus/node-exporter/uwsgi.prom'):
|
|
with open(machine_stat) as fd:
|
|
file_lines = [x for x in fd.readlines() if x not in content_lines]
|
|
content_lines.extend(file_lines)
|
|
if content_lines:
|
|
with open('/var/lib/prometheus/node-exporter/uwsgi.prom.tmp', 'w') as fd:
|
|
fd.write(''.join(content_lines))
|
|
os.rename(
|
|
'/var/lib/prometheus/node-exporter/uwsgi.prom.tmp', '/var/lib/prometheus/node-exporter/uwsgi.prom'
|
|
)
|