forked from aces/Loris
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Core] Add performance profiler logger
This adds a new Profiler class that can be used for logging performance bottlenecks in LORIS. To use it, add a call to Profiler::checkpoint("message") and if the profiler is enabled in the configuration module (default, disabled) it will print to the error logs a timestamp, how long the request has taken so far, the message, max memory usage, and any new memory usage since the last checkpoint call. This can be used to debug where requests are slowing down. The checkpoints added in this PR are the places that I used to optimize the dataquery module.
- Loading branch information
Dave MacFarlane
committed
Oct 2, 2024
1 parent
403fd0c
commit 0481617
Showing
9 changed files
with
100 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, DataType, Parent, Label, OrderNumber) SELECT 'profiler_log_level', 'Verbosity of performance profiler logging', 1, 0, 'log_level', ID, 'Profiler Log Level', 3 FROM ConfigSettings WHERE Name='logs'; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php declare(strict_types=1); | ||
|
||
use \Psr\Log\LoggerInterface; | ||
|
||
/** | ||
* Class to consistently log profiling related information to LORIS | ||
* logs so that performance issues can be more easily debugged. | ||
* | ||
* @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 | ||
*/ | ||
class Profiler | ||
{ | ||
protected \DateTimeImmutable $startTime; | ||
protected ?\DateTimeImmutable $lastCheckpoint; | ||
protected int $lastMemory; | ||
protected LoggerInterface $logger; | ||
|
||
/** | ||
* Private constructor that is only called from checkpoint, so | ||
* that a singleton is used. | ||
*/ | ||
private function __construct() | ||
{ | ||
|
||
$this->startTime = new \DateTimeImmutable(); | ||
$this->lastMemory = memory_get_peak_usage(); | ||
|
||
$loglevel = \NDB_Config::singleton() | ||
->getLogSettings() | ||
->getProfilerLogLevel(); | ||
if ($loglevel !== "none") { | ||
$this->logger = new \LORIS\Log\ErrorLogLogger(\Psr\Log\LogLevel::DEBUG); | ||
} else { | ||
$this->logger = new \Psr\Log\NullLogger(); | ||
} | ||
} | ||
|
||
/** | ||
* Adds a checkpoint to the error logs that displays the timing since | ||
* the initial checkpoint, and any increase in the PHP max memory usage | ||
* since the last checkpoint. | ||
* | ||
* @param string $msg - A message to display with the stats in the log | ||
* | ||
* @return void | ||
*/ | ||
public static function checkpoint(string $msg) : void | ||
{ | ||
static $profiler = new Profiler(); | ||
$currentMemory = memory_get_peak_usage(); | ||
$now = new \DateTimeImmutable(); | ||
$profiler->logger->debug( | ||
"[" | ||
. $now->format("U") | ||
. " (" | ||
. $now->diff($profiler->startTime)->format("%s") . "s)] " | ||
. $msg | ||
. ' (Max memory: ' | ||
. $currentMemory | ||
. ', since last checkpoint: ' | ||
. ($currentMemory - $profiler->lastMemory) | ||
. ')' | ||
); | ||
$profiler->lastCheckpoint = new \DateTimeImmutable(); | ||
$profiler->lastMemory = $currentMemory; | ||
} | ||
} |