mirror of
https://github.com/cytopia/devilbox.git
synced 2025-06-01 15:10:58 +00:00
Separate devilbox config and user-defined config
This commit is contained in:
parent
9f756c3906
commit
eb5c0ccdfc
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,6 +17,7 @@
|
|||||||
log/
|
log/
|
||||||
run/
|
run/
|
||||||
|
|
||||||
|
cfg/mysql-5.5/*.cnf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
7
base/README.md
Normal file
7
base/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Devilbox base configuration
|
||||||
|
|
||||||
|
Those folders include the devilbox base configuration.
|
||||||
|
|
||||||
|
Do not edit anything here!
|
||||||
|
|
||||||
|
You can use the `cfg/` directory in the root folder to customize your configuration.
|
@ -12,7 +12,7 @@
|
|||||||
html, body {
|
html, body {
|
||||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
line-height: 1.42857143;
|
line-height: 1.42857143;
|
||||||
color: #333;
|
color: #333;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
@ -31,7 +31,10 @@
|
|||||||
<li><a href="/">Home</a></li>
|
<li><a href="/">Home</a></li>
|
||||||
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
||||||
<li class="active"><a href="#">Databases</a></li>
|
<li class="active"><a href="#">Databases</a></li>
|
||||||
<li><a href="/php.php">PHP</a></li>
|
<li> | </li>
|
||||||
|
<li><a href="/phpinfo.php">PHP info</a></li>
|
||||||
|
<li><a href="/opcache.php">PHP opcache</a></li>
|
||||||
|
<li><a href="/mysqlinfo.php">MySQL info</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><!--/.nav-collapse -->
|
</div><!--/.nav-collapse -->
|
||||||
</div>
|
</div>
|
@ -31,7 +31,10 @@
|
|||||||
<li class="active"><a href="#">Home</a></li>
|
<li class="active"><a href="#">Home</a></li>
|
||||||
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
||||||
<li><a href="/databases.php">Databases</a></li>
|
<li><a href="/databases.php">Databases</a></li>
|
||||||
<li><a href="/php.php">PHP</a></li>
|
<li> | </li>
|
||||||
|
<li><a href="/phpinfo.php">PHP info</a></li>
|
||||||
|
<li><a href="/opcache.php">PHP opcache</a></li>
|
||||||
|
<li><a href="/mysqlinfo.php">MySQL info</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><!--/.nav-collapse -->
|
</div><!--/.nav-collapse -->
|
||||||
</div>
|
</div>
|
||||||
@ -58,15 +61,15 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Webserver</th>
|
<th>Webserver</th>
|
||||||
<td><?php echo getHttpVersion();?> (IP: <?php echo $HTTPD_HOST_ADDR;?>)</td>
|
<td><?php echo getHttpVersion();?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>PHP</th>
|
<th>PHP</th>
|
||||||
<td><?php echo getPHPVersion(); ?> (IP: <?php echo $PHP_HOST_ADDR;?>)</td>
|
<td><?php echo getPHPVersion(); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>MySQL Server</th>
|
<th>MySQL Server</th>
|
||||||
<td><?php echo getMySQLVersion();?> (IP: <?php echo $MYSQL_HOST_ADDR;?>)</td>
|
<td><?php echo getMySQLVersion();?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -104,29 +107,46 @@
|
|||||||
<th colspan="2"><h3>[docker] HTTPD</h3></th>
|
<th colspan="2"><h3>[docker] HTTPD</h3></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">--</td>
|
<th>IP Adress</th>
|
||||||
|
<td><?php echo $HTTPD_HOST_ADDR;?></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
<!-- ############################################################ -->
|
<!-- ############################################################ -->
|
||||||
<!-- PHP Docker -->
|
<!-- PHP Docker -->
|
||||||
<!-- ############################################################ -->
|
<!-- ############################################################ -->
|
||||||
|
<?php
|
||||||
|
$error_loc;
|
||||||
|
$error_127;
|
||||||
|
$error_rem;
|
||||||
|
|
||||||
|
my_mysql_connection_test($error_loc, 'localhost');
|
||||||
|
my_mysql_connection_test($error_127, '127.0.0.1');
|
||||||
|
my_mysql_connection_test($error_rem);
|
||||||
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="2"><h3>[docker] PHP</h3></th>
|
<th colspan="2"><h3>[docker] PHP</h3></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>IP Adress</th>
|
||||||
|
<td><?php echo $PHP_HOST_ADDR;?></td>
|
||||||
|
</tr> <tr>
|
||||||
<th>MySQL Remote Port forwarded to PHP Docker?</th>
|
<th>MySQL Remote Port forwarded to PHP Docker?</th>
|
||||||
<td><?php echo ($ENV['FORWARD_MYSQL_PORT_TO_LOCALHOST']) ? 'To: 127.0.0.1:'.$ENV['MYSQL_LOCAL_PORT'] : 'No'; ?></td>
|
<td><?php echo ($ENV['FORWARD_MYSQL_PORT_TO_LOCALHOST']) ? 'To: 127.0.0.1:'.$ENV['MYSQL_LOCAL_PORT'] : 'No'; ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>MySQL Remote Socket mounted on PHP Docker?</th>
|
<th>MySQL Remote Socket mounted on PHP Docker?</th>
|
||||||
<td>
|
<td class="<?php echo file_exists($ENV['MYSQL_SOCKET_PATH']) && getMySQLConfigByKey('socket') == $ENV['MYSQL_SOCKET_PATH']? 'success' : 'danger'; ?>">
|
||||||
<?php
|
<?php
|
||||||
if ($ENV['MOUNT_MYSQL_SOCKET_TO_LOCALDISK']) {
|
if ($ENV['MOUNT_MYSQL_SOCKET_TO_LOCALDISK']) {
|
||||||
if (file_exists($ENV['MYSQL_SOCKET_PATH'])) {
|
if (file_exists($ENV['MYSQL_SOCKET_PATH'])) {
|
||||||
echo 'To: '.$ENV['MYSQL_SOCKET_PATH'];
|
if (getMySQLConfigByKey('socket') == $ENV['MYSQL_SOCKET_PATH']) {
|
||||||
|
echo 'OK: '.$ENV['MYSQL_SOCKET_PATH'];
|
||||||
} else {
|
} else {
|
||||||
echo 'To: '.$ENV['MYSQL_SOCKET_PATH']. ' - [ERROR] no such file';
|
echo 'ERR: Mounted from mysql:'.$ENV['MYSQL_SOCKET_PATH']. ', but socket is in mysql:'.getMySQLConfigByKey('socket');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo 'ERR: '.$ENV['MYSQL_SOCKET_PATH']. ' does not exist inside docker';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
echo 'No';
|
echo 'No';
|
||||||
@ -136,15 +156,15 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>PHP-MySQL connection test: localhost</th>
|
<th>PHP-MySQL connection test: localhost</th>
|
||||||
<td><?php echo testMySQLLocalhost(); ?></td>
|
<td class="<?php echo !$error_loc ? 'success' : 'danger';?>"><?php echo !$error_loc ? 'OK' : $error_loc;?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>PHP-MySQL connection test: 127.0.0.1</th>
|
<th>PHP-MySQL connection test: 127.0.0.1</th>
|
||||||
<td><?php echo testMySQLLocalIp(); ?></td>
|
<td class="<?php echo !$error_127 ? 'success' : 'danger';?>"><?php echo !$error_127 ? 'OK' : $error_127;?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>PHP-MySQL connection test: <?php echo $MYSQL_HOST_ADDR;?></th>
|
<th>PHP-MySQL connection test: <?php echo $MYSQL_HOST_ADDR;?></th>
|
||||||
<td><?php echo testMySQLRemotelIp(); ?></td>
|
<td class="<?php echo !$error_rem ? 'success' : 'danger';?>"><?php echo !$error_rem ? 'OK' : $error_rem;?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>PHP custom run-time options</th>
|
<th>PHP custom run-time options</th>
|
||||||
@ -170,7 +190,7 @@ track_errors = <?php echo $ENV['PHP_TRACK_ERRORS'];?>
|
|||||||
</pre>
|
</pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr></tr>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ############################################################ -->
|
<!-- ############################################################ -->
|
||||||
@ -180,30 +200,22 @@ track_errors = <?php echo $ENV['PHP_TRACK_ERRORS'];?>
|
|||||||
<th colspan="2"><h3>[docker] MySQL</h3></th>
|
<th colspan="2"><h3>[docker] MySQL</h3></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>IP Adress</th>
|
||||||
|
<td><?php echo $MYSQL_HOST_ADDR;?></td>
|
||||||
|
</tr> <tr>
|
||||||
<th>MySQL root password</th>
|
<th>MySQL root password</th>
|
||||||
<td><?php echo $MYSQL_ROOT_PASS; ?></td>
|
<td><?php echo $MYSQL_ROOT_PASS; ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>MySQL socket</th>
|
<th>MySQL socket</th>
|
||||||
<td><?php echo getMySQLConfig('socket'); ?></td>
|
<td><?php echo getMySQLConfigByKey('socket'); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>MySQL custom run-time options</th>
|
<th>MySQL logging</th>
|
||||||
<td>
|
<td><?php echo getMySQLConfigByKey('general-log');?></td>
|
||||||
<pre>
|
|
||||||
general_log = <?php echo getMySQLConfig('general-log')."\n";?>
|
|
||||||
innodb_buffer_pool_size = <?php echo getMySQLConfig('innodb-buffer-pool-size')."\n";?>
|
|
||||||
join_buffer_size = <?php echo getMySQLConfig('join-buffer-size')."\n";?>
|
|
||||||
sort_buffer_size = <?php echo getMySQLConfig('sort-buffer-size')."\n";?>
|
|
||||||
read_rnd_buffer_size = <?php echo getMySQLConfig('read-rnd-buffer_size')."\n";?>
|
|
||||||
symbolic_links = <?php echo getMySQLConfig('symbolic-links')."\n";?>
|
|
||||||
sql_mode = <?php echo getMySQLConfig('sql-mode')."\n";?>
|
|
||||||
</pre>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
90
base/www/htdocs/mysqlinfo.php
Normal file
90
base/www/htdocs/mysqlinfo.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php require '../config.php'; ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<link rel="icon" href="favicon.ico">
|
||||||
|
<link href="/assets/css/custom.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>DevilBox</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<nav class="navbar navbar-inverse navbar-static-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<span class="navbar-brand" href="#">DevilBox</span>
|
||||||
|
</div>
|
||||||
|
<div id="navbar" class="collapse navbar-collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
||||||
|
<li><a href="/databases.php">Databases</a></li>
|
||||||
|
<li> | </li>
|
||||||
|
<li><a href="/phpinfo.php">PHP info</a></li>
|
||||||
|
<li><a href="/opcache.php">PHP opcache</a></li>
|
||||||
|
<li class="active"><a href="#">MySQL info</a></li>
|
||||||
|
</ul>
|
||||||
|
</div><!--/.nav-collapse -->
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<h1>MySQL Info</h1>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
|
||||||
|
<p>For reference see here:</p>
|
||||||
|
<ul>
|
||||||
|
<li><a target="_blank" href="https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html">https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html</a></li>
|
||||||
|
<li><a target="_blank" href="https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html">https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html</a></li>
|
||||||
|
<li><a target="_blank" href="https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html">https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Variable</th>
|
||||||
|
<th>Value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach (getMySQLConfig() as $key => $val): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $key;?></td>
|
||||||
|
<td><?php echo $val;?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- /.container -->
|
||||||
|
|
||||||
|
<?php require '../include/footer.php'; ?>
|
||||||
|
<script>
|
||||||
|
// self executing function here
|
||||||
|
(function() {
|
||||||
|
// your page initialization code here
|
||||||
|
// the DOM will be available here
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
802
base/www/htdocs/opcache.php
Normal file
802
base/www/htdocs/opcache.php
Normal file
@ -0,0 +1,802 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OPcache GUI
|
||||||
|
*
|
||||||
|
* A simple but effective single-file GUI for the OPcache PHP extension.
|
||||||
|
*
|
||||||
|
* @author Andrew Collington, andy@amnuts.com
|
||||||
|
* @version 2.2.3
|
||||||
|
* @link https://github.com/amnuts/opcache-gui
|
||||||
|
* @license MIT, http://acollington.mit-license.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
$options = [
|
||||||
|
'allow_filelist' => true, // show/hide the files tab
|
||||||
|
'allow_invalidate' => true, // give a link to invalidate files
|
||||||
|
'allow_reset' => true, // give option to reset the whole cache
|
||||||
|
'allow_realtime' => true, // give option to enable/disable real-time updates
|
||||||
|
'refresh_time' => 5, // how often the data will refresh, in seconds
|
||||||
|
'size_precision' => 2, // Digits after decimal point
|
||||||
|
'size_space' => false, // have '1MB' or '1 MB' when showing sizes
|
||||||
|
'charts' => true, // show gauge chart or just big numbers
|
||||||
|
'debounce_rate' => 250 // milliseconds after key press to send keyup event when filtering
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shouldn't need to alter anything else below here
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!extension_loaded('Zend OPcache')) {
|
||||||
|
die('The Zend OPcache extension does not appear to be installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
class OpCacheService
|
||||||
|
{
|
||||||
|
protected $data;
|
||||||
|
protected $options;
|
||||||
|
protected $defaults = [
|
||||||
|
'allow_filelist' => true,
|
||||||
|
'allow_invalidate' => true,
|
||||||
|
'allow_reset' => true,
|
||||||
|
'allow_realtime' => true,
|
||||||
|
'refresh_time' => 5,
|
||||||
|
'size_precision' => 2,
|
||||||
|
'size_space' => false,
|
||||||
|
'charts' => true,
|
||||||
|
'debounce_rate' => 250
|
||||||
|
];
|
||||||
|
|
||||||
|
private function __construct($options = [])
|
||||||
|
{
|
||||||
|
$this->options = array_merge($this->defaults, $options);
|
||||||
|
$this->data = $this->compileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function init($options = [])
|
||||||
|
{
|
||||||
|
$self = new self($options);
|
||||||
|
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
|
||||||
|
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
|
||||||
|
) {
|
||||||
|
if (isset($_GET['reset']) && $self->getOption('allow_reset')) {
|
||||||
|
echo '{ "success": "' . ($self->resetCache() ? 'yes' : 'no') . '" }';
|
||||||
|
} else if (isset($_GET['invalidate']) && $self->getOption('allow_invalidate')) {
|
||||||
|
echo '{ "success": "' . ($self->resetCache($_GET['invalidate']) ? 'yes' : 'no') . '" }';
|
||||||
|
} else {
|
||||||
|
echo json_encode($self->getData((empty($_GET['section']) ? null : $_GET['section'])));
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
} else if (isset($_GET['reset']) && $self->getOption('allow_reset')) {
|
||||||
|
$self->resetCache();
|
||||||
|
header('Location: ?');
|
||||||
|
exit;
|
||||||
|
} else if (isset($_GET['invalidate']) && $self->getOption('allow_invalidate')) {
|
||||||
|
$self->resetCache($_GET['invalidate']);
|
||||||
|
header('Location: ?');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOption($name = null)
|
||||||
|
{
|
||||||
|
if ($name === null) {
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
return (isset($this->options[$name])
|
||||||
|
? $this->options[$name]
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData($section = null, $property = null)
|
||||||
|
{
|
||||||
|
if ($section === null) {
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
$section = strtolower($section);
|
||||||
|
if (isset($this->data[$section])) {
|
||||||
|
if ($property === null || !isset($this->data[$section][$property])) {
|
||||||
|
return $this->data[$section];
|
||||||
|
}
|
||||||
|
return $this->data[$section][$property];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canInvalidate()
|
||||||
|
{
|
||||||
|
return ($this->getOption('allow_invalidate') && function_exists('opcache_invalidate'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetCache($file = null)
|
||||||
|
{
|
||||||
|
$success = false;
|
||||||
|
if ($file === null) {
|
||||||
|
$success = opcache_reset();
|
||||||
|
} else if (function_exists('opcache_invalidate')) {
|
||||||
|
$success = opcache_invalidate(urldecode($file), true);
|
||||||
|
}
|
||||||
|
if ($success) {
|
||||||
|
$this->compileState();
|
||||||
|
}
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function size($size)
|
||||||
|
{
|
||||||
|
$i = 0;
|
||||||
|
$val = array('b', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
||||||
|
while (($size / 1024) > 1) {
|
||||||
|
$size /= 1024;
|
||||||
|
++$i;
|
||||||
|
}
|
||||||
|
return sprintf('%.'.$this->getOption('size_precision').'f%s%s',
|
||||||
|
$size, ($this->getOption('size_space') ? ' ' : ''), $val[$i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function compileState()
|
||||||
|
{
|
||||||
|
$status = opcache_get_status();
|
||||||
|
$config = opcache_get_configuration();
|
||||||
|
|
||||||
|
$files = [];
|
||||||
|
if (!empty($status['scripts']) && $this->getOption('allow_filelist')) {
|
||||||
|
uasort($status['scripts'], function($a, $b) {
|
||||||
|
return $a['hits'] < $b['hits'];
|
||||||
|
});
|
||||||
|
foreach ($status['scripts'] as &$file) {
|
||||||
|
$file['full_path'] = str_replace('\\', '/', $file['full_path']);
|
||||||
|
$file['readable'] = [
|
||||||
|
'hits' => number_format($file['hits']),
|
||||||
|
'memory_consumption' => $this->size($file['memory_consumption'])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$files = array_values($status['scripts']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$overview = array_merge(
|
||||||
|
$status['memory_usage'], $status['opcache_statistics'], [
|
||||||
|
'used_memory_percentage' => round(100 * (
|
||||||
|
($status['memory_usage']['used_memory'] + $status['memory_usage']['wasted_memory'])
|
||||||
|
/ $config['directives']['opcache.memory_consumption'])),
|
||||||
|
'hit_rate_percentage' => round($status['opcache_statistics']['opcache_hit_rate']),
|
||||||
|
'wasted_percentage' => round($status['memory_usage']['current_wasted_percentage'], 2),
|
||||||
|
'readable' => [
|
||||||
|
'total_memory' => $this->size($config['directives']['opcache.memory_consumption']),
|
||||||
|
'used_memory' => $this->size($status['memory_usage']['used_memory']),
|
||||||
|
'free_memory' => $this->size($status['memory_usage']['free_memory']),
|
||||||
|
'wasted_memory' => $this->size($status['memory_usage']['wasted_memory']),
|
||||||
|
'num_cached_scripts' => number_format($status['opcache_statistics']['num_cached_scripts']),
|
||||||
|
'hits' => number_format($status['opcache_statistics']['hits']),
|
||||||
|
'misses' => number_format($status['opcache_statistics']['misses']),
|
||||||
|
'blacklist_miss' => number_format($status['opcache_statistics']['blacklist_misses']),
|
||||||
|
'num_cached_keys' => number_format($status['opcache_statistics']['num_cached_keys']),
|
||||||
|
'max_cached_keys' => number_format($status['opcache_statistics']['max_cached_keys']),
|
||||||
|
'start_time' => date('Y-m-d H:i:s', $status['opcache_statistics']['start_time']),
|
||||||
|
'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] == 0
|
||||||
|
? 'never'
|
||||||
|
: date('Y-m-d H:i:s', $status['opcache_statistics']['last_restart_time'])
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$directives = [];
|
||||||
|
ksort($config['directives']);
|
||||||
|
foreach ($config['directives'] as $k => $v) {
|
||||||
|
$directives[] = ['k' => $k, 'v' => $v];
|
||||||
|
}
|
||||||
|
|
||||||
|
$version = array_merge(
|
||||||
|
$config['version'],
|
||||||
|
[
|
||||||
|
'php' => phpversion(),
|
||||||
|
'server' => $_SERVER['SERVER_SOFTWARE'],
|
||||||
|
'host' => (function_exists('gethostname')
|
||||||
|
? gethostname()
|
||||||
|
: (php_uname('n')
|
||||||
|
?: (empty($_SERVER['SERVER_NAME'])
|
||||||
|
? $_SERVER['HOST_NAME']
|
||||||
|
: $_SERVER['SERVER_NAME']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'version' => $version,
|
||||||
|
'overview' => $overview,
|
||||||
|
'files' => $files,
|
||||||
|
'directives' => $directives,
|
||||||
|
'blacklist' => $config['blacklist'],
|
||||||
|
'functions' => get_extension_funcs('Zend OPcache')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$opcache = OpCacheService::init($options);
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<link rel="icon" href="favicon.ico">
|
||||||
|
<link href="/assets/css/custom.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>DevilBox</title>
|
||||||
|
|
||||||
|
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<title>OPcache statistics on <?php echo $opcache->getData('version', 'host'); ?></title>
|
||||||
|
<script src="//cdn.jsdelivr.net/react/15.0.1/react.min.js"></script>
|
||||||
|
<script src="//cdn.jsdelivr.net/react/15.0.1/react-dom.min.js"></script>
|
||||||
|
<script src="//code.jquery.com/jquery-2.2.3.min.js"></script>
|
||||||
|
<style type="text/css">
|
||||||
|
body { font-family:sans-serif; font-size:90%; padding: 0; margin: 0 }
|
||||||
|
nav { padding-top: 20px; }
|
||||||
|
nav > ul { list-style-type: none; padding-left: 8px; margin: 0; border-bottom: 1px solid #ccc; }
|
||||||
|
nav > ul > li { display: inline-block; padding: 0; margin: 0 0 -1px 0; }
|
||||||
|
nav > ul > li > a { display: block; margin: 0 10px; padding: 15px 30px; border: 1px solid transparent; border-bottom-color: #ccc; text-decoration: none; }
|
||||||
|
nav > ul > li > a:hover { background-color: #f4f4f4; text-decoration: underline; }
|
||||||
|
nav > ul > li > a.active:hover { background-color: initial; }
|
||||||
|
nav > ul > li > a[data-for].active { border: 1px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
|
||||||
|
table { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; table-layout: fixed; }
|
||||||
|
table caption { text-align: left; font-size: 1.5em; }
|
||||||
|
table tr { background-color: #99D0DF; border-color: #fff; }
|
||||||
|
table th { text-align: left; padding: 6px; background-color: #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
|
||||||
|
table td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; }
|
||||||
|
table tr:nth-child(odd) { background-color: #EFFEFF; }
|
||||||
|
table tr:nth-child(even) { background-color: #E0ECEF; }
|
||||||
|
#filelist table tr { background-color: #EFFEFF; }
|
||||||
|
#filelist table tr.alternate { background-color: #E0ECEF; }
|
||||||
|
td.pathname { width: 70%; }
|
||||||
|
footer { border-top: 1px solid #ccc; padding: 1em 2em; }
|
||||||
|
footer a { padding: 2em; text-decoration: none; opacity: 0.7; }
|
||||||
|
footer a:hover { opacity: 1; }
|
||||||
|
canvas { display: block; width: 250px; height: 250px; margin: 0 auto; }
|
||||||
|
#tabs { padding: 2em; }
|
||||||
|
#tabs > div { display: none; }
|
||||||
|
#tabs > div#overview { display:block; }
|
||||||
|
#resetCache, #toggleRealtime, footer > a { background-position: 5px 50%; background-repeat: no-repeat; background-color: transparent; }
|
||||||
|
footer > a { background-position: 0 50%; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII='); font-size: 80%; }
|
||||||
|
#resetCache { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg=='); }
|
||||||
|
#toggleRealtime { position: relative; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII='); }
|
||||||
|
#counts { width: 270px; float: right; }
|
||||||
|
#counts > div > div { background-color: #ededed; margin-bottom: 10px; }
|
||||||
|
#counts > div > div > h3 { background-color: #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
|
||||||
|
#counts > div > div > p { margin: 0; text-align: center; }
|
||||||
|
#counts > div > div > p span.large + span { font-size: 20pt; margin: 0; color: #6ca6ef; }
|
||||||
|
#counts > div > div > p span.large { color: #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
|
||||||
|
#info { margin-right: 280px; }
|
||||||
|
#frmFilter { width: 520px; }
|
||||||
|
#moreinfo { padding: 10px; }
|
||||||
|
#moreinfo > p { text-align: left !important; line-height: 180%; }
|
||||||
|
.metainfo { font-size: 80%; }
|
||||||
|
.hide { display: none; }
|
||||||
|
#toggleRealtime.pulse::before {
|
||||||
|
content: ""; position: absolute;
|
||||||
|
top: 13px; left: 3px; width: 18px; height: 18px;
|
||||||
|
z-index: 10; opacity: 0; background-color: transparent;
|
||||||
|
border: 2px solid rgb(255, 116, 0); border-radius: 100%;
|
||||||
|
-webkit-animation: pulse 1s linear 2;
|
||||||
|
-moz-animation: pulse 1s linear 2;
|
||||||
|
animation: pulse 1s linear 2;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 750px) {
|
||||||
|
#info { margin-right:auto; clear:both; }
|
||||||
|
nav > ul { border-bottom: 0; }
|
||||||
|
nav > ul > li { display: block; margin: 0; }
|
||||||
|
nav > ul > li > a { display: block; margin: 0 10px; padding: 10px 0 10px 30px; border: 0; }
|
||||||
|
nav > ul > li > a[data-for].active { border-bottom-color: #ccc; }
|
||||||
|
#counts { position:relative; display:block; width:100%; }
|
||||||
|
#toggleRealtime.pulse::before { top: 8px; }
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 550px) {
|
||||||
|
#frmFilter { width: 100%; }
|
||||||
|
}
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {transform: scale(1); opacity: 0;}
|
||||||
|
50% {transform: scale(1.3); opacity: 0.7;}
|
||||||
|
100% {transform: scale(1.6); opacity: 1;}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes pulse {
|
||||||
|
0% {-webkit-transform: scale(1); opacity: 0;}
|
||||||
|
50% {-webkit-transform: scale(1.3); opacity: 0.7;}
|
||||||
|
100% {-webkit-transform: scale(1.6); opacity: 0;}
|
||||||
|
}
|
||||||
|
@-moz-keyframes pulse {
|
||||||
|
0% {-moz-transform: scale(1); opacity: 0;}
|
||||||
|
50% {-moz-transform: scale(1.3); opacity: 0.7;}
|
||||||
|
100% {-moz-transform: scale(1.6); opacity: 0;}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-inverse navbar-static-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<span class="navbar-brand" href="#">DevilBox</span>
|
||||||
|
</div>
|
||||||
|
<div id="navbar" class="collapse navbar-collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
<li><a href="/vhosts">Virtual Hosts</a></li>
|
||||||
|
<li><a href="/databases.php">Databases</a></li>
|
||||||
|
<li> | </li>
|
||||||
|
<li><a href="/phpinfo.php">PHP info</a></li>
|
||||||
|
<li class="active"><a href="#">PHP opcache</a></li>
|
||||||
|
<li><a href="/mysqlinfo.php">MySQL info</a></li>
|
||||||
|
</ul>
|
||||||
|
</div><!--/.nav-collapse -->
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li><a data-for="overview" href="#overview" class="active">Overview</a></li>
|
||||||
|
<?php if ($opcache->getOption('allow_filelist')): ?>
|
||||||
|
<li><a data-for="files" href="#files">File usage</a></li>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($opcache->getOption('allow_reset')): ?>
|
||||||
|
<li><a href="?reset=1" id="resetCache" onclick="return confirm('Are you sure you want to reset the cache?');">Reset cache</a></li>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($opcache->getOption('allow_realtime')): ?>
|
||||||
|
<li><a href="#" id="toggleRealtime">Enable real-time update</a></li>
|
||||||
|
<?php endif; ?>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="tabs">
|
||||||
|
<div id="overview">
|
||||||
|
<div class="container">
|
||||||
|
<div id="counts"></div>
|
||||||
|
<div id="info">
|
||||||
|
<div id="generalInfo"></div>
|
||||||
|
<div id="directives"></div>
|
||||||
|
<div id="functions">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Available functions</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($opcache->getData('functions') as $func): ?>
|
||||||
|
<tr><td><a href="http://php.net/<?php echo $func; ?>" title="View manual page" target="_blank"><?php echo $func; ?></a></td></tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<br style="clear:both;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="files">
|
||||||
|
<?php if ($opcache->getOption('allow_filelist')): ?>
|
||||||
|
<p><label>Start typing to filter on script path<br/><input type="text" name="filter" id="frmFilter" /><label></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="container" id="filelist"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<a href="https://github.com/amnuts/opcache-gui" target="_blank">https://github.com/amnuts/opcache-gui</a>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var realtime = false;
|
||||||
|
var opstate = <?php echo json_encode($opcache->getData()); ?>;
|
||||||
|
var canInvalidate = <?php echo json_encode($opcache->canInvalidate()); ?>;
|
||||||
|
var useCharts = <?php echo json_encode($opcache->getOption('charts')); ?>;
|
||||||
|
var allowFiles = <?php echo json_encode($opcache->getOption('allow_filelist')); ?>;
|
||||||
|
var debounce = function(func, wait, immediate) {
|
||||||
|
var timeout;
|
||||||
|
wait = wait || 250;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
var later = function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) {
|
||||||
|
func.apply(context, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
function keyUp(event){
|
||||||
|
var compare = $('#frmFilter').val().toLowerCase();
|
||||||
|
$('#filelist').find('table tbody tr').each(function(index){
|
||||||
|
if ($(this).data('path').indexOf(compare) == -1) {
|
||||||
|
$(this).addClass('hide');
|
||||||
|
} else {
|
||||||
|
$(this).removeClass('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('#filelist table tbody').trigger('paint');
|
||||||
|
};
|
||||||
|
|
||||||
|
<?php if ($opcache->getOption('charts')): ?>
|
||||||
|
var Gauge = function(el, colour) {
|
||||||
|
this.canvas = $(el).get(0);
|
||||||
|
this.ctx = this.canvas.getContext('2d');
|
||||||
|
this.width = this.canvas.width;
|
||||||
|
this.height = this.canvas.height;
|
||||||
|
this.colour = colour || '#6ca6ef';
|
||||||
|
this.loop = null;
|
||||||
|
this.degrees = 0;
|
||||||
|
this.newdegs = 0;
|
||||||
|
this.text = '';
|
||||||
|
this.init = function() {
|
||||||
|
this.ctx.clearRect(0, 0, this.width, this.height);
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.strokeStyle = '#e2e2e2';
|
||||||
|
this.ctx.lineWidth = 30;
|
||||||
|
this.ctx.arc(this.width/2, this.height/2, 100, 0, Math.PI*2, false);
|
||||||
|
this.ctx.stroke();
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.strokeStyle = this.colour;
|
||||||
|
this.ctx.lineWidth = 30;
|
||||||
|
this.ctx.arc(this.width/2, this.height/2, 100, 0 - (90 * Math.PI / 180), (this.degrees * Math.PI / 180) - (90 * Math.PI / 180), false);
|
||||||
|
this.ctx.stroke();
|
||||||
|
this.ctx.fillStyle = this.colour;
|
||||||
|
this.ctx.font = '60px sans-serif';
|
||||||
|
this.text = Math.round((this.degrees/360)*100) + '%';
|
||||||
|
this.ctx.fillText(this.text, (this.width/2) - (this.ctx.measureText(this.text).width/2), (this.height/2) + 20);
|
||||||
|
};
|
||||||
|
this.draw = function() {
|
||||||
|
if (typeof this.loop != 'undefined') {
|
||||||
|
clearInterval(this.loop);
|
||||||
|
}
|
||||||
|
var self = this;
|
||||||
|
self.loop = setInterval(function(){ self.animate(); }, 1000/(this.newdegs - this.degrees));
|
||||||
|
};
|
||||||
|
this.animate = function() {
|
||||||
|
if (this.degrees == this.newdegs) {
|
||||||
|
clearInterval(this.loop);
|
||||||
|
}
|
||||||
|
if (this.degrees < this.newdegs) {
|
||||||
|
++this.degrees;
|
||||||
|
} else {
|
||||||
|
--this.degrees;
|
||||||
|
}
|
||||||
|
this.init();
|
||||||
|
};
|
||||||
|
this.setValue = function(val) {
|
||||||
|
this.newdegs = Math.round(3.6 * val);
|
||||||
|
this.draw();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
<?php if ($opcache->getOption('allow_realtime')): ?>
|
||||||
|
function updateStatus() {
|
||||||
|
$('#toggleRealtime').removeClass('pulse');
|
||||||
|
$.ajax({
|
||||||
|
url: "#",
|
||||||
|
dataType: "json",
|
||||||
|
cache: false,
|
||||||
|
success: function(data) {
|
||||||
|
$('#toggleRealtime').addClass('pulse');
|
||||||
|
opstate = data;
|
||||||
|
overviewCountsObj.setState({
|
||||||
|
data : opstate.overview
|
||||||
|
});
|
||||||
|
generalInfoObj.setState({
|
||||||
|
version : opstate.version,
|
||||||
|
start : opstate.overview.readable.start_time,
|
||||||
|
reset : opstate.overview.readable.last_restart_time
|
||||||
|
});
|
||||||
|
filesObj.setState({
|
||||||
|
data : opstate.files,
|
||||||
|
count_formatted : opstate.overview.readable.num_cached_scripts,
|
||||||
|
count : opstate.overview.num_cached_scripts
|
||||||
|
});
|
||||||
|
keyUp();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$('#toggleRealtime').click(function(){
|
||||||
|
if (realtime === false) {
|
||||||
|
realtime = setInterval(function(){updateStatus()}, <?php echo (int)$opcache->getOption('refresh_time') * 1000; ?>);
|
||||||
|
$(this).text('Disable real-time update');
|
||||||
|
} else {
|
||||||
|
clearInterval(realtime);
|
||||||
|
realtime = false;
|
||||||
|
$(this).text('Enable real-time update').removeClass('pulse');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
<?php endif; ?>
|
||||||
|
$('nav a[data-for]').click(function(){
|
||||||
|
$('#tabs > div').hide();
|
||||||
|
$('#' + $(this).data('for')).show();
|
||||||
|
$('nav a[data-for]').removeClass('active');
|
||||||
|
$(this).addClass('active');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(document).on('paint', '#filelist table tbody', function(event, params) {
|
||||||
|
var trs = $('#filelist').find('tbody tr');
|
||||||
|
trs.removeClass('alternate');
|
||||||
|
trs.filter(':not(.hide):odd').addClass('alternate');
|
||||||
|
filesObj.setState({showing: trs.filter(':not(.hide)').length});
|
||||||
|
});
|
||||||
|
$('#frmFilter').bind('keyup', debounce(keyUp, <?php echo $opcache->getOption('debounce_rate'); ?>));
|
||||||
|
});
|
||||||
|
|
||||||
|
var MemoryUsage = React.createClass({displayName: "MemoryUsage",
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
memoryUsageGauge : null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
componentDidMount: function() {
|
||||||
|
if (this.props.chart) {
|
||||||
|
this.state.memoryUsageGauge = new Gauge('#memoryUsageCanvas');
|
||||||
|
this.state.memoryUsageGauge.setValue(this.props.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDidUpdate: function() {
|
||||||
|
if (this.state.memoryUsageGauge != null) {
|
||||||
|
this.state.memoryUsageGauge.setValue(this.props.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
if (this.props.chart == true) {
|
||||||
|
return(React.createElement("canvas", {id: "memoryUsageCanvas", width: "250", height: "250", "data-value": this.props.value}));
|
||||||
|
}
|
||||||
|
return(React.createElement("p", null, React.createElement("span", {className: "large"}, this.props.value), React.createElement("span", null, "%")));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var HitRate = React.createClass({displayName: "HitRate",
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
hitRateGauge : null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
componentDidMount: function() {
|
||||||
|
if (this.props.chart) {
|
||||||
|
this.state.hitRateGauge = new Gauge('#hitRateCanvas');
|
||||||
|
this.state.hitRateGauge.setValue(this.props.value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDidUpdate: function() {
|
||||||
|
if (this.state.hitRateGauge != null) {
|
||||||
|
this.state.hitRateGauge.setValue(this.props.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
if (this.props.chart == true) {
|
||||||
|
return(React.createElement("canvas", {id: "hitRateCanvas", width: "250", height: "250", "data-value": this.props.value}));
|
||||||
|
}
|
||||||
|
return(React.createElement("p", null, React.createElement("span", {className: "large"}, this.props.value), React.createElement("span", null, "%")));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var OverviewCounts = React.createClass({displayName: "OverviewCounts",
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
data : opstate.overview,
|
||||||
|
chart : useCharts
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
React.createElement("div", null,
|
||||||
|
React.createElement("div", null,
|
||||||
|
React.createElement("h3", null, "memory usage"),
|
||||||
|
React.createElement("p", null, React.createElement(MemoryUsage, {chart: this.state.chart, value: this.state.data.used_memory_percentage}))
|
||||||
|
),
|
||||||
|
React.createElement("div", null,
|
||||||
|
React.createElement("h3", null, "hit rate"),
|
||||||
|
React.createElement("p", null, React.createElement(HitRate, {chart: this.state.chart, value: this.state.data.hit_rate_percentage}))
|
||||||
|
),
|
||||||
|
React.createElement("div", {id: "moreinfo"},
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "total memory:"), " ", this.state.data.readable.total_memory),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "used memory:"), " ", this.state.data.readable.used_memory),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "free memory:"), " ", this.state.data.readable.free_memory),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "wasted memory:"), " ", this.state.data.readable.wasted_memory, " (", this.state.data.wasted_percentage, "%)"),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "number of cached files:"), " ", this.state.data.readable.num_cached_scripts),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "number of hits:"), " ", this.state.data.readable.hits),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "number of misses:"), " ", this.state.data.readable.misses),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "blacklist misses:"), " ", this.state.data.readable.blacklist_miss),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "number of cached keys:"), " ", this.state.data.readable.num_cached_keys),
|
||||||
|
React.createElement("p", null, React.createElement("b", null, "max cached keys:"), " ", this.state.data.readable.max_cached_keys)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var GeneralInfo = React.createClass({displayName: "GeneralInfo",
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
version : opstate.version,
|
||||||
|
start : opstate.overview.readable.start_time,
|
||||||
|
reset : opstate.overview.readable.last_restart_time
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
React.createElement("table", null,
|
||||||
|
React.createElement("thead", null,
|
||||||
|
React.createElement("tr", null, React.createElement("th", {colSpan: "2"}, "General info"))
|
||||||
|
),
|
||||||
|
React.createElement("tbody", null,
|
||||||
|
React.createElement("tr", null, React.createElement("td", null, "Zend OPcache"), React.createElement("td", null, this.state.version.version)),
|
||||||
|
React.createElement("tr", null, React.createElement("td", null, "PHP"), React.createElement("td", null, this.state.version.php)),
|
||||||
|
React.createElement("tr", null, React.createElement("td", null, "Host"), React.createElement("td", null, this.state.version.host)),
|
||||||
|
React.createElement("tr", null, React.createElement("td", null, "Server Software"), React.createElement("td", null, this.state.version.server)),
|
||||||
|
React.createElement("tr", null, React.createElement("td", null, "Start time"), React.createElement("td", null, this.state.start)),
|
||||||
|
React.createElement("tr", null, React.createElement("td", null, "Last reset"), React.createElement("td", null, this.state.reset))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Directives = React.createClass({displayName: "Directives",
|
||||||
|
getInitialState: function() {
|
||||||
|
return { data : opstate.directives };
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var directiveNodes = this.state.data.map(function(directive) {
|
||||||
|
var map = { 'opcache.':'', '_':' ' };
|
||||||
|
var dShow = directive.k.replace(/opcache\.|_/gi, function(matched){
|
||||||
|
return map[matched];
|
||||||
|
});
|
||||||
|
var vShow;
|
||||||
|
if (directive.v === true || directive.v === false) {
|
||||||
|
vShow = React.createElement('i', {}, directive.v.toString());
|
||||||
|
} else if (directive.v === '') {
|
||||||
|
vShow = React.createElement('i', {}, 'no value');
|
||||||
|
} else {
|
||||||
|
vShow = directive.v;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
React.createElement("tr", {key: directive.k},
|
||||||
|
React.createElement("td", {title: 'View ' + directive.k + ' manual entry'}, React.createElement("a", {href: 'http://php.net/manual/en/opcache.configuration.php#ini.'
|
||||||
|
+ (directive.k).replace(/_/g,'-'), target: "_blank"}, dShow)),
|
||||||
|
React.createElement("td", null, vShow)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
React.createElement("table", null,
|
||||||
|
React.createElement("thead", null,
|
||||||
|
React.createElement("tr", null, React.createElement("th", {colSpan: "2"}, "Directives"))
|
||||||
|
),
|
||||||
|
React.createElement("tbody", null, directiveNodes)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Files = React.createClass({displayName: "Files",
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
data : opstate.files,
|
||||||
|
showing: null,
|
||||||
|
allowFiles: allowFiles
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleInvalidate: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (realtime) {
|
||||||
|
$.get('#', { invalidate: e.currentTarget.getAttribute('data-file') }, function(data) {
|
||||||
|
console.log('success: ' + data.success);
|
||||||
|
}, 'json');
|
||||||
|
} else {
|
||||||
|
window.location.href = e.currentTarget.href;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
if (this.state.allowFiles) {
|
||||||
|
var fileNodes = this.state.data.map(function(file, i) {
|
||||||
|
var invalidate, invalidated;
|
||||||
|
if (file.timestamp == 0) {
|
||||||
|
invalidated = React.createElement("span", null, React.createElement("i", {className: "invalid metainfo"}, " - has been invalidated"));
|
||||||
|
}
|
||||||
|
if (canInvalidate) {
|
||||||
|
invalidate = React.createElement("span", null, ", ", React.createElement("a", {className: "metainfo", href: '?invalidate='
|
||||||
|
+ file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate}, "force file invalidation"));
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
React.createElement("tr", {key: file.full_path, "data-path": file.full_path.toLowerCase(), className: i%2?'alternate':''},
|
||||||
|
React.createElement("td", null,
|
||||||
|
React.createElement("div", null,
|
||||||
|
React.createElement("span", {className: "pathname"}, file.full_path), React.createElement("br", null),
|
||||||
|
React.createElement(FilesMeta, {data: [file.readable.hits, file.readable.memory_consumption, file.last_used]}),
|
||||||
|
invalidate,
|
||||||
|
invalidated
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}.bind(this));
|
||||||
|
return (
|
||||||
|
React.createElement("div", null,
|
||||||
|
React.createElement(FilesListed, {showing: this.state.showing}),
|
||||||
|
React.createElement("table", null,
|
||||||
|
React.createElement("thead", null,
|
||||||
|
React.createElement("tr", null,
|
||||||
|
React.createElement("th", null, "Script")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
React.createElement("tbody", null, fileNodes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return React.createElement("span", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var FilesMeta = React.createClass({displayName: "FilesMeta",
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
React.createElement("span", {className: "metainfo"},
|
||||||
|
React.createElement("b", null, "hits: "), React.createElement("span", null, this.props.data[0], ", "),
|
||||||
|
React.createElement("b", null, "memory: "), React.createElement("span", null, this.props.data[1], ", "),
|
||||||
|
React.createElement("b", null, "last used: "), React.createElement("span", null, this.props.data[2])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var FilesListed = React.createClass({displayName: "FilesListed",
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
formatted : opstate.overview.readable.num_cached_scripts,
|
||||||
|
total : opstate.overview.num_cached_scripts
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var display = this.state.formatted + ' file' + (this.state.total == 1 ? '' : 's') + ' cached';
|
||||||
|
if (this.props.showing !== null && this.props.showing != this.state.total) {
|
||||||
|
display += ', ' + this.props.showing + ' showing due to filter';
|
||||||
|
}
|
||||||
|
return (React.createElement("h3", null, display));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var overviewCountsObj = ReactDOM.render(React.createElement(OverviewCounts, null), document.getElementById('counts'));
|
||||||
|
var generalInfoObj = ReactDOM.render(React.createElement(GeneralInfo, null), document.getElementById('generalInfo'));
|
||||||
|
var filesObj = ReactDOM.render(React.createElement(Files, null), document.getElementById('filelist'));
|
||||||
|
ReactDOM.render(React.createElement(Directives, null), document.getElementById('directives'));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -31,7 +31,10 @@
|
|||||||
<li><a href="/">Home</a></li>
|
<li><a href="/">Home</a></li>
|
||||||
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
<li><a href="/vhosts.php">Virtual Hosts</a></li>
|
||||||
<li><a href="/databases.php">Databases</a></li>
|
<li><a href="/databases.php">Databases</a></li>
|
||||||
<li class="active"><a href="#">PHP</a></li>
|
<li> | </li>
|
||||||
|
<li class="active"><a href="#">PHP info</a></li>
|
||||||
|
<li><a href="/opcache.php">PHP opcache</a></li>
|
||||||
|
<li><a href="/mysqlinfo.php">MySQL info</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><!--/.nav-collapse -->
|
</div><!--/.nav-collapse -->
|
||||||
</div>
|
</div>
|
@ -31,7 +31,10 @@
|
|||||||
<li><a href="/">Home</a></li>
|
<li><a href="/">Home</a></li>
|
||||||
<li class="active"><a href="#">Virtual Hosts</a></li>
|
<li class="active"><a href="#">Virtual Hosts</a></li>
|
||||||
<li><a href="/databases.php">Databases</a></li>
|
<li><a href="/databases.php">Databases</a></li>
|
||||||
<li><a href="/php.php">PHP</a></li>
|
<li> | </li>
|
||||||
|
<li><a href="/phpinfo.php">PHP info</a></li>
|
||||||
|
<li><a href="/opcache.php">PHP opcache</a></li>
|
||||||
|
<li><a href="/mysqlinfo.php">MySQL info</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><!--/.nav-collapse -->
|
</div><!--/.nav-collapse -->
|
||||||
</div>
|
</div>
|
@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes shell commands on the PHP-FPM Host
|
* Executes shell commands on the PHP-FPM Host
|
||||||
*
|
*
|
||||||
@ -25,8 +24,10 @@ function my_exec($cmd, &$output = '')
|
|||||||
* @param [type] $user [description]
|
* @param [type] $user [description]
|
||||||
* @return [type] [description]
|
* @return [type] [description]
|
||||||
*/
|
*/
|
||||||
function my_mysql_connect(&$err, $host = NULL, $pass = NULL, $user = NULL)
|
function my_mysql_connection_test(&$err, $host = NULL, $pass = NULL, $user = NULL)
|
||||||
{
|
{
|
||||||
|
$err = FALSE;
|
||||||
|
|
||||||
if ($host === NULL) {
|
if ($host === NULL) {
|
||||||
$host = $GLOBALS['MYSQL_HOST_ADDR'];
|
$host = $GLOBALS['MYSQL_HOST_ADDR'];
|
||||||
}
|
}
|
||||||
@ -37,20 +38,55 @@ function my_mysql_connect(&$err, $host = NULL, $pass = NULL, $user = NULL)
|
|||||||
$user = 'root';
|
$user = 'root';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
$link = mysqli_connect($host, $user, $pass);
|
if (!($link = @mysqli_connect($host, $user, $pass))) {
|
||||||
} catch (Exception $e) {
|
$err = 'Failed to connect: ' .mysqli_connect_error();
|
||||||
$err = $e->getMessage().': '.mysqli_connect_error();
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
mysqli_close($link);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// if (!($link = @mysqli_connect($host, $user, $pass))) {
|
|
||||||
// $err = mysqli_connect_error();
|
|
||||||
// return FALSE;
|
|
||||||
// }
|
/**
|
||||||
|
* Connect to database
|
||||||
|
*
|
||||||
|
* @param [type] $err [description]
|
||||||
|
* @param [type] $host [description]
|
||||||
|
* @param [type] $pass [description]
|
||||||
|
* @param [type] $user [description]
|
||||||
|
* @return [type] [description]
|
||||||
|
*/
|
||||||
|
function my_mysql_connect(&$err, $pass = NULL, $user = NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($pass === NULL) {
|
||||||
|
$pass = $GLOBALS['MYSQL_ROOT_PASS'];
|
||||||
|
}
|
||||||
|
if ($user === NULL) {
|
||||||
|
$user = 'root';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!($link = @mysqli_connect('localhost', $user, $pass))) {
|
||||||
|
$err = 'Failed to connect: ' .mysqli_connect_error();
|
||||||
|
if (!($link = @mysqli_connect('127.0.0.1', $user, $pass))) {
|
||||||
|
$err = 'Failed to connect: ' .mysqli_connect_error();
|
||||||
|
if (!($link = @mysqli_connect($GLOBALS['MYSQL_HOST_ADDR'], $user, $pass))) {
|
||||||
|
$err = 'Failed to connect: ' .mysqli_connect_error();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$err = FALSE;
|
||||||
return $link;
|
return $link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close Database connection
|
* Close Database connection
|
||||||
*
|
*
|
||||||
@ -58,8 +94,11 @@ function my_mysql_connect(&$err, $host = NULL, $pass = NULL, $user = NULL)
|
|||||||
* @return [type] [description]
|
* @return [type] [description]
|
||||||
*/
|
*/
|
||||||
function my_mysqli_close($link) {
|
function my_mysqli_close($link) {
|
||||||
|
if (is_object($link)) {
|
||||||
return mysqli_close($link);
|
return mysqli_close($link);
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,8 +124,10 @@ function my_mysqli_select(&$err, $link, $query, $callback = NULL)
|
|||||||
$callback($row, $data);
|
$callback($row, $data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
|
||||||
$data[] = $row;
|
$data[] = $row;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
mysqli_free_result($result);
|
mysqli_free_result($result);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
@ -181,7 +222,7 @@ function getTableCount($db_name) {
|
|||||||
* @param [type] $key [description]
|
* @param [type] $key [description]
|
||||||
* @return [type] [description]
|
* @return [type] [description]
|
||||||
*/
|
*/
|
||||||
function getMySQLConfig($key) {
|
function getMySQLConfigByKey($key) {
|
||||||
$key = str_replace('-', '_', $key);
|
$key = str_replace('-', '_', $key);
|
||||||
|
|
||||||
$callback = function ($row, &$data) use ($key) {
|
$callback = function ($row, &$data) use ($key) {
|
||||||
@ -200,6 +241,17 @@ function getMySQLConfig($key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMySQLConfig() {
|
||||||
|
$callback = function ($row, &$data) {
|
||||||
|
$key = $row['Variable_name'];
|
||||||
|
$val = $row['Value'];
|
||||||
|
$data[$key] = $val;
|
||||||
|
};
|
||||||
|
|
||||||
|
$sql = 'SHOW VARIABLES;';
|
||||||
|
return my_mysqli_select($error, $GLOBALS['MY_MYSQL_LINK'], $sql, $callback);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -351,7 +403,7 @@ function getHttpVersion() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function getMySQLVersion() {
|
function getMySQLVersion() {
|
||||||
return getMySQLConfig('version_comment') . ' ' . getMySQLConfig('version');
|
return getMySQLConfigByKey('version_comment') . ' ' . getMySQLConfigByKey('version');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPHPVersion() {
|
function getPHPVersion() {
|
3
cfg/README.md
Normal file
3
cfg/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Devilbox user-defined settings
|
||||||
|
|
||||||
|
Use this folders to add your custom configuration.
|
5
cfg/mysql-5.5/README.md
Normal file
5
cfg/mysql-5.5/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# User-defined MySQL configuration
|
||||||
|
|
||||||
|
Add as many `*.cnf` files here as you wish.
|
||||||
|
|
||||||
|
Files not ending with `*.cnf` will not be picked up during startup.
|
3
cfg/mysql-5.5/devilbox-user.cnf-example
Normal file
3
cfg/mysql-5.5/devilbox-user.cnf-example
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[mysqld]
|
||||||
|
slow_query_log = 1
|
||||||
|
log_queries_not_using_indexes = 1
|
@ -70,25 +70,24 @@ services:
|
|||||||
# ---- Format: ----
|
# ---- Format: ----
|
||||||
# HOST-DIRECTORY : DOCKER-DIRECTORY
|
# HOST-DIRECTORY : DOCKER-DIRECTORY
|
||||||
|
|
||||||
|
|
||||||
# Custom scripts/binaries required for httpd server vhost
|
# Custom scripts/binaries required for httpd server vhost
|
||||||
# configuration to work.
|
# configuration to work.
|
||||||
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
|
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
|
||||||
- ./bin/${HTTPD_SERVER}:/opt/bin
|
- ./base/bin/${HTTPD_SERVER}:/opt/bin
|
||||||
|
|
||||||
# Mount user-defined httpd configuration files
|
# Mount user-defined httpd configuration files
|
||||||
# @see environment::CUSTOM_HTTPD_CONF_DIR for how this
|
# @see environment::CUSTOM_HTTPD_CONF_DIR for how this
|
||||||
# is added in httpd server
|
# is added in httpd server
|
||||||
- ./etc/${HTTPD_SERVER}:/etc/${HTTPD_SERVER}
|
- ./base/etc/${HTTPD_SERVER}:/etc/${HTTPD_SERVER}
|
||||||
|
|
||||||
|
# Mount custom intranet
|
||||||
|
# (configured in /etc/${HTTPD_SERVER}/01-vhost-default.conf)
|
||||||
|
- ./base/www:/var/www/default
|
||||||
|
|
||||||
# Mount user-defined httpd log
|
# Mount user-defined httpd log
|
||||||
# @see ./etc/${HTTPD_SERVER}/*.conf for log defines
|
# @see ./etc/${HTTPD_SERVER}/*.conf for log defines
|
||||||
- ./log/${HTTPD_SERVER}:/var/log/${HTTPD_SERVER}
|
- ./log/${HTTPD_SERVER}:/var/log/${HTTPD_SERVER}
|
||||||
|
|
||||||
# Mount custom intranet
|
|
||||||
# (configured in /etc/${HTTPD_SERVER}/01-vhost-default.conf)
|
|
||||||
- ./www:/var/www/default
|
|
||||||
|
|
||||||
# Mount custom mass virtual hosting
|
# Mount custom mass virtual hosting
|
||||||
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
|
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
|
||||||
- ${HOST_PATH_TO_WWW_DOCROOTS}:/shared/httpd
|
- ${HOST_PATH_TO_WWW_DOCROOTS}:/shared/httpd
|
||||||
@ -180,16 +179,16 @@ services:
|
|||||||
# ---- Format: ----
|
# ---- Format: ----
|
||||||
# HOST-DIRECTORY : DOCKER-DIRECTORY
|
# HOST-DIRECTORY : DOCKER-DIRECTORY
|
||||||
|
|
||||||
|
# Mount custom intranet
|
||||||
|
# (configured in /etc/${HTTPD_SERVER}/01-vhost-default.conf)
|
||||||
|
- ./base/www:/var/www/default
|
||||||
|
|
||||||
# Mount logs
|
# Mount logs
|
||||||
- ./log/${PHP_SERVER}:/var/log/php-fpm
|
- ./log/${PHP_SERVER}:/var/log/php-fpm
|
||||||
|
|
||||||
# Mount MySQL Socket directory
|
# Mount MySQL Socket directory
|
||||||
- ./run/mysql:/tmp/mysql
|
- ./run/mysql:/tmp/mysql
|
||||||
|
|
||||||
# Mount custom intranet
|
|
||||||
# (configured in /etc/${HTTPD_SERVER}/01-vhost-default.conf)
|
|
||||||
- ./www:/var/www/default
|
|
||||||
|
|
||||||
# Mount custom mass virtual hosting
|
# Mount custom mass virtual hosting
|
||||||
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
|
# (configured in /etc/${HTTPD_SERVER}/02-vhost-mass.conf)
|
||||||
- ${HOST_PATH_TO_WWW_DOCROOTS}:/shared/httpd
|
- ${HOST_PATH_TO_WWW_DOCROOTS}:/shared/httpd
|
||||||
@ -222,17 +221,6 @@ services:
|
|||||||
|
|
||||||
# Runtime settings
|
# Runtime settings
|
||||||
- MYSQL_GENERAL_LOG=${MYSQL_GENERAL_LOG}
|
- MYSQL_GENERAL_LOG=${MYSQL_GENERAL_LOG}
|
||||||
- MYSQL_INNODB_LOG_FILE_SIZE=${MYSQL_INNODB_LOG_FILE_SIZE}
|
|
||||||
- MYSQL_INNODB_BUFFER_POOL_SIZE=${MYSQL_INNODB_BUFFER_POOL_SIZE}
|
|
||||||
- MYSQL_JOIN_BUFFER_SIZE=${MYSQL_JOIN_BUFFER_SIZE}
|
|
||||||
- MYSQL_SORT_BUFFER_SIZE=${MYSQL_SORT_BUFFER_SIZE}
|
|
||||||
- MYSQL_READ_RND_BUFFER_SIZE=${MYSQL_READ_RND_BUFFER_SIZE}
|
|
||||||
- MYSQL_SYMBOLIC_LINKS=${MYSQL_SYMBOLIC_LINKS}
|
|
||||||
- MYSQL_SQL_MODE=${MYSQL_SQL_MODE}
|
|
||||||
|
|
||||||
# Used for repairing
|
|
||||||
- MYSQL_INNODB_FORCE_RECOVERY=${MYSQL_INNODB_FORCE_RECOVERY}
|
|
||||||
- MYSQL_MODE=${MYSQL_MODE}
|
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
# [local-machine:]local-port:docker-port
|
# [local-machine:]local-port:docker-port
|
||||||
@ -252,6 +240,10 @@ services:
|
|||||||
# Mount MySQL Socket directory
|
# Mount MySQL Socket directory
|
||||||
- ./run/mysql:/tmp/mysql
|
- ./run/mysql:/tmp/mysql
|
||||||
|
|
||||||
|
# Mount devilbox user-defined cnf files in order
|
||||||
|
# to overwrite the MySQL server configuration
|
||||||
|
- ./cfg/${MYSQL_SERVER}:/etc/mysql/conf.d
|
||||||
|
|
||||||
# Mount MySQL Data directory
|
# Mount MySQL Data directory
|
||||||
- ${HOST_PATH_TO_MYSQL_DATADIR}:/var/lib/mysql
|
- ${HOST_PATH_TO_MYSQL_DATADIR}:/var/lib/mysql
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user