[FEATURE] Monitor peak memory usage
authorJigal van Hemert <jigal@xs4all.nl>
Thu, 7 Apr 2011 20:34:36 +0000 (22:34 +0200)
committerJigal van Hemert <jigal@xs4all.nl>
Sun, 31 Jul 2011 20:40:13 +0000 (22:40 +0200)
Monitor the peak memory usage during page generation and report if
it exceeds 90% of the memory limit.

Change-Id: Ie0cfed4dce4b2f3e269832a28be7045b972a6867
Resolves: #25836
Reviewed-on: http://review.typo3.org/1507
Reviewed-by: Susanne Moog
Tested-by: Susanne Moog
Tested-by: Thorsten Kahler
Reviewed-by: Stefan Neufeind
Tested-by: Stefan Neufeind
Reviewed-by: Philipp Gampe
Tested-by: Philipp Gampe
Reviewed-by: Jigal van Hemert
t3lib/core_autoload.php
t3lib/utility/class.t3lib_utility_monitor.php [new file with mode: 0644]
typo3/sysext/cms/tslib/index_ts.php
typo3/sysext/reports/reports/locallang.xml
typo3/sysext/reports/reports/status/class.tx_reports_reports_status_systemstatus.php

index 91122af..7701923 100644 (file)
@@ -176,6 +176,7 @@ $t3libClasses = array(
        't3lib_utility_dependency_reference' => PATH_t3lib . 'utility/dependency/class.t3lib_utility_dependency_reference.php',
        't3lib_utility_http' => PATH_t3lib . 'utility/class.t3lib_utility_http.php',
        't3lib_utility_mail' => PATH_t3lib . 'utility/class.t3lib_utility_mail.php',
+       't3lib_utility_monitor' => PATH_t3lib . 'utility/class.t3lib_utility_monitor.php',
        't3lib_utility_phpoptions' => PATH_t3lib . 'utility/class.t3lib_utility_phpoptions.php',
        't3lib_utility_debug' => PATH_t3lib . 'utility/class.t3lib_utility_debug.php',
        't3lib_utility_array' => PATH_t3lib . 'utility/class.t3lib_utility_array.php',
@@ -235,4 +236,4 @@ $t3libClasses = array(
 $tslibClasses = require(PATH_typo3 . 'sysext/cms/ext_autoload.php');
 
 return array_merge($t3libClasses, $tslibClasses);
-?>
\ No newline at end of file
+?>
diff --git a/t3lib/utility/class.t3lib_utility_monitor.php b/t3lib/utility/class.t3lib_utility_monitor.php
new file mode 100644 (file)
index 0000000..b594f04
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2011 Jigal van Hemert <jigal@xs4all.nl>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * This script 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 General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Class to handle monitoring actions.
+ *
+ * @author     Jigal van Hemert <jigal@xs4all.nl>
+ */
+final class t3lib_utility_Monitor {
+
+       /**
+        * Checks peak memory usage and stores data in cache for use in the report module
+        *
+        * @return void
+        */
+       public static function peakMemoryUsage() {
+               $peakUsage = memory_get_peak_usage(TRUE);
+               $memoryLimit = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
+
+               if (is_double($memoryLimit) && $memoryLimit != 0) {
+                       if ($peakUsage / $memoryLimit >= 0.9) {
+                               /** @var $registry t3lib_Registry */
+                               $registry = t3lib_div::makeInstance('t3lib_Registry');
+                               $data = array (
+                                       'used' => $peakUsage,
+                                       'tstamp' => $GLOBALS['EXEC_TIME'],
+                                       'url' => t3lib_div::getIndpEnv('TYPO3_REQUEST_URL')
+                               );
+                               $registry->set('core', 'reports-peakMemoryUsage', $data);
+                       }
+               }
+       }
+}
+
+?>
\ No newline at end of file
index 8b3c4f8..74badfa 100644 (file)
@@ -521,6 +521,10 @@ $TSFE->hook_eofe();
 // ********************
 $TT->pull();
 
+// ******************
+// Check memory usage
+// ******************
+t3lib_utility_Monitor::peakMemoryUsage();
 
 // ******************
 // beLoginLinkIPList
@@ -550,4 +554,4 @@ if (TYPO3_DLOG) {
        t3lib_div::devLog('END of FRONTEND session', 'cms', 0, array('_FLUSH' => TRUE));
 }
 
-?>
\ No newline at end of file
+?>
index c219657..10dd562 100644 (file)
@@ -40,6 +40,9 @@
                        <label index="status_phpMemoryRequirement">Depending on your configuration, TYPO3 can run with a %1$s PHP memory limit. However, a %2$s PHP memory limit or above is required especially if your site uses additional extensions.</label>
                        <label index="status_phpMemoryEditLimit">Increase the memory limit by editing the memory_limit parameter in the file %s and then restart your web server (or contact your system administrator or hosting provider for assistance).</label>
                        <label index="status_phpMemoryContactAdmin">Contact your system administrator or hosting provider for assistance with increasing your PHP memory limit.</label>
+                       <label index="status_phpPeakMemory">PHP peak memory usage</label>
+                       <label index="status_phpPeakMemoryTooHigh">During a request %2$s of the memory limit was used. On %4$s a request to %5$s used %1$s of %3$s.</label>
+                       <label index="status_phpPeakMemoryClearFlag">Clear this flag</label>
                        <label index="status_phpRegisterGlobals">PHP Register Globals</label>
                        <label index="status_phpRegisterGlobalsEnabled">%s is enabled. TYPO3 requires this configuration directive to be disabled.</label>
                        <label index="status_phpRegisterGlobalsSecurity">Your site may not be secure when %s is enabled.</label>
@@ -61,4 +64,4 @@
                        <label index="status_updateTask_email_issues">Issues</label>
                </languageKey>
        </data>
-</T3locallang>
\ No newline at end of file
+</T3locallang>
index e21dc53..98bcf36 100644 (file)
@@ -39,9 +39,12 @@ class tx_reports_reports_status_SystemStatus implements tx_reports_StatusProvide
         * @see typo3/sysext/reports/interfaces/tx_reports_StatusProvider::getStatus()
         */
        public function getStatus() {
+               $this->executeAdminCommand();
+
                $statuses = array(
                        'Php'                 => $this->getPhpStatus(),
                        'PhpMemoryLimit'      => $this->getPhpMemoryLimitStatus(),
+                       'PhpPeakMemory'       => $this->getPhpPeakMemoryStatus(),
                        'PhpRegisterGlobals'  => $this->getPhpRegisterGlobalsStatus(),
                        'Webserver'           => $this->getWebserverStatus(),
                );
@@ -106,6 +109,62 @@ class tx_reports_reports_status_SystemStatus implements tx_reports_StatusProvide
        }
 
        /**
+        * Executes commands like clearing the memory status flag
+        *
+        * @return      void
+        */
+       protected function executeAdminCommand() {
+               $command = t3lib_div::_GET('adminCmd');
+
+               switch ($command) {
+                       case 'clear_peak_memory_usage_flag':
+                               /** @var $registry t3lib_Registry */
+                               $registry = t3lib_div::makeInstance('t3lib_Registry');
+                               $registry->remove('core', 'reports-peakMemoryUsage');
+                               break;
+               }
+       }
+
+       /**
+        * Checks if there was a request in the past which approached the memory limit
+        *
+        * @return tx_reports_reports_status_Status     A status of whether the memory limit was approached by one of the requests
+        */
+       protected function getPhpPeakMemoryStatus() {
+               /** @var $registry t3lib_Registry */
+               $registry = t3lib_div::makeInstance('t3lib_Registry');
+               $peakMemoryUsage = $registry->get('core', 'reports-peakMemoryUsage');
+               $memoryLimit = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
+               $value = $GLOBALS['LANG']->getLL('status_ok');
+
+               $message = '';
+               $severity = tx_reports_reports_status_Status::OK;
+               $bytesUsed = $peakMemoryUsage['used'];
+               $percentageUsed = $memoryLimit ? number_format($bytesUsed / $memoryLimit * 100, 1) . '%' : '?';
+               $dateOfPeak = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $peakMemoryUsage['tstamp']);
+               $urlOfPeak = '<a href="' . htmlspecialchars($peakMemoryUsage['url']) . '">' . htmlspecialchars($peakMemoryUsage['url']) . '</a>';
+               $clearFlagUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=clear_peak_memory_usage_flag';
+
+               if ($peakMemoryUsage['used']) {
+                       $message = sprintf(
+                               $GLOBALS['LANG']->getLL('status_phpPeakMemoryTooHigh'),
+                               t3lib_div::formatSize($peakMemoryUsage['used']),
+                               $percentageUsed,
+                               t3lib_div::formatSize($memoryLimit),
+                               $dateOfPeak,
+                               $urlOfPeak
+                       );
+                       $message .= ' <a href="' . $clearFlagUrl . '">' . $GLOBALS['LANG']->getLL('status_phpPeakMemoryClearFlag') . '</a>.';
+                       $severity = tx_reports_reports_status_Status::WARNING;
+                       $value = $percentageUsed;
+               }
+
+               return t3lib_div::makeInstance('tx_reports_reports_status_Status',
+                       $GLOBALS['LANG']->getLL('status_phpPeakMemory'), $value, $message, $severity
+               );
+       }
+
+       /**
         * checks whether register globals is on or off.
         *
         * @return      tx_reports_reports_status_Status        A status of whether register globals is on or off