[FEATURE] Monitor peak memory usage
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / reports / status / class.tx_reports_reports_status_systemstatus.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25
26 /**
27 * Performs several checks about the system's health
28 *
29 * @author Ingo Renner <ingo@typo3.org>
30 * @package TYPO3
31 * @subpackage reports
32 */
33 class tx_reports_reports_status_SystemStatus implements tx_reports_StatusProvider {
34
35 /**
36 * Determines the Install Tool's status, mainly concerning its protection.
37 *
38 * @return array List of statuses
39 * @see typo3/sysext/reports/interfaces/tx_reports_StatusProvider::getStatus()
40 */
41 public function getStatus() {
42 $this->executeAdminCommand();
43
44 $statuses = array(
45 'Php' => $this->getPhpStatus(),
46 'PhpMemoryLimit' => $this->getPhpMemoryLimitStatus(),
47 'PhpPeakMemory' => $this->getPhpPeakMemoryStatus(),
48 'PhpRegisterGlobals' => $this->getPhpRegisterGlobalsStatus(),
49 'Webserver' => $this->getWebserverStatus(),
50 );
51
52 return $statuses;
53 }
54
55
56 /**
57 * Checks the current PHP version against a minimum required version.
58 *
59 * @return tx_reports_reports_status_Status A status of whether a minimum PHP version requirment is met
60 */
61 protected function getPhpStatus() {
62 $message = '';
63 $severity = tx_reports_reports_status_Status::OK;
64
65 if (version_compare(phpversion(), TYPO3_REQUIREMENTS_MINIMUM_PHP) < 0) {
66 $message = $GLOBALS['LANG']->getLL('status_phpTooOld');
67 $severity = tx_reports_reports_status_Status::ERROR;
68 }
69
70 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
71 $GLOBALS['LANG']->getLL('status_phpVersion'),
72 phpversion(),
73 $message,
74 $severity
75 );
76 }
77
78 /**
79 * Checks the current memory limit against a minimum required version.
80 *
81 * @return tx_reports_reports_status_Status A status of whether a minimum memory limit requirment is met
82 */
83 protected function getPhpMemoryLimitStatus() {
84 $memoryLimit = ini_get('memory_limit');
85 $message = '';
86 $severity = tx_reports_reports_status_Status::OK;
87
88 if ($memoryLimit && t3lib_div::getBytesFromSizeMeasurement($memoryLimit) < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_RECOMMENDED_PHP_MEMORY_LIMIT)) {
89 $message = sprintf($GLOBALS['LANG']->getLL('status_phpMemoryRecommendation'), $memoryLimit, TYPO3_REQUIREMENTS_RECOMMENDED_PHP_MEMORY_LIMIT);
90 $severity = tx_reports_reports_status_Status::WARNING;
91 }
92
93 if ($memoryLimit && t3lib_div::getBytesFromSizeMeasurement($memoryLimit) < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) {
94 $message = sprintf($GLOBALS['LANG']->getLL('status_phpMemoryRequirement'), $memoryLimit, TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT);
95 $severity = tx_reports_reports_status_Status::ERROR;
96 }
97
98 if ($severity > tx_reports_reports_status_Status::OK) {
99 if ($php_ini_path = get_cfg_var('cfg_file_path')) {
100 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpMemoryEditLimit'), $php_ini_path);
101 } else {
102 $message .= ' ' . $GLOBALS['LANG']->getLL('status_phpMemoryContactAdmin');
103 }
104 }
105
106 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
107 $GLOBALS['LANG']->getLL('status_phpMemory'), $memoryLimit, $message, $severity
108 );
109 }
110
111 /**
112 * Executes commands like clearing the memory status flag
113 *
114 * @return void
115 */
116 protected function executeAdminCommand() {
117 $command = t3lib_div::_GET('adminCmd');
118
119 switch ($command) {
120 case 'clear_peak_memory_usage_flag':
121 /** @var $registry t3lib_Registry */
122 $registry = t3lib_div::makeInstance('t3lib_Registry');
123 $registry->remove('core', 'reports-peakMemoryUsage');
124 break;
125 }
126 }
127
128 /**
129 * Checks if there was a request in the past which approached the memory limit
130 *
131 * @return tx_reports_reports_status_Status A status of whether the memory limit was approached by one of the requests
132 */
133 protected function getPhpPeakMemoryStatus() {
134 /** @var $registry t3lib_Registry */
135 $registry = t3lib_div::makeInstance('t3lib_Registry');
136 $peakMemoryUsage = $registry->get('core', 'reports-peakMemoryUsage');
137 $memoryLimit = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
138 $value = $GLOBALS['LANG']->getLL('status_ok');
139
140 $message = '';
141 $severity = tx_reports_reports_status_Status::OK;
142 $bytesUsed = $peakMemoryUsage['used'];
143 $percentageUsed = $memoryLimit ? number_format($bytesUsed / $memoryLimit * 100, 1) . '%' : '?';
144 $dateOfPeak = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $peakMemoryUsage['tstamp']);
145 $urlOfPeak = '<a href="' . htmlspecialchars($peakMemoryUsage['url']) . '">' . htmlspecialchars($peakMemoryUsage['url']) . '</a>';
146 $clearFlagUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=clear_peak_memory_usage_flag';
147
148 if ($peakMemoryUsage['used']) {
149 $message = sprintf(
150 $GLOBALS['LANG']->getLL('status_phpPeakMemoryTooHigh'),
151 t3lib_div::formatSize($peakMemoryUsage['used']),
152 $percentageUsed,
153 t3lib_div::formatSize($memoryLimit),
154 $dateOfPeak,
155 $urlOfPeak
156 );
157 $message .= ' <a href="' . $clearFlagUrl . '">' . $GLOBALS['LANG']->getLL('status_phpPeakMemoryClearFlag') . '</a>.';
158 $severity = tx_reports_reports_status_Status::WARNING;
159 $value = $percentageUsed;
160 }
161
162 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
163 $GLOBALS['LANG']->getLL('status_phpPeakMemory'), $value, $message, $severity
164 );
165 }
166
167 /**
168 * checks whether register globals is on or off.
169 *
170 * @return tx_reports_reports_status_Status A status of whether register globals is on or off
171 */
172 protected function getPhpRegisterGlobalsStatus() {
173 $value = $GLOBALS['LANG']->getLL('status_disabled');
174 $message = '';
175 $severity = tx_reports_reports_status_Status::OK;
176
177 $registerGlobals = trim(ini_get('register_globals'));
178
179 // can't reliably check for 'on', therefore checking for the oposite 'off', '', or 0
180 if (!empty($registerGlobals) && strtolower($registerGlobals) != 'off') {
181 $registerGlobalsHighlight = '<em>register_globals</em>';
182 $phpManualLink .= '<a href="http://php.net/configuration.changes">' . $GLOBALS['LANG']->getLL('status_phpRegisterGlobalsHowToChange') . '</a>';
183 $message = sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsEnabled'), $registerGlobalsHighlight);
184 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsSecurity'), $registerGlobalsHighlight);
185 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsPHPManual'), $phpManualLink);
186 $severity = tx_reports_reports_status_Status::ERROR;
187 $value = $GLOBALS['LANG']->getLL('status_enabled')
188 . ' (\'' . $registerGlobals . '\')';
189 }
190
191 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
192 $GLOBALS['LANG']->getLL('status_phpRegisterGlobals'), $value, $message, $severity
193 );
194 }
195
196 /**
197 * Reports the webserver TYPO3 is running on.
198 *
199 * @return tx_reports_reports_status_Status The server software as a status
200 */
201 protected function getWebserverStatus() {
202 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
203 $GLOBALS['LANG']->getLL('status_webServer'),
204 $_SERVER['SERVER_SOFTWARE']
205 );
206 }
207 }
208
209
210 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/reports/reports/status/class.tx_reports_reports_status_systemstatus.php'])) {
211 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/reports/reports/status/class.tx_reports_reports_status_systemstatus.php']);
212 }
213
214 ?>