refactor: extract slow operation logging into trait

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2025-09-23 09:40:55 +02:00 committed by Christoph Wurst
parent 5403284b23
commit cc89a2a2b8
4 changed files with 67 additions and 25 deletions

View file

@ -1633,6 +1633,7 @@ return array(
'OC\\Diagnostics\\EventLogger' => $baseDir . '/lib/private/Diagnostics/EventLogger.php',
'OC\\Diagnostics\\Query' => $baseDir . '/lib/private/Diagnostics/Query.php',
'OC\\Diagnostics\\QueryLogger' => $baseDir . '/lib/private/Diagnostics/QueryLogger.php',
'OC\\Diagnostics\\TLogSlowOperation' => $baseDir . '/lib/private/Diagnostics/TLogSlowOperation.php',
'OC\\DirectEditing\\Manager' => $baseDir . '/lib/private/DirectEditing/Manager.php',
'OC\\DirectEditing\\Token' => $baseDir . '/lib/private/DirectEditing/Token.php',
'OC\\EmojiHelper' => $baseDir . '/lib/private/EmojiHelper.php',

View file

@ -1674,6 +1674,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Diagnostics\\EventLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/EventLogger.php',
'OC\\Diagnostics\\Query' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/Query.php',
'OC\\Diagnostics\\QueryLogger' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/QueryLogger.php',
'OC\\Diagnostics\\TLogSlowOperation' => __DIR__ . '/../../..' . '/lib/private/Diagnostics/TLogSlowOperation.php',
'OC\\DirectEditing\\Manager' => __DIR__ . '/../../..' . '/lib/private/DirectEditing/Manager.php',
'OC\\DirectEditing\\Token' => __DIR__ . '/../../..' . '/lib/private/DirectEditing/Token.php',
'OC\\EmojiHelper' => __DIR__ . '/../../..' . '/lib/private/EmojiHelper.php',

View file

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Diagnostics;
use OCP\ILogger;
use Psr\Log\LoggerInterface;
use function microtime;
trait TLogSlowOperation {
/**
* @template R
* @param LoggerInterface $logger
* @param string $operation
* @param callable $fn
* @psalm-param callable(): R $fn
*
* @return mixed
*/
public function monitorAndLog(LoggerInterface $logger, string $operation, callable $fn): mixed {
$timeBefore = microtime(true);
$result = $fn();
$timeAfter = microtime(true);
$timeSpent = $timeAfter - $timeBefore;
if ($timeSpent > 0.1) {
$logLevel = match (true) {
$timeSpent > 25 => ILogger::ERROR,
$timeSpent > 10 => ILogger::WARN,
$timeSpent > 0.5 => ILogger::INFO,
default => ILogger::DEBUG,
};
$logger->log(
$logLevel,
"Slow $operation detected",
[
'timeSpent' => $timeSpent,
],
);
}
return $result;
}
}

View file

@ -10,6 +10,7 @@ declare(strict_types=1);
namespace OC\Session;
use OC\Authentication\Token\IProvider;
use OC\Diagnostics\TLogSlowOperation;
use OCP\Authentication\Exceptions\InvalidTokenException;
use OCP\ILogger;
use OCP\Session\Exceptions\SessionNotAvailableException;
@ -25,6 +26,9 @@ use function microtime;
* @package OC\Session
*/
class Internal extends Session {
use TLogSlowOperation;
/**
* @param string $name
* @throws \Exception
@ -191,31 +195,17 @@ class Internal extends Session {
*/
private function invoke(string $functionName, array $parameters = [], bool $silence = false) {
try {
$timeBefore = microtime(true);
if ($silence) {
$result = @call_user_func_array($functionName, $parameters);
} else {
$result = call_user_func_array($functionName, $parameters);
}
$timeAfter = microtime(true);
$timeSpent = $timeAfter - $timeBefore;
if ($timeSpent > 0.1) {
$logLevel = match (true) {
$timeSpent > 25 => ILogger::ERROR,
$timeSpent > 10 => ILogger::WARN,
$timeSpent > 0.5 => ILogger::INFO,
default => ILogger::DEBUG,
};
$this->logger?->log(
$logLevel,
"Slow session operation $functionName detected",
[
'parameters' => $parameters,
'timeSpent' => $timeSpent,
],
);
}
return $result;
return $this->monitorAndLog(
$this->logger,
$functionName,
function () use ($silence, $functionName, $parameters){
if ($silence) {
return @call_user_func_array($functionName, $parameters);
} else {
return call_user_func_array($functionName, $parameters);
}
}
);
} catch (\Error $e) {
$this->trapError($e->getCode(), $e->getMessage());
}