Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
```
6 changes: 6 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<dependencies>
<nextcloud min-version="20" max-version="20" />
</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>
Expand Down
59 changes: 59 additions & 0 deletions lib/Commands/UpdateStorageStats.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Arthur Schiwon <[email protected]>
*
* @author Arthur Schiwon <[email protected]>
*
* @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;
}
}
51 changes: 51 additions & 0 deletions lib/Jobs/UpdateStorageStats.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2020 Arthur Schiwon <[email protected]>
*
* @author Arthur Schiwon <[email protected]>
*
* @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();
}
}
50 changes: 35 additions & 15 deletions lib/StorageStatistics.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand All @@ -65,18 +69,34 @@ protected function countUserEntries() {
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->fetchColumn();
$fileResult->closeCursor();
}
$storageResult->closeCursor();

$this->config->setAppValue('serverinfo', 'cached_count_filecache' , (string)$fileCount);
$this->config->setAppValue('serverinfo', 'cached_count_storages', (string)$storageCount);
}

/**
Expand Down