upadated colorbox andd prod_check

This commit is contained in:
Bachir Soussi Chiadmi
2015-10-12 11:52:36 +02:00
parent 50c3e1c7d7
commit 0ba0c21bb9
27 changed files with 2203 additions and 311 deletions

View File

@@ -97,8 +97,8 @@ function prod_check_settings_form($form, &$form_state) {
$form['prod_check_apc'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced APC settings'),
'#description' => t('These settings are used in the !link functionality.', prod_check_link_array('advanced APC', 'admin/reports/status/apc')),
'#title' => t('Advanced APC/OPcache settings'),
'#description' => t('These settings are used in the !link functionality.', prod_check_link_array('advanced APC', 'admin/reports/status/apc-opc')),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
@@ -106,7 +106,7 @@ function prod_check_settings_form($form, &$form_state) {
// Cache full count threshold
$form['prod_check_apc']['prod_check_apc_expunge'] = array(
'#type' => 'textfield',
'#title' => t('APC cache full count threshold'),
'#title' => t('APC/OPcache cache full count threshold'),
'#default_value' => variable_get('prod_check_apc_expunge', 0),
'#size' => 2,
'#description' => t('Issue a critical error when the cache full count is greater than the number entered here.'),
@@ -293,7 +293,7 @@ function prod_check_settings_form($form, &$form_state) {
'!settings' => l(t('Nagios page callback'), 'admin/config/system/nagios'),
'%callback' => 'prod_check_nagios_status_page',
)
) .'</p>',
) . '</p>',
);
$form['prod_check_nagios']['nagios']['settings']['prod_check_nagios_verbose'] = array(
@@ -428,7 +428,7 @@ function prod_check_settings_form_validate($form, &$form_state) {
}
if (!is_numeric($form_state['values']['prod_check_apc_expunge'])) {
form_set_error('prod_check_apc_expunge', t('APC Cache full count threshold should be numeric!'));
form_set_error('prod_check_apc_expunge', t('APC/OPcache Cache full count threshold should be numeric!'));
}
if (isset($form_state['values']['prod_check_enable_nagios']) && $form_state['values']['prod_check_enable_nagios']) {
@@ -461,9 +461,11 @@ function prod_check_settings_form_submit($form, &$form_state) {
case t('Save configuration'):
variable_set('prod_check_sitemail', $form_state['values']['prod_check_sitemail']);
// PHP errors.
variable_set('prod_check_dblog_php', $form_state['values']['prod_check_dblog_php']);
variable_set('prod_check_dblog_php_threshold', $form_state['values']['prod_check_dblog_php_threshold']);
// APC.
if (module_exists('dblog')) {
variable_set('prod_check_dblog_php', $form_state['values']['prod_check_dblog_php']);
variable_set('prod_check_dblog_php_threshold', $form_state['values']['prod_check_dblog_php_threshold']);
}
// APC/OPcache.
variable_set('prod_check_apc_expunge', $form_state['values']['prod_check_apc_expunge']);
variable_set('prod_check_apcuser', $form_state['values']['prod_check_apcuser']);
if (!empty($form_state['values']['prod_check_apcpass'])) {
@@ -1031,11 +1033,22 @@ function _prod_check_dbstatus_pgsql($db_name, $details) {
/**
* Integration of the APC status page.
*/
function prod_check_apc() {
define('ADMIN_USERNAME', variable_get('prod_check_apcuser', 'apc'));
define('ADMIN_PASSWORD', variable_get('prod_check_apcpass', 'password'));
include(drupal_get_path('module', 'prod_check') . '/includes/prod_check.apc.inc');
exit;
function prod_check_apc_opc() {
// APC.
if (function_exists('apc_cache_info')) {
define('ADMIN_USERNAME', variable_get('prod_check_apcuser', 'apc'));
define('ADMIN_PASSWORD', variable_get('prod_check_apcpass', 'password'));
include(drupal_get_path('module', 'prod_check') . '/includes/prod_check.apc.inc');
exit;
}
// OPcache.
elseif (function_exists('opcache_get_status')) {
include(drupal_get_path('module', 'prod_check') . '/includes/prod_check.opcache.inc');
exit;
}
else {
return t('APC nor OPcache is installed on this webserver!');
}
}
/**

View File

@@ -0,0 +1,502 @@
<?php
function opcache_get_status() {
return array (
'opcache_enabled' => true,
'cache_full' => false,
'memory_usage' =>
array (
'used_memory' => 12028872,
'free_memory' => 4235696,
'wasted_memory' => 512648,
'current_wasted_percentage' => 3.0556201934814,
),
'opcache_statistics' =>
array (
'num_cached_scripts' => 59,
'num_cached_keys' => 78,
'max_cached_keys' => 223,
'hits' => 66817,
'last_restart_time' => 0,
'misses' => 126,
'blacklist_misses' => 0,
'blacklist_miss_ratio' => 0,
'opcache_hit_rate' => 99.81178017119,
'oom_restarts' => 0,
'manual_restarts' => 0,
'hash_restarts' => 0,
),
'scripts' =>
array (
'/var/www/phpweb/manual/en/toc/faq.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/faq.inc',
'hits' => 9,
'memory_consumption' => 5680,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345905,
),
'/var/www/phpweb/downloads.php' =>
array (
'full_path' => '/var/www/phpweb/downloads.php',
'hits' => 86,
'memory_consumption' => 9488,
'last_used' => 'Sat Mar 16 12:03:47 2013',
'last_used_timestamp' => 1363460627,
'timestamp' => 1355102402,
),
'/var/www/phpweb/include/languages.inc' =>
array (
'full_path' => '/var/www/phpweb/include/languages.inc',
'hits' => 5605,
'memory_consumption' => 16984,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1362994804,
),
'/var/www/phpweb/include/header.inc' =>
array (
'full_path' => '/var/www/phpweb/include/header.inc',
'hits' => 9,
'memory_consumption' => 20352,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1357938001,
),
'/var/www/phpweb/manual/en/toc/getting-started.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/getting-started.inc',
'hits' => 9,
'memory_consumption' => 1936,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345409,
),
'/var/www/phpweb/manual/en/faq.php' =>
array (
'full_path' => '/var/www/phpweb/manual/en/faq.php',
'hits' => 122,
'memory_consumption' => 5152,
'last_used' => 'Sat Mar 16 12:06:15 2013',
'last_used_timestamp' => 1363460775,
'timestamp' => 1363345906,
),
'/var/www/phpweb/include/footer.inc' =>
array (
'full_path' => '/var/www/phpweb/include/footer.inc',
'hits' => 9,
'memory_consumption' => 1976,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1347648001,
),
'/var/www/phpweb/include/site.inc' =>
array (
'full_path' => '/var/www/phpweb/include/site.inc',
'hits' => 5605,
'memory_consumption' => 63488,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1354724402,
),
'/var/www/phpweb/include/mirrors.inc' =>
array (
'full_path' => '/var/www/phpweb/include/mirrors.inc',
'hits' => 5605,
'memory_consumption' => 96160,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363419613,
),
'/var/www/phpweb/manual/en/toc/refs.basic.vartype.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/refs.basic.vartype.inc',
'hits' => 9,
'memory_consumption' => 5032,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345844,
),
'/var/www/phpweb/include/layout.inc' =>
array (
'full_path' => '/var/www/phpweb/include/layout.inc',
'hits' => 5605,
'memory_consumption' => 145704,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1356610801,
),
'/var/www/phpweb/sites.php' =>
array (
'full_path' => '/var/www/phpweb/sites.php',
'hits' => 73,
'memory_consumption' => 2024,
'last_used' => 'Sat Mar 16 12:10:10 2013',
'last_used_timestamp' => 1363461010,
'timestamp' => 1354724402,
),
'/var/www/phpweb/search.php' =>
array (
'full_path' => '/var/www/phpweb/search.php',
'hits' => 3083,
'memory_consumption' => 19728,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1347648005,
),
'/var/www/phpweb/manual/en/toc/langref.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/langref.inc',
'hits' => 49,
'memory_consumption' => 7416,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345411,
),
'/var/www/phpweb/manual/en/toc/index.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/index.inc',
'hits' => 132,
'memory_consumption' => 4680,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345409,
),
'/var/www/phpweb/docs.php' =>
array (
'full_path' => '/var/www/phpweb/docs.php',
'hits' => 73,
'memory_consumption' => 4536,
'last_used' => 'Sat Mar 16 12:04:36 2013',
'last_used_timestamp' => 1363460676,
'timestamp' => 1347648000,
),
'/var/www/phpweb/include/shared-manual.inc' =>
array (
'full_path' => '/var/www/phpweb/include/shared-manual.inc',
'hits' => 122,
'memory_consumption' => 107688,
'last_used' => 'Sat Mar 16 12:06:15 2013',
'last_used_timestamp' => 1363460775,
'timestamp' => 1357938001,
),
'/var/www/phpweb/include/mozopensearch.inc' =>
array (
'full_path' => '/var/www/phpweb/include/mozopensearch.inc',
'hits' => 14,
'memory_consumption' => 1232,
'last_used' => 'Sat Mar 16 12:00:34 2013',
'last_used_timestamp' => 1363460434,
'timestamp' => 1347648001,
),
'/var/www/phpweb/include/ip-to-country.inc' =>
array (
'full_path' => '/var/www/phpweb/include/ip-to-country.inc',
'hits' => 5605,
'memory_consumption' => 21840,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1347648001,
),
'/var/www/phpweb/include/version.inc' =>
array (
'full_path' => '/var/www/phpweb/include/version.inc',
'hits' => 775,
'memory_consumption' => 7880,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363321202,
),
'/var/www/phpweb/include/errors.inc' =>
array (
'full_path' => '/var/www/phpweb/include/errors.inc',
'hits' => 691,
'memory_consumption' => 59888,
'last_used' => 'Sat Mar 16 12:10:33 2013',
'last_used_timestamp' => 1363461033,
'timestamp' => 1347648001,
),
'/var/www/phpweb/include/countries.inc' =>
array (
'full_path' => '/var/www/phpweb/include/countries.inc',
'hits' => 5605,
'memory_consumption' => 31184,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363419614,
),
'/var/www/phpweb/error.php' =>
array (
'full_path' => '/var/www/phpweb/error.php',
'hits' => 691,
'memory_consumption' => 61952,
'last_used' => 'Sat Mar 16 12:10:33 2013',
'last_used_timestamp' => 1363461033,
'timestamp' => 1347648000,
),
'/var/www/phpweb/manual/en/toc/refs.basic.text.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/refs.basic.text.inc',
'hits' => 9,
'memory_consumption' => 3312,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345831,
),
'/var/www/phpweb/include/loadavg.inc' =>
array (
'full_path' => '/var/www/phpweb/include/loadavg.inc',
'hits' => 3775,
'memory_consumption' => 12184,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1354738801,
),
'/var/www/phpweb/include/prepend.inc' =>
array (
'full_path' => '/var/www/phpweb/include/prepend.inc',
'hits' => 5605,
'memory_consumption' => 23432,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1347648001,
),
'/var/www/phpweb/o.php' =>
array (
'full_path' => '/var/www/phpweb/o.php',
'hits' => 1,
'memory_consumption' => 13424,
'last_used' => 'Sat Mar 16 18:11:21 2013',
'last_used_timestamp' => 1363482681,
'timestamp' => 1363482654,
),
'/var/www/phpweb/include/pregen-events.inc' =>
array (
'full_path' => '/var/www/phpweb/include/pregen-events.inc',
'hits' => 1141,
'memory_consumption' => 840,
'last_used' => 'Sat Mar 16 12:15:07 2013',
'last_used_timestamp' => 1363461307,
'timestamp' => 1363419615,
),
'/var/www/phpweb/opcache.php' =>
array (
'full_path' => '/var/www/phpweb/opcache.php',
'hits' => 0,
'memory_consumption' => 13944,
'last_used' => 'Sun Mar 17 01:22:31 2013',
'last_used_timestamp' => 1363508551,
'timestamp' => 1363508542,
),
'/var/www/phpweb/manual/en/toc/refs.calendar.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/refs.calendar.inc',
'hits' => 9,
'memory_consumption' => 2264,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345437,
),
'/var/www/phpweb/manual/en/toc/security.inc' =>
array (
'full_path' => '/var/www/phpweb/manual/en/toc/security.inc',
'hits' => 19,
'memory_consumption' => 5352,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363345419,
),
'/var/www/phpweb/include/pregen-news.inc' =>
array (
'full_path' => '/var/www/phpweb/include/pregen-news.inc',
'hits' => 1161,
'memory_consumption' => 57896,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363419615,
),
'/var/www/phpweb/my.php' =>
array (
'full_path' => '/var/www/phpweb/my.php',
'hits' => 34,
'memory_consumption' => 22640,
'last_used' => 'Sat Mar 16 12:15:15 2013',
'last_used_timestamp' => 1363461315,
'timestamp' => 1354724402,
),
'/var/www/phpweb/include/pregen-confs.inc' =>
array (
'full_path' => '/var/www/phpweb/include/pregen-confs.inc',
'hits' => 678,
'memory_consumption' => 1400,
'last_used' => 'Sat Mar 16 12:02:49 2013',
'last_used_timestamp' => 1363460569,
'timestamp' => 1363419615,
),
'/var/www/index.php' =>
array (
'full_path' => '/var/www/index.php',
'hits' => 1,
'memory_consumption' => 744,
'last_used' => 'Sat Mar 16 12:01:20 2013',
'last_used_timestamp' => 1363460480,
'timestamp' => 1358644238,
),
'/var/www/phpweb/index-stable.php' =>
array (
'full_path' => '/var/www/phpweb/index-stable.php',
'hits' => 679,
'memory_consumption' => 22208,
'last_used' => 'Sat Mar 16 12:02:49 2013',
'last_used_timestamp' => 1363460569,
'timestamp' => 1347648003,
),
'/var/www/phpweb/conferences/index.php' =>
array (
'full_path' => '/var/www/phpweb/conferences/index.php',
'hits' => 462,
'memory_consumption' => 3872,
'last_used' => 'Sat Mar 16 12:15:07 2013',
'last_used_timestamp' => 1363461307,
'timestamp' => 1347648000,
),
'/var/www/phpweb/support.php' =>
array (
'full_path' => '/var/www/phpweb/support.php',
'hits' => 73,
'memory_consumption' => 1912,
'last_used' => 'Sat Mar 16 12:06:40 2013',
'last_used_timestamp' => 1363460800,
'timestamp' => 1347648005,
),
'/var/www/phpweb/op.php' =>
array (
'full_path' => '/var/www/phpweb/op.php',
'hits' => 0,
'memory_consumption' => 1448,
'last_used' => 'Sun Mar 17 01:34:33 2013',
'last_used_timestamp' => 1363509273,
'timestamp' => 1363509263,
),
'/var/www/phpweb/include/posttohost.inc' =>
array (
'full_path' => '/var/www/phpweb/include/posttohost.inc',
'hits' => 342,
'memory_consumption' => 3824,
'last_used' => 'Sat Mar 16 12:09:18 2013',
'last_used_timestamp' => 1363460958,
'timestamp' => 1347648001,
),
'/var/www/phpweb/include/langchooser.inc' =>
array (
'full_path' => '/var/www/phpweb/include/langchooser.inc',
'hits' => 5605,
'memory_consumption' => 23784,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1347648001,
),
'/var/www/phpweb/include/manual-lookup.inc' =>
array (
'full_path' => '/var/www/phpweb/include/manual-lookup.inc',
'hits' => 624,
'memory_consumption' => 26648,
'last_used' => 'Sat Mar 16 12:10:33 2013',
'last_used_timestamp' => 1363461033,
'timestamp' => 1354750802,
),
'/var/www/phpweb/mailing-lists.php' =>
array (
'full_path' => '/var/www/phpweb/mailing-lists.php',
'hits' => 342,
'memory_consumption' => 31576,
'last_used' => 'Sat Mar 16 12:09:18 2013',
'last_used_timestamp' => 1363460958,
'timestamp' => 1361200802,
),
'/var/www/phpweb/include/last_updated.inc' =>
array (
'full_path' => '/var/www/phpweb/include/last_updated.inc',
'hits' => 5605,
'memory_consumption' => 840,
'last_used' => 'Sat Mar 16 12:16:31 2013',
'last_used_timestamp' => 1363461391,
'timestamp' => 1363419675,
),
'/var/www/phpweb/include/email-validation.inc' =>
array (
'full_path' => '/var/www/phpweb/include/email-validation.inc',
'hits' => 342,
'memory_consumption' => 9168,
'last_used' => 'Sat Mar 16 12:09:18 2013',
'last_used_timestamp' => 1363460958,
'timestamp' => 1362175205,
),
'/var/www/phpweb/index.php' =>
array (
'full_path' => '/var/www/phpweb/index.php',
'hits' => 679,
'memory_consumption' => 1840,
'last_used' => 'Sat Mar 16 12:02:49 2013',
'last_used_timestamp' => 1363460569,
'timestamp' => 1347648003,
),
),
);
}
function opcache_get_configuration() {
return array (
'directives' =>
array (
'opcache.enable' => true,
'opcache.enable_cli' => false,
'opcache.use_cwd' => true,
'opcache.validate_timestamps' => true,
'opcache.inherited_hack' => true,
'opcache.dups_fix' => false,
'opcache.revalidate_path' => false,
'opcache.log_verbosity_level' => 4,
'opcache.memory_consumption' => 16777216,
'opcache.interned_strings_buffer' => 8,
'opcache.max_accelerated_files' => 200,
'opcache.max_wasted_percentage' => 0.05,
'opcache.consistency_checks' => 0,
'opcache.force_restart_timeout' => 180,
'opcache.revalidate_freq' => 0,
'opcache.preferred_memory_model' => '',
'opcache.blacklist_filename' => '/etc/zo_blacklist.txt',
'opcache.max_file_size' => 0,
'opcache.error_log' => '',
'opcache.protect_memory' => false,
'opcache.save_comments' => true,
'opcache.load_comments' => true,
'opcache.fast_shutdown' => true,
'opcache.enable_file_override' => false,
'opcache.optimization_level' => 4294967295,
),
'version' =>
array (
'version' => '7.0.1-dev',
'opcache_product_name' => 'Zend Optimizer+',
),
'blacklist' =>
array (
0 => '/var/www/www.php.net/manual/es',
1 => '/var/www/www.php.net/manual/it',
2 => '/var/www/www.php.net/manual/bg',
3 => '/var/www/www.php.net/manual/fa',
4 => '/var/www/www.php.net/manual/fr',
5 => '/var/www/www.php.net/manual/kr',
6 => '/var/www/www.php.net/manual/pt_BR',
7 => '/var/www/www.php.net/manual/tr',
8 => '/var/www/www.php.net/manual/de',
9 => '/var/www/www.php.net/manual/ro',
10 => '/var/www/www.php.net/manual/ru',
11 => '/var/www/www.php.net/manual/zh',
12 => '/var/www/www.php.net/manual/ja',
13 => '/var/www/www.php.net/manual/pl',
14 => '/var/www/www.php.net/manual/sr',
),
);
}

View File

@@ -0,0 +1,748 @@
<?php
/**
* Taken from https://github.com/rlerdorf/opcache-status
*/
define('THOUSAND_SEPARATOR',true);
if (!extension_loaded('Zend OPcache')) {
echo '<div style="background-color: #F2DEDE; color: #B94A48; padding: 1em;">You do not have the Zend OPcache extension loaded, sample data is being shown instead.</div>';
require 'prod_check.opcache.data_sample.inc';
}
class OpCacheDataModel
{
private $_configuration;
private $_status;
private $_d3Scripts = array();
public function __construct()
{
$this->_configuration = opcache_get_configuration();
$this->_status = opcache_get_status();
}
public function getPageTitle()
{
return 'PHP ' . phpversion() . " with OpCache {$this->_configuration['version']['version']}";
}
public function getStatusDataRows()
{
$rows = array();
foreach ($this->_status as $key => $value) {
if ($key === 'scripts') {
continue;
}
if (is_array($value)) {
foreach ($value as $k => $v) {
if ($v === false) {
$value = 'false';
}
if ($v === true) {
$value = 'true';
}
if ($k === 'used_memory' || $k === 'free_memory' || $k === 'wasted_memory') {
$v = $this->_size_for_humans(
$v
);
}
if ($k === 'current_wasted_percentage' || $k === 'opcache_hit_rate') {
$v = number_format(
$v,
2
) . '%';
}
if ($k === 'blacklist_miss_ratio') {
$v = number_format($v, 2) . '%';
}
if ($k === 'start_time' || $k === 'last_restart_time') {
$v = ($v ? date(DATE_RFC822, $v) : 'never');
}
if (THOUSAND_SEPARATOR === true && is_int($v)) {
$v = number_format($v);
}
$rows[] = "<tr><th>$k</th><td>$v</td></tr>\n";
}
continue;
}
if ($value === false) {
$value = 'false';
}
if ($value === true) {
$value = 'true';
}
$rows[] = "<tr><th>$key</th><td>$value</td></tr>\n";
}
return implode("\n", $rows);
}
public function getConfigDataRows()
{
$rows = array();
foreach ($this->_configuration['directives'] as $key => $value) {
if ($value === false) {
$value = 'false';
}
if ($value === true) {
$value = 'true';
}
if ($key == 'opcache.memory_consumption') {
$value = $this->_size_for_humans($value);
}
$rows[] = "<tr><th>$key</th><td>$value</td></tr>\n";
}
return implode("\n", $rows);
}
public function getScriptStatusRows()
{
foreach ($this->_status['scripts'] as $key => $data) {
$dirs[dirname($key)][basename($key)] = $data;
$this->_arrayPset($this->_d3Scripts, $key, array(
'name' => basename($key),
'size' => $data['memory_consumption'],
));
}
asort($dirs);
$basename = '';
while (true) {
if (count($this->_d3Scripts) !=1) break;
$basename .= DIRECTORY_SEPARATOR . key($this->_d3Scripts);
$this->_d3Scripts = reset($this->_d3Scripts);
}
$this->_d3Scripts = $this->_processPartition($this->_d3Scripts, $basename);
$id = 1;
$rows = array();
foreach ($dirs as $dir => $files) {
$count = count($files);
$file_plural = $count > 1 ? 's' : null;
$m = 0;
foreach ($files as $file => $data) {
$m += $data["memory_consumption"];
}
$m = $this->_size_for_humans($m);
if ($count > 1) {
$rows[] = '<tr>';
$rows[] = "<th class=\"clickable\" id=\"head-{$id}\" colspan=\"3\" onclick=\"toggleVisible('#head-{$id}', '#row-{$id}')\">{$dir} ({$count} file{$file_plural}, {$m})</th>";
$rows[] = '</tr>';
}
foreach ($files as $file => $data) {
$rows[] = "<tr id=\"row-{$id}\">";
$rows[] = "<td>" . $this->_format_value($data["hits"]) . "</td>";
$rows[] = "<td>" . $this->_size_for_humans($data["memory_consumption"]) . "</td>";
$rows[] = $count > 1 ? "<td>{$file}</td>" : "<td>{$dir}/{$file}</td>";
$rows[] = '</tr>';
}
++$id;
}
return implode("\n", $rows);
}
public function getScriptStatusCount()
{
return count($this->_status["scripts"]);
}
public function getGraphDataSetJson()
{
$dataset = array();
$dataset['memory'] = array(
$this->_status['memory_usage']['used_memory'],
$this->_status['memory_usage']['free_memory'],
$this->_status['memory_usage']['wasted_memory'],
);
$dataset['keys'] = array(
$this->_status['opcache_statistics']['num_cached_keys'],
$this->_status['opcache_statistics']['max_cached_keys'] - $this->_status['opcache_statistics']['num_cached_keys'],
0
);
$dataset['hits'] = array(
$this->_status['opcache_statistics']['misses'],
$this->_status['opcache_statistics']['hits'],
0,
);
$dataset['restarts'] = array(
$this->_status['opcache_statistics']['oom_restarts'],
$this->_status['opcache_statistics']['manual_restarts'],
$this->_status['opcache_statistics']['hash_restarts'],
);
if (THOUSAND_SEPARATOR === true) {
$dataset['TSEP'] = 1;
} else {
$dataset['TSEP'] = 0;
}
return json_encode($dataset);
}
public function getHumanUsedMemory()
{
return $this->_size_for_humans($this->getUsedMemory());
}
public function getHumanFreeMemory()
{
return $this->_size_for_humans($this->getFreeMemory());
}
public function getHumanWastedMemory()
{
return $this->_size_for_humans($this->getWastedMemory());
}
public function getUsedMemory()
{
return $this->_status['memory_usage']['used_memory'];
}
public function getFreeMemory()
{
return $this->_status['memory_usage']['free_memory'];
}
public function getWastedMemory()
{
return $this->_status['memory_usage']['wasted_memory'];
}
public function getWastedMemoryPercentage()
{
return number_format($this->_status['memory_usage']['current_wasted_percentage'], 2);
}
public function getD3Scripts()
{
return $this->_d3Scripts;
}
private function _processPartition($value, $name = null)
{
if (array_key_exists('size', $value)) {
return $value;
}
$array = array('name' => $name,'children' => array());
foreach ($value as $k => $v) {
$array['children'][] = $this->_processPartition($v, $k);
}
return $array;
}
private function _format_value($value)
{
if (THOUSAND_SEPARATOR === true) {
return number_format($value);
} else {
return $value;
}
}
private function _size_for_humans($bytes)
{
if ($bytes > 1048576) {
return sprintf('%.2f&nbsp;MB', $bytes / 1048576);
} else {
if ($bytes > 1024) {
return sprintf('%.2f&nbsp;kB', $bytes / 1024);
} else {
return sprintf('%d&nbsp;bytes', $bytes);
}
}
}
// Borrowed from Laravel
private function _arrayPset(&$array, $key, $value)
{
if (is_null($key)) return $array = $value;
$keys = explode(DIRECTORY_SEPARATOR, ltrim($key, DIRECTORY_SEPARATOR));
while (count($keys) > 1) {
$key = array_shift($keys);
if ( ! isset($array[$key]) || ! is_array($array[$key])) {
$array[$key] = array();
}
$array =& $array[$key];
}
$array[array_shift($keys)] = $value;
return $array;
}
}
$dataModel = new OpCacheDataModel();
?>
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<style>
body {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
margin: 0;
padding: 0;
}
#container {
width: 1024px;
margin: auto;
position: relative;
}
h1 {
padding: 10px 0;
}
table {
border-collapse: collapse;
}
tbody tr:nth-child(even) {
background-color: #eee;
}
p.capitalize {
text-transform: capitalize;
}
.tabs {
position: relative;
float: left;
width: 60%;
}
.tab {
float: left;
}
.tab label {
background: #eee;
padding: 10px 12px;
border: 1px solid #ccc;
margin-left: -1px;
position: relative;
left: 1px;
}
.tab [type=radio] {
display: none;
}
.tab th, .tab td {
padding: 8px 12px;
}
.content {
position: absolute;
top: 28px;
left: 0;
background: white;
border: 1px solid #ccc;
height: 450px;
width: 100%;
overflow: auto;
}
.content table {
width: 100%;
}
.content th, .tab:nth-child(3) td {
text-align: left;
}
.content td {
text-align: right;
}
.clickable {
cursor: pointer;
}
[type=radio]:checked ~ label {
background: white;
border-bottom: 1px solid white;
z-index: 2;
}
[type=radio]:checked ~ label ~ .content {
z-index: 1;
}
#graph {
float: right;
width: 40%;
position: relative;
}
#graph > form {
position: absolute;
right: 60px;
top: -20px;
}
#graph > svg {
position: absolute;
top: 0;
right: 0;
}
#stats {
position: absolute;
right: 125px;
top: 145px;
}
#stats th, #stats td {
padding: 6px 10px;
font-size: 0.8em;
}
#partition {
position: absolute;
width: 100%;
height: 100%;
z-index: 10;
top: 0;
left: 0;
background: #ddd;
display: none;
}
#close-partition {
display: none;
position: absolute;
z-index: 20;
right: 15px;
top: 15px;
background: #f9373d;
color: #fff;
padding: 12px 15px;
}
#close-partition:hover {
background: #D32F33;
cursor: pointer;
}
#partition rect {
stroke: #fff;
fill: #aaa;
fill-opacity: 1;
}
#partition rect.parent {
cursor: pointer;
fill: steelblue;
}
#partition text {
pointer-events: none;
}
label {
cursor: pointer;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var hidden = {};
function toggleVisible(head, row) {
if (!hidden[row]) {
d3.selectAll(row).transition().style('display', 'none');
hidden[row] = true;
d3.select(head).transition().style('color', '#ccc');
} else {
d3.selectAll(row).transition().style('display');
hidden[row] = false;
d3.select(head).transition().style('color', '#000');
}
}
</script>
<title><?php echo $dataModel->getPageTitle(); ?></title>
</head>
<body>
<div id="container">
<h1><?php echo $dataModel->getPageTitle(); ?></h1>
<div class="tabs">
<div class="tab">
<input type="radio" id="tab-status" name="tab-group-1" checked>
<label for="tab-status">Status</label>
<div class="content">
<table>
<?php echo $dataModel->getStatusDataRows(); ?>
</table>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-config" name="tab-group-1">
<label for="tab-config">Configuration</label>
<div class="content">
<table>
<?php echo $dataModel->getConfigDataRows(); ?>
</table>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-scripts" name="tab-group-1">
<label for="tab-scripts">Scripts (<?php echo $dataModel->getScriptStatusCount(); ?>)</label>
<div class="content">
<table style="font-size:0.8em;">
<tr>
<th width="10%">Hits</th>
<th width="20%">Memory</th>
<th width="70%">Path</th>
</tr>
<?php echo $dataModel->getScriptStatusRows(); ?>
</table>
</div>
</div>
<div class="tab">
<input type="radio" id="tab-visualise" name="tab-group-1">
<label for="tab-visualise">Visualise Partition</label>
<div class="content"></div>
</div>
</div>
<div id="graph">
<form>
<label><input type="radio" name="dataset" value="memory" checked> Memory</label>
<label><input type="radio" name="dataset" value="keys"> Keys</label>
<label><input type="radio" name="dataset" value="hits"> Hits</label>
<label><input type="radio" name="dataset" value="restarts"> Restarts</label>
</form>
<div id="stats"></div>
</div>
</div>
<div id="close-partition">&#10006; Close Visualisation</div>
<div id="partition"></div>
<script>
var dataset = <?php echo $dataModel->getGraphDataSetJson(); ?>;
var width = 400,
height = 400,
radius = Math.min(width, height) / 2,
colours = ['#B41F1F', '#1FB437', '#ff7f0e'];
d3.scale.customColours = function() {
return d3.scale.ordinal().range(colours);
};
var colour = d3.scale.customColours();
var pie = d3.layout.pie().sort(null);
var arc = d3.svg.arc().innerRadius(radius - 20).outerRadius(radius - 50);
var svg = d3.select("#graph").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path")
.data(pie(dataset.memory))
.enter().append("path")
.attr("fill", function(d, i) { return colour(i); })
.attr("d", arc)
.each(function(d) { this._current = d; }); // store the initial values
d3.selectAll("input").on("change", change);
set_text("memory");
function set_text(t) {
if (t === "memory") {
d3.select("#stats").html(
"<table><tr><th style='background:#B41F1F;'>Used</th><td><?php echo $dataModel->getHumanUsedMemory()?></td></tr>"+
"<tr><th style='background:#1FB437;'>Free</th><td><?php echo $dataModel->getHumanFreeMemory()?></td></tr>"+
"<tr><th style='background:#ff7f0e;' rowspan=\"2\">Wasted</th><td><?php echo $dataModel->getHumanWastedMemory()?></td></tr>"+
"<tr><td><?php echo $dataModel->getWastedMemoryPercentage()?>%</td></tr></table>"
);
} else if (t === "keys") {
d3.select("#stats").html(
"<table><tr><th style='background:#B41F1F;'>Cached keys</th><td>"+format_value(dataset[t][0])+"</td></tr>"+
"<tr><th style='background:#1FB437;'>Free Keys</th><td>"+format_value(dataset[t][1])+"</td></tr></table>"
);
} else if (t === "hits") {
d3.select("#stats").html(
"<table><tr><th style='background:#B41F1F;'>Misses</th><td>"+format_value(dataset[t][0])+"</td></tr>"+
"<tr><th style='background:#1FB437;'>Cache Hits</th><td>"+format_value(dataset[t][1])+"</td></tr></table>"
);
} else if (t === "restarts") {
d3.select("#stats").html(
"<table><tr><th style='background:#B41F1F;'>Memory</th><td>"+dataset[t][0]+"</td></tr>"+
"<tr><th style='background:#1FB437;'>Manual</th><td>"+dataset[t][1]+"</td></tr>"+
"<tr><th style='background:#ff7f0e;'>Keys</th><td>"+dataset[t][2]+"</td></tr></table>"
);
}
}
function change() {
// Filter out any zero values to see if there is anything left
var remove_zero_values = dataset[this.value].filter(function(value) {
return value > 0;
});
// Skip if the value is undefined for some reason
if (typeof dataset[this.value] !== 'undefined' && remove_zero_values.length > 0) {
$('#graph').find('> svg').show();
path = path.data(pie(dataset[this.value])); // update the data
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
// Hide the graph if we can't draw it correctly, not ideal but this works
} else {
$('#graph').find('> svg').hide();
}
set_text(this.value);
}
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
function size_for_humans(bytes) {
if (bytes > 1048576) {
return (bytes/1048576).toFixed(2) + ' MB';
} else if (bytes > 1024) {
return (bytes/1024).toFixed(2) + ' KB';
} else return bytes + ' bytes';
}
function format_value(value) {
if (dataset["TSEP"] == 1) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return value;
}
}
var w = window.innerWidth,
h = window.innerHeight,
x = d3.scale.linear().range([0, w]),
y = d3.scale.linear().range([0, h]);
var vis = d3.select("#partition")
.style("width", w + "px")
.style("height", h + "px")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
var partition = d3.layout.partition()
.value(function(d) { return d.size; });
root = JSON.parse('<?php echo json_encode($dataModel->getD3Scripts()); ?>');
var g = vis.selectAll("g")
.data(partition.nodes(root))
.enter().append("svg:g")
.attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; })
.on("click", click);
var kx = w / root.dx,
ky = h / 1;
g.append("svg:rect")
.attr("width", root.dy * kx)
.attr("height", function(d) { return d.dx * ky; })
.attr("class", function(d) { return d.children ? "parent" : "child"; });
g.append("svg:text")
.attr("transform", transform)
.attr("dy", ".35em")
.style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; })
.text(function(d) { return d.name; })
d3.select(window)
.on("click", function() { click(root); })
function click(d) {
if (!d.children) return;
kx = (d.y ? w - 40 : w) / (1 - d.y);
ky = h / d.dx;
x.domain([d.y, 1]).range([d.y ? 40 : 0, w]);
y.domain([d.x, d.x + d.dx]);
var t = g.transition()
.duration(d3.event.altKey ? 7500 : 750)
.attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; });
t.select("rect")
.attr("width", d.dy * kx)
.attr("height", function(d) { return d.dx * ky; });
t.select("text")
.attr("transform", transform)
.style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; });
d3.event.stopPropagation();
}
function transform(d) {
return "translate(8," + d.dx * ky / 2 + ")";
}
$(document).ready(function() {
function handleVisualisationToggle(close) {
$('#partition, #close-partition').fadeToggle();
// Is the visualisation being closed? If so show the status tab again
if (close) {
$('#tab-visualise').removeAttr('checked');
$('#tab-status').trigger('click');
}
}
$('label[for="tab-visualise"], #close-partition').on('click', function() {
handleVisualisationToggle(($(this).attr('id') === 'close-partition'));
});
$(document).keyup(function(e) {
if (e.keyCode == 27) handleVisualisationToggle(true);
});
});
</script>
</body>
</html>