From c13b08ec8b2c8c630baa181db4033eebf13401e7 Mon Sep 17 00:00:00 2001 From: flifloo Date: Sat, 10 Jul 2021 15:58:31 +0200 Subject: [PATCH] Report & metrics server --- app.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 8 +++++++ 2 files changed, 69 insertions(+) create mode 100644 app.py create mode 100644 requirements.txt diff --git a/app.py b/app.py new file mode 100644 index 0000000..e3496f8 --- /dev/null +++ b/app.py @@ -0,0 +1,61 @@ +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) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d7df739 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +click==8.0.1 +Flask==2.0.1 +itsdangerous==2.0.1 +Jinja2==3.0.1 +MarkupSafe==2.0.1 +prometheus-client==0.11.0 +uWSGI==2.0.19.1 +Werkzeug==2.0.1