diff options
-rw-r--r-- | .github/workflows/oci.yml | 10 | ||||
-rw-r--r-- | README.md | 20 | ||||
-rw-r--r-- | appinfo/info.xml | 6 | ||||
-rw-r--r-- | lib/Commands/UpdateStorageStats.php | 59 | ||||
-rw-r--r-- | lib/Jobs/UpdateStorageStats.php | 51 | ||||
-rw-r--r-- | lib/StorageStatistics.php | 50 |
6 files changed, 176 insertions, 20 deletions
diff --git a/.github/workflows/oci.yml b/.github/workflows/oci.yml index 2236635..825b690 100644 --- a/.github/workflows/oci.yml +++ b/.github/workflows/oci.yml @@ -12,7 +12,7 @@ env: jobs: oci: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: # do not stop on another job's failure @@ -49,10 +49,6 @@ jobs: with: path: apps/${{ env.APP_NAME }} - - name: Set up PHPUnit - working-directory: apps/${{ env.APP_NAME }} - run: composer i - - name: Set up php ${{ matrix.php-versions }} uses: "shivammathur/setup-php@v2" with: @@ -61,6 +57,10 @@ jobs: tools: phpunit:8.5.2 coverage: none + - name: Set up PHPUnit + working-directory: apps/${{ env.APP_NAME }} + run: composer i + - name: Set up Nextcloud run: | mkdir data @@ -107,3 +107,23 @@ https://<nextcloud-fqdn>/ocs/v2.php/apps/serverinfo/api/v1/info ``` {"ocs":{"meta":{"status":"ok","statuscode":200,"message":"OK"},"data":{"nextcloud":{"system":{"version":"15.0.4.0","theme":"","enable_avatars":"yes","enable_previews":"yes","memcache.local":"OC\\Memcache\\APCu","memcache.distributed":"none","filelocking.enabled":"yes","memcache.locking":"OC\\Memcache\\Redis","debug":"no","freespace":48472944640,"cpuload":[0.84999999999999997779553950749686919152736663818359375,1.04000000000000003552713678800500929355621337890625,1.1699999999999999289457264239899814128875732421875],"mem_total":8183664,"mem_free":5877156,"swap_total":0,"swap_free":0,"apps":{"num_installed":53,"num_updates_available":1,"app_updates":{"files_antivirus":"2.0.1"}}},"storage":{"num_users":7,"num_files":708860,"num_storages":125,"num_storages_local":7,"num_storages_home":7,"num_storages_other":111},"shares":{"num_shares":1,"num_shares_user":0,"num_shares_groups":0,"num_shares_link":0,"num_shares_link_no_password":0,"num_fed_shares_sent":0,"num_fed_shares_received":0,"permissions_4_1":"1"}},"server":{"webserver":"Apache\/2.4","php":{"version":"7.2.14","memory_limit":536870912,"max_execution_time":3600,"upload_max_filesize":535822336},"database":{"type":"mysql","version":"10.2.21","size":331382784}},"activeUsers":{"last5minutes":2,"last1hour":3,"last24hours":5}}}} ``` + +## Configuration + +Since collecting storage statistics might take time and cause slow downs, they are updated in the background. A background job runs once every three hours to update the number of storages and files. The interval can be overridden per app settings (the value is specified in seconds): + +``php occ config:app:set --value=3600 serverinfo job_interval_storage_stats`` + +It is also possible to trigger the update manually per occ call. With verbose mode enabled, the current values are being printed. + +``` +php occ serverinfo:update-storage-statistics -v --output=json_pretty +{ + "num_users": 80, + "num_files": 3934, + "num_storages": 2545, + "num_storages_local": 2, + "num_storages_home": 2510, + "num_storages_other": 33 +} +``` diff --git a/appinfo/info.xml b/appinfo/info.xml index a22d59d..787d613 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -17,6 +17,12 @@ <dependencies> <nextcloud min-version="21" max-version="21" /> </dependencies> + <background-jobs> + <job>OCA\ServerInfo\Jobs\UpdateStorageStats</job> + </background-jobs> + <commands> + <command>OCA\ServerInfo\Commands\UpdateStorageStats</command> + </commands> <settings> <admin>OCA\ServerInfo\Settings\AdminSettings</admin> <admin-section>OCA\ServerInfo\Settings\AdminSection</admin-section> diff --git a/lib/Commands/UpdateStorageStats.php b/lib/Commands/UpdateStorageStats.php new file mode 100644 index 0000000..a561662 --- /dev/null +++ b/lib/Commands/UpdateStorageStats.php @@ -0,0 +1,59 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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/>. + * + */ + +namespace OCA\ServerInfo\Commands; + +use OC\Core\Command\Base; +use OCA\ServerInfo\StorageStatistics; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class UpdateStorageStats extends Base { + /** @var StorageStatistics */ + private $storageStatistics; + + public function __construct(StorageStatistics $storageStatistics) { + parent::__construct(); + + $this->storageStatistics = $storageStatistics; + } + + public function configure() { + parent::configure(); + $this->setName('serverinfo:update-storage-statistics') + ->setDescription('Triggers an update of the counts related to storages used in serverinfo'); + } + + public function execute(InputInterface $input, OutputInterface $output) { + if ($output->isVeryVerbose()) { + $this->writeMixedInOutputFormat($input, $output, 'Updating database counts. This might take a while.'); + } + $this->storageStatistics->updateStorageCounts(); + if ($output->isVerbose()) { + $this->writeArrayInOutputFormat($input, $output, $this->storageStatistics->getStorageStatistics()); + } + return 0; + } +} diff --git a/lib/Jobs/UpdateStorageStats.php b/lib/Jobs/UpdateStorageStats.php new file mode 100644 index 0000000..034395c --- /dev/null +++ b/lib/Jobs/UpdateStorageStats.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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/>. + * + */ + +namespace OCA\ServerInfo\Jobs; + +use OCA\ServerInfo\StorageStatistics; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\TimedJob; +use OCP\IConfig; + +class UpdateStorageStats extends TimedJob { + + /** @var StorageStatistics */ + private $storageStatistics; + + public function __construct(ITimeFactory $time, StorageStatistics $storageStatistics, IConfig $config) { + $this->setInterval((int)$config->getAppValue('serverinfo', 'job_interval_storage_stats', (string)(60 * 60 * 3))); + parent::__construct($time); + + $this->storageStatistics = $storageStatistics; + } + + /** + * @inheritDoc + */ + protected function run($argument) { + $this->storageStatistics->updateStorageCounts(); + } +} diff --git a/lib/StorageStatistics.php b/lib/StorageStatistics.php index ce5586b..e922016 100644 --- a/lib/StorageStatistics.php +++ b/lib/StorageStatistics.php @@ -22,27 +22,31 @@ namespace OCA\ServerInfo; +use OCP\IConfig; use OCP\IDBConnection; class StorageStatistics { /** @var IDBConnection */ private $connection; + /** @var IConfig */ + private $config; /** * SystemStatistics constructor. * * @param IDBConnection $connection */ - public function __construct(IDBConnection $connection) { + public function __construct(IDBConnection $connection, IConfig $config) { $this->connection = $connection; + $this->config = $config; } public function getStorageStatistics() { return [ 'num_users' => $this->countUserEntries(), - 'num_files' => $this->countEntries('filecache'), - 'num_storages' => $this->countEntries('storages'), + 'num_files' => $this->getCountOf('filecache'), + 'num_storages' => $this->getCountOf('storages'), 'num_storages_local' => $this->countStorages('local'), 'num_storages_home' => $this->countStorages('home'), 'num_storages_other' => $this->countStorages('other'), @@ -65,18 +69,34 @@ class StorageStatistics { return (int) $row['num_entries']; } - /** - * @param string $tableName - * @return int - */ - protected function countEntries($tableName) { - $query = $this->connection->getQueryBuilder(); - $query->selectAlias($query->createFunction('COUNT(*)'), 'num_entries') - ->from($tableName); - $result = $query->execute(); - $row = $result->fetch(); - $result->closeCursor(); - return (int) $row['num_entries']; + protected function getCountOf(string $table): int { + return (int)$this->config->getAppValue('serverinfo', 'cached_count_' . $table, '0'); + } + + public function updateStorageCounts(): void { + $storageCount = 0; + $fileCount = 0; + + $fileQuery = $this->connection->getQueryBuilder(); + $fileQuery->select($fileQuery->func()->count()) + ->from('filecache') + ->where($fileQuery->expr()->eq('storage', $fileQuery->createParameter('storageId'))); + + $storageQuery = $this->connection->getQueryBuilder(); + $storageQuery->selectAlias('numeric_id', 'id') + ->from('storages'); + $storageResult = $storageQuery->execute(); + while ($storageRow = $storageResult->fetch()) { + $storageCount++; + $fileQuery->setParameter('storageId', $storageRow['id']); + $fileResult = $fileQuery->execute(); + $fileCount += (int)$fileResult->fetchOne(); + $fileResult->closeCursor(); + } + $storageResult->closeCursor(); + + $this->config->setAppValue('serverinfo', 'cached_count_filecache' , (string)$fileCount); + $this->config->setAppValue('serverinfo', 'cached_count_storages', (string)$storageCount); } /** |