61 lines
1.8 KiB
Python
61 lines
1.8 KiB
Python
from re import sub
|
|
|
|
from flask import Flask, request, Response
|
|
from prometheus_client import make_wsgi_app, Gauge, Info
|
|
from werkzeug.middleware.dispatcher import DispatcherMiddleware
|
|
|
|
app = Flask(__name__)
|
|
app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {
|
|
"/metrics": make_wsgi_app()
|
|
})
|
|
|
|
metrics = {}
|
|
|
|
|
|
def to_snake_case(name):
|
|
name = sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
|
name = sub('__([A-Z])', r'_\1', name)
|
|
name = sub('([a-z0-9])([A-Z])', r'\1_\2', name)
|
|
return name.lower()
|
|
|
|
|
|
def pars_data(data_name: str, data_value, operation_name: str, backup_name: str):
|
|
if isinstance(data_value, dict):
|
|
for dd, vv in data_value.items():
|
|
pars_data(f"{data_name}_{dd}", vv, operation_name, backup_name)
|
|
else:
|
|
set_metric(data_name, data_value, operation_name, backup_name)
|
|
|
|
|
|
def set_metric(name: str, value, operation_name: str, backup_name: str):
|
|
metric_name = to_snake_case(name)
|
|
|
|
if name not in metrics:
|
|
if isinstance(value, int):
|
|
metrics[name] = Gauge(metric_name, name, ["operation", "name"])
|
|
elif isinstance(value, str) or isinstance(value, bool):
|
|
metrics[name] = Info(metric_name, name, ["operation", "name"])
|
|
else:
|
|
return
|
|
|
|
m = metrics[name]
|
|
if isinstance(m, Gauge):
|
|
m.labels(operation_name, backup_name).set(value)
|
|
elif isinstance(m, Info):
|
|
m.labels(operation_name, backup_name).info({"data": value})
|
|
|
|
|
|
@app.route("/report", methods=["POST"])
|
|
def report() -> Response:
|
|
request.get_json()
|
|
|
|
operation_name = request.json["Extra"]["OperationName"]
|
|
backup_name = request.json["Extra"]["backup-name"]
|
|
|
|
pars_data("duplicati", request.json["Data"], operation_name, backup_name)
|
|
|
|
return Response("Ok", 200)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="127.0.0.1", port=80)
|