From edfa0b07ffa0ff6e1a256b5eff9b5d3f7380ea79 Mon Sep 17 00:00:00 2001 From: psy Date: Sat, 1 Apr 2023 18:10:20 +0200 Subject: [PATCH] add prometheus exporter for groupfolder metrics --- defaults/main.yml | 3 ++ files/nextcloud-prometheus-exporter.service | 18 +++++++ handlers/main.yml | 6 +++ tasks/base.yml | 28 +++++++++++ templates/nextcloud-prometheus-exporter.py.j2 | 49 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 files/nextcloud-prometheus-exporter.service create mode 100644 handlers/main.yml create mode 100644 templates/nextcloud-prometheus-exporter.py.j2 diff --git a/defaults/main.yml b/defaults/main.yml index d1bab2c..532579d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -19,3 +19,6 @@ nextcloud: pw: None name: nextcloud groupfolders: [] + prometheus_exporter: + enabled: True + port: 9123 \ No newline at end of file diff --git a/files/nextcloud-prometheus-exporter.service b/files/nextcloud-prometheus-exporter.service new file mode 100644 index 0000000..d715197 --- /dev/null +++ b/files/nextcloud-prometheus-exporter.service @@ -0,0 +1,18 @@ +[Unit] +Description=nextcloud prometheus exporter +After=mariadb.service +Requires=mariadb.service + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStart=/usr/bin/python3 /usr/local/bin/nextcloud-prometheus-exporter.py +Environment=PYTHONUNBUFFERED=1 +Restart=always + +User=www-data +Group=www-data + +NoNewPrivileges=True +#ProtectSystem=strict diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..d82622d --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,6 @@ +- name: restart prometheus exporter + service: + name: nextcloud-prometheus-exporter + enabled: True + daemon_reload: True + state: restarted \ No newline at end of file diff --git a/tasks/base.yml b/tasks/base.yml index b2813fa..319e462 100644 --- a/tasks/base.yml +++ b/tasks/base.yml @@ -115,3 +115,31 @@ state: link notify: - restart nginx + +- name: + when: nextcloud.prometheus_exporter.enabled + block: + - name: install python and modules + apt: + pkg: + - python3 + - python3-prometheus-client + - python3-schedule + + - name: copy exporter script + notify: restart prometheus exporter + template: + src: nextcloud-prometheus-exporter.py.j2 + dest: /usr/local/bin/nextcloud-prometheus-exporter.py + owner: root + group: root + mode: 0755 + + - name: copy systemd service file + notify: restart prometheus exporter + copy: + src: nextcloud-prometheus-exporter.service + dest: /etc/systemd/system + owner: root + group: root + mode: 0644 diff --git a/templates/nextcloud-prometheus-exporter.py.j2 b/templates/nextcloud-prometheus-exporter.py.j2 new file mode 100644 index 0000000..3dc5b57 --- /dev/null +++ b/templates/nextcloud-prometheus-exporter.py.j2 @@ -0,0 +1,49 @@ +import json +from prometheus_client import Gauge, Summary, start_http_server +import subprocess +import schedule +from time import sleep + + +gauge_groupfolder_quota = Gauge('nextcloud_groupfolder_quota_bytes', 'nextcloud groupfolder quota', ['folder']) +gauge_groupfolder_size = Gauge('nextcloud_groupfolder_bytes', 'nextcloud groupfolder size', ['folder']) + + +def occ(cmd): + args = ['/usr/bin/php', '/usr/share/nextcloud/occ', cmd, '--output=json'] + + process = subprocess.run(args, capture_output=True) + + output = None + + try: + process.check_returncode() + output = json.loads(process.stdout.decode('utf-8')) + except Exception as e: + print('OCC command returned an error:') + print(str(e)) + print(process.stderr.decode('utf-8')) + + return output + + +def update_groupfolders(): + groupfolders = occ('groupfolders:list') + + if not groupfolders: + return + + for groupfolder in groupfolders: + gauge_groupfolder_quota.labels(groupfolder['mount_point']).set(int(groupfolder['quota'])) + gauge_groupfolder_size.labels(groupfolder['mount_point']).set(int(groupfolder['size'])) + + +if __name__ == '__main__': + update_groupfolders() + + schedule.every().minute.do(update_groupfolders) + start_http_server(addr='127.0.0.1', port={{ nextcloud.prometheus_exporter.port }}) + + while True: + schedule.run_pending() + sleep(1)