2025-07-29 11:07:08 -04:00
< ? php
declare ( strict_types = 1 );
/**
* SPDX - FileCopyrightText : 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX - License - Identifier : AGPL - 3.0 - or - later
*/
namespace OCA\DAV\Connector\Sabre ;
use Sabre\DAV\Server as SabreServer ;
use Sabre\DAV\ServerPlugin ;
use Sabre\HTTP\RequestInterface ;
use Sabre\HTTP\ResponseInterface ;
/**
* This plugin runs after requests and logs an error if a plugin is detected
* to be doing too many SQL requests .
*/
class PropFindMonitorPlugin extends ServerPlugin {
/**
* A Plugin can scan up to this amount of nodes without an error being
* reported .
*/
public const THRESHOLD_NODES = 50 ;
/**
* A plugin can use up to this amount of queries per node .
*/
public const THRESHOLD_QUERY_FACTOR = 1 ;
private SabreServer $server ;
public function initialize ( SabreServer $server ) : void {
$this -> server = $server ;
$this -> server -> on ( 'afterResponse' , [ $this , 'afterResponse' ]);
}
public function afterResponse (
RequestInterface $request ,
ResponseInterface $response ) : void {
if ( ! $this -> server instanceof Server ) {
return ;
}
$pluginQueries = $this -> server -> getPluginQueries ();
if ( empty ( $pluginQueries )) {
return ;
}
$logger = $this -> server -> getLogger ();
2025-08-05 07:12:00 -04:00
foreach ( $pluginQueries as $eventName => $eventQueries ) {
$maxDepth = max ( 0 , ... array_keys ( $eventQueries ));
// entries at the top are usually not interesting
unset ( $eventQueries [ $maxDepth ]);
foreach ( $eventQueries as $depth => $propFinds ) {
foreach ( $propFinds as $pluginName => $propFind ) {
[
'queries' => $queries ,
'nodes' => $nodes
] = $propFind ;
if ( $queries === 0 || $nodes > $queries || $nodes < self :: THRESHOLD_NODES
|| $queries < $nodes * self :: THRESHOLD_QUERY_FACTOR ) {
continue ;
}
$logger -> error (
'{name}:{event} scanned {scans} nodes with {count} queries in depth {depth}/{maxDepth}. This is bad for performance, please report to the plugin developer!' ,
[
'name' => $pluginName ,
'scans' => $nodes ,
'count' => $queries ,
'depth' => $depth ,
'maxDepth' => $maxDepth ,
'event' => $eventName ,
]
);
2025-07-29 11:07:08 -04:00
}
}
}
}
}