You've already forked pg_probackup_exporter
mirror of
https://github.com/pavel-v-sobolev/pg_probackup_exporter.git
synced 2026-06-18 21:35:20 +02:00
first commit
This commit is contained in:
@@ -1 +1,57 @@
|
||||
# pg_probackup_exporter
|
||||
# pg_probackup_exporter
|
||||
|
||||
|
||||
Postgres pg_probackup prometheus metrics exporter.
|
||||
This is a tool for monitoring postgresql backups.
|
||||
It exports pg_probackup metrics as a web service in prometheus format.
|
||||
|
||||
**Installation**<br />
|
||||
1) download pg_probackup_exporter.py and put to your folder. E.g. _/usr/local/bin_
|
||||
2) install python flask library. For ubuntu: _sudo apt install python3-flask_
|
||||
3) set environment variables and run the program with the following command: _python3 /usr/local/bin/pg_probackup_exporter.py_
|
||||
|
||||
**You need to set 3 environment vars:**<br />
|
||||
1) path to your pg_probackup executable e.g.
|
||||
PG_PROBACKUP_COMMAND = '/usr/bin/pg_probackup-17'
|
||||
2) web service port, default 9899
|
||||
PG_PROBACKUP_EXPORTER_PORT = '9899'
|
||||
3) path to backup folder e.g.
|
||||
PG_PROBACKUP_PATH = '/mnt/backup'
|
||||
|
||||
Metrics are available under _http://your_host:port/metrics_<br />
|
||||
|
||||
**Example service file for ubuntu linux:**<br />
|
||||
_sudo nano /etc/systemd/system/pg_probackup_exporter.service_<br />
|
||||
<br />
|
||||
[Service]<br />
|
||||
Type=simple<br />
|
||||
User=postgres<br />
|
||||
Group=postgres<br />
|
||||
Environment=PG_PROBACKUP_COMMAND='/usr/bin/pg_probackup-17'<br />
|
||||
Environment=PG_PROBACKUP_PATH='/mnt/backup'<br />
|
||||
<br />
|
||||
ExecStart=/usr/bin/python3 /usr/local/bin/pg_probackup_exporter.py<br />
|
||||
KillMode=control-group<br />
|
||||
TimeoutSec=5<br />
|
||||
Restart=on-failure<br />
|
||||
RestartSec=10<br />
|
||||
<br />
|
||||
[Install]<br />
|
||||
WantedBy=multi-user.target<br />
|
||||
|
||||
|
||||
**Example for prometheus config**
|
||||
scrape_configs:<br />
|
||||
- job_name: pg_probackup<br />
|
||||
scrape_interval: 30s<br />
|
||||
scrape_timeout: 30s<br />
|
||||
scheme: http<br />
|
||||
static_configs:<br />
|
||||
- targets: ["10.8.200.138:9899"]<br />
|
||||
labels:<br />
|
||||
"service": "postgres"<br />
|
||||
"instance": "pg_master"<br />
|
||||
"host": "10.8.200.138"<br />
|
||||
"Business_Critical": "Medium"<br />
|
||||
"Team": "Postgres"<br />
|
||||
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Author: Pavel Sobolev
|
||||
|
||||
|
||||
"""
|
||||
pg_probackup prometheus metrics exporter.
|
||||
This is a tool for monitoring postgres backups.
|
||||
It exports pg_probackup metrics as a web service in prometheus format.
|
||||
|
||||
To use this program, you need to set 3 environment vars:
|
||||
1) path to your pg_probackup executable e.g.
|
||||
PG_PROBACKUP_COMMAND = '/usr/bin/pg_probackup-17'
|
||||
2) web service port, default 9899
|
||||
PG_PROBACKUP_EXPORTER_PORT = '9899'
|
||||
3) path to backup folder e.g.
|
||||
PG_PROBACKUP_PATH = '/mnt/backup'
|
||||
|
||||
Metrics are available under http://your_host:port/metrics
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from flask import Flask
|
||||
from flask import Response
|
||||
from datetime import datetime
|
||||
|
||||
import os
|
||||
import json
|
||||
from json import JSONDecodeError
|
||||
import sys
|
||||
|
||||
cmd = os.environ.get('PG_PROBACKUP_COMMAND')
|
||||
|
||||
backup_path = os.environ.get('PG_PROBACKUP_PATH')
|
||||
|
||||
if cmd is None:
|
||||
print('ERROR: Need PG_PROBACKUP_COMMAND environment varible')
|
||||
sys.exit()
|
||||
|
||||
if backup_path is None:
|
||||
print('ERROR: Need PG_PROBACKUP_PATH environment varible')
|
||||
sys.exit()
|
||||
|
||||
port = os.environ.get('PG_PROBACKUP_EXPORTER_PORT','9899')
|
||||
|
||||
fields = {'id':'id',
|
||||
'status':'status',
|
||||
'wal':'wal',
|
||||
'backup-mode':'backup_mode',
|
||||
'compress-alg':'compress_alg',
|
||||
'start-time':'start_time',
|
||||
'end-time':'end_time',
|
||||
'retention-redundancy':'retention_redundancy',
|
||||
'retention-window':'retention_window'
|
||||
}
|
||||
|
||||
figures = {'count':'count',
|
||||
'error':'error',
|
||||
'data-bytes':'data_bytes',
|
||||
'wal-bytes':'wal_bytes',
|
||||
'uncompressed-bytes':'uncompressed_bytes'}
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/')
|
||||
def root_folder():
|
||||
return 'pg_probackup metrics'
|
||||
|
||||
@app.route('/metrics')
|
||||
def metrics_folder():
|
||||
|
||||
# call pg_probackup_command
|
||||
show_cmd = f"""{cmd} show --backup-path="{backup_path}" --format=json"""
|
||||
cmd_result = os.popen(show_cmd).read()
|
||||
|
||||
try:
|
||||
data = json.loads(cmd_result)
|
||||
except JSONDecodeError:
|
||||
print(f'ERROR: {show_cmd}\n {cmd_result}')
|
||||
|
||||
res_figures = {}
|
||||
for fig in figures:
|
||||
res_figures[fig] = f"# HELP {figures[fig]}\n"
|
||||
res_figures[fig] += f"# TYPE postgres_backup_{figures[fig]} gauge\n"
|
||||
|
||||
for d in data:
|
||||
n = 0
|
||||
for b in d['backups']:
|
||||
start_time = datetime.strptime(b['start-time'][0:19],'%Y-%m-%d %H:%M:%S')
|
||||
status = b['status']
|
||||
instance = d['instance']
|
||||
|
||||
config_cmd = f"""{cmd} show-config --backup-path="{backup_path}" --format=json --instance={instance}"""
|
||||
cmd_result = os.popen(config_cmd).read()
|
||||
try:
|
||||
config_data = json.loads(cmd_result)
|
||||
except JSONDecodeError:
|
||||
print(f'ERROR: {config_cmd}\n {cmd_result}')
|
||||
|
||||
# append config data to backup data
|
||||
b = b | config_data
|
||||
|
||||
duration_minutes = 0
|
||||
|
||||
|
||||
|
||||
if 'recovery-time' in b:
|
||||
recovery_time = datetime.strptime(b['recovery-time'][0:19],'%Y-%m-%d %H:%M:%S')
|
||||
duration_minutes = round((recovery_time - start_time).seconds/60,2)
|
||||
|
||||
for fig in figures:
|
||||
res_figures[fig] += "postgres_backup_" + figures[fig] + "{service_id=\"" + instance + "\""
|
||||
|
||||
# add all characteristic fields to figure data
|
||||
for fld in fields:
|
||||
if fld in b:
|
||||
res_figures[fig] += "," + fields[fld] + "=\"" + b[fld] + "\""
|
||||
|
||||
# add backup index
|
||||
res_figures[fig] += ",backup_no=\"" + ('00' + str(n))[-3:] + "\""
|
||||
|
||||
# add backup duration
|
||||
res_figures[fig] += ",duration_minutes=\"" + str(duration_minutes) + "\""
|
||||
|
||||
if fig == 'count':
|
||||
res_figures[fig] += "} 1\n"
|
||||
elif fig == 'error':
|
||||
if status=='ERROR':
|
||||
res_figures[fig] += "} 1\n"
|
||||
else:
|
||||
res_figures[fig] += "} 0\n"
|
||||
else:
|
||||
if fig in b:
|
||||
res_figures[fig] += "} " + str(b[fig]) + "\n"
|
||||
else:
|
||||
res_figures[fig] += "} 0\n"
|
||||
n+=1
|
||||
|
||||
# add all figure data to result
|
||||
res = ""
|
||||
for fig in figures:
|
||||
res += res_figures[fig]
|
||||
|
||||
return Response(res, mimetype='text/plain')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
app.run(host='0.0.0.0', port=port)
|
||||
Reference in New Issue
Block a user