Newer
Older
nextcloud-monitoring-dashboard / zabbix-agent-scripts / get_teamfolders_metrics.py
#
# @copyright Copyright (c) 2025, Pietro Marini (pmarini@rcasys.com)
#
# @license GNU AGPL version 3 or any later version
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import subprocess

import pandas as pd

import io

import json

cmd = "sudo -u www-data /usr/bin/php /var/www/nextcloud/occ groupfolders:list --output json".split()

try:
    teamfolders_output = subprocess.check_output(cmd)
except:
    print("It seems that the app groupfolders is not installed")

    results = {
        "teamfolder_nr": 0,
        "teamfolder_total_quota_gb": 0,
        "teamfolder_nr_files_trash": 0,
        "teamfolder_nr_files_versions": 0,
        "teamfolder_nr_files": 0,
        "teamfolder_total_trash_size_gb": 0,
        "teamfolder_total_size_gb": 0,
        "teamfolder_total_versions_size_gb": 0,
    }

else:    
    teamfolders = json.loads(teamfolders_output.decode())

    gb_conversion_factor = 1./(1024.*1024.*1024.)
    
    cmd = "sudo -u www-data /usr/bin/php /var/www/nextcloud/occ config:system:get datadirectory".split()
    
    datadir = subprocess.check_output(cmd).strip(b"\n").decode()
                                     
    ####################
    # Metrics
    ####################
    
    # Number of team folders
    teamfolder_nr = len(teamfolders)
    
    # Total quota assigned to team folders
    teamfolders_quota = [teamfolder['quota'] for teamfolder in teamfolders]
    
    teamfolder_total_quota_gb = sum(teamfolders_quota)*gb_conversion_factor
    
    # Number of files and folders in team folders (excluding versions and trash)
    cmd = "find /{datadir}/__groupfolders/ -not -path */versions/* -not -path */trash/*".format(datadir=datadir).split()
    
    teamfolder_nr_files_find = subprocess.Popen(cmd, 
    								stdout=subprocess.PIPE)
    
    teamfolder_nr_files = subprocess.check_output(('wc', '-l'), 
    								stdin=teamfolder_nr_files_find.stdout)
    
    teamfolder_nr_files_find.wait()
    
    teamfolder_nr_files = int(teamfolder_nr_files.decode().strip())
    
    # Number of files in team folders versions
    cmd = 'find /{datadir}/__groupfolders/versions/'.format(datadir=datadir).split()
    
    teamfolder_nr_files_versions_find = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    
    teamfolder_nr_files_versions = subprocess.check_output(('wc', '-l'), 
    					stdin=teamfolder_nr_files_versions_find.stdout)
    
    teamfolder_nr_files_versions_find.wait()
    
    teamfolder_nr_files_versions = int(teamfolder_nr_files_versions.decode().strip())-teamfolder_nr-1
    
    # Number of files in team folders trash
    cmd = 'find /ncdata/__groupfolders/trash/'.split()
    
    teamfolder_nr_files_trash_find = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    
    teamfolder_nr_files_trash = subprocess.check_output(('wc', '-l'), 
    								stdin=teamfolder_nr_files_trash_find.stdout)
    
    teamfolder_nr_files_trash_find.wait()
    
    teamfolder_nr_files_trash = int(teamfolder_nr_files_trash.decode().strip())-teamfolder_nr-1
    
    # Storage used by team folders (excluding versions and trash)
    cmd = "du -b -d1 {datadir}/__groupfolders/".format(datadir=datadir).split()
    
    teamfolder_total_size_output = subprocess.check_output(cmd)
    
    df_teamfolder_total_size = pd.read_table(io.StringIO(teamfolder_total_size_output.decode()),names=["folder_size", "folder"])
    
    df_teamfolder_total_size["folder"] = df_teamfolder_total_size.folder.str.removeprefix("{datadir}/__groupfolders/".format(datadir=datadir))
    
    df_teamfolder_total_size["folder_size_gb"]   = df_teamfolder_total_size["folder_size"]*gb_conversion_factor
    
    # Storage used by team folders (excluding versions and trash)
    teamfolder_total_size_gb = float(df_teamfolder_total_size.query("folder not in ('trash', 'versions') and folder != ''").folder_size_gb.sum())
    
    # Storage used by team folders versions
    teamfolder_total_versions_size_gb = float(df_teamfolder_total_size.query("folder == 'versions'").folder_size_gb.sum())
    
    # Storage used by team folders trash
    teamfolder_total_trash_size_gb = float(df_teamfolder_total_size.query("folder == 'trash'").folder_size_gb.sum())
    
    results = {
    	"teamfolder_nr": teamfolder_nr,
    	"teamfolder_total_quota_gb": teamfolder_total_quota_gb,
    	"teamfolder_nr_files_trash": teamfolder_nr_files_trash,
    	"teamfolder_nr_files_versions":teamfolder_nr_files_versions,
    	"teamfolder_nr_files":teamfolder_nr_files,
    	"teamfolder_total_trash_size_gb": teamfolder_total_trash_size_gb,
    	"teamfolder_total_size_gb": teamfolder_total_size_gb,
    	"teamfolder_total_versions_size_gb": teamfolder_total_versions_size_gb, 
    }
    
json.dump(results,
        open("/var/lib/zabbix/output/nc_teamfolders_metrics.json","w")
          )