Fixes #39
This adds a new graph to the highlight bar along with the ability to turn on/off individual charts.
This commit is contained in:
parent
3f1591471d
commit
351525a1a0
3 changed files with 115 additions and 118 deletions
30
README.md
30
README.md
|
@ -3,10 +3,13 @@
|
|||
A clean and responsive interface for Zend OPcache information, showing statistics, settings and cached files, and providing a real-time update for the information (using jQuery and React).
|
||||
|
||||
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=acollington&url=https://github.com/amnuts/opcache-gui&title=opcache-gui&language=&tags=github&category=software)
|
||||
If you like this software or find it helpful then please consider [signing up to Flattr and leaving a micro-donation](https://flattr.com/@acollington). If you don't want to do that, I hope you find it useful anyway! :-).
|
||||
If you like this software or find it helpful then maybe you'll consider supporting my efforts in some way by [signing up to Flattr and leaving a micro-donation](https://flattr.com/@acollington).
|
||||
|
||||
## What's new
|
||||
|
||||
**Version 2.5.0**\
|
||||
Added a new highlight chart to show the cached keys percentage with options to turn on/off the individual highlight graphs.
|
||||
|
||||
**Version 2.4.1**\
|
||||
Mostly bug fixes
|
||||
* `memory_consumption` and `max_file_size` config settings now display as human-readable sizes
|
||||
|
@ -51,15 +54,22 @@ There are two ways to getting started using this gui.
|
|||
If you want to set the configuration options just alter the array at the top of the script:
|
||||
```php
|
||||
$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
|
||||
'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
|
||||
'cookie_name' => 'opcachegui', // name of cookie
|
||||
'cookie_ttl' => 365, // days to store cookie
|
||||
'highlight' => [ // highlight charts/big numbers
|
||||
'memory' => true,
|
||||
'hits' => true,
|
||||
'keys' => true
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
|
|
135
index.php
135
index.php
|
@ -8,7 +8,7 @@ namespace OpcacheGui;
|
|||
* A simple but effective single-file GUI for the OPcache PHP extension.
|
||||
*
|
||||
* @author Andrew Collington, andy@amnuts.com
|
||||
* @version 2.4.1
|
||||
* @version 2.5.0
|
||||
* @link https://github.com/amnuts/opcache-gui
|
||||
* @license MIT, http://acollington.mit-license.org/
|
||||
*/
|
||||
|
@ -28,7 +28,12 @@ $options = [
|
|||
'charts' => true, // show gauge chart or just big numbers
|
||||
'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering
|
||||
'cookie_name' => 'opcachegui', // name of cookie
|
||||
'cookie_ttl' => 365 // days to store cookie
|
||||
'cookie_ttl' => 365, // days to store cookie
|
||||
'highlight' => [ // highlight charts/big numbers
|
||||
'memory' => true,
|
||||
'hits' => true,
|
||||
'keys' => true
|
||||
]
|
||||
];
|
||||
|
||||
/*
|
||||
|
@ -188,6 +193,9 @@ class OpCacheService
|
|||
($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']),
|
||||
'used_key_percentage' => round(100 * (
|
||||
$status['opcache_statistics']['num_cached_keys']
|
||||
/ $status['opcache_statistics']['max_cached_keys'])),
|
||||
'wasted_percentage' => round($status['memory_usage']['current_wasted_percentage'], 2),
|
||||
'readable' => [
|
||||
'total_memory' => $this->size($config['directives']['opcache.memory_consumption']),
|
||||
|
@ -416,6 +424,7 @@ $opcache = OpCacheService::init($options);
|
|||
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 highlight = <?php echo json_encode($opcache->getOption('highlight')); ?>;
|
||||
var allowFiles = <?php echo json_encode($opcache->getOption('allow_filelist')); ?>;
|
||||
var debounce = function(func, wait, immediate) {
|
||||
var timeout;
|
||||
|
@ -576,64 +585,26 @@ $opcache = OpCacheService::init($options);
|
|||
$('#frmFilter').bind('keyup', debounce(keyUp, <?php echo $opcache->getOption('debounce_rate'); ?>));
|
||||
});
|
||||
|
||||
var MemoryUsageGraph = React.createClass({
|
||||
var UsageGraph = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
memoryUsageGauge: null
|
||||
gauge: null
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
if (this.props.chart) {
|
||||
this.state.memoryUsageGauge = new Gauge('#memoryUsageCanvas');
|
||||
this.state.memoryUsageGauge.setValue(this.props.value);
|
||||
this.state.gauge = new Gauge('#' + this.props.gaugeId);
|
||||
this.state.gauge.setValue(this.props.value);
|
||||
}
|
||||
},
|
||||
componentDidUpdate: function () {
|
||||
if (this.state.memoryUsageGauge != null) {
|
||||
this.state.memoryUsageGauge.setValue(this.props.value);
|
||||
if (this.state.gauge != null) {
|
||||
this.state.gauge.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 HitRateGraph = React.createClass({
|
||||
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("canvas", { id: this.props.gaugeId, width: "250", height: "250", "data-value": this.props.value });
|
||||
}
|
||||
return React.createElement(
|
||||
"p",
|
||||
|
@ -867,7 +838,8 @@ $opcache = OpCacheService::init($options);
|
|||
getInitialState: function () {
|
||||
return {
|
||||
data: opstate.overview,
|
||||
chart: useCharts
|
||||
chart: useCharts,
|
||||
highlight: highlight
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
|
@ -896,37 +868,58 @@ $opcache = OpCacheService::init($options);
|
|||
strings_free_memory: this.state.data.readable.interned.strings_free_memory,
|
||||
number_of_strings: this.state.data.readable.interned.number_of_strings
|
||||
}) : '';
|
||||
return React.createElement(
|
||||
|
||||
var memoryHighlight = this.state.highlight.memory ? React.createElement(
|
||||
"div",
|
||||
null,
|
||||
React.createElement(
|
||||
"div",
|
||||
"h3",
|
||||
null,
|
||||
React.createElement(
|
||||
"h3",
|
||||
null,
|
||||
"memory"
|
||||
),
|
||||
React.createElement(
|
||||
"p",
|
||||
null,
|
||||
React.createElement(MemoryUsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage })
|
||||
)
|
||||
"memory"
|
||||
),
|
||||
React.createElement(
|
||||
"div",
|
||||
"p",
|
||||
null,
|
||||
React.createElement(
|
||||
"h3",
|
||||
null,
|
||||
"hit rate"
|
||||
),
|
||||
React.createElement(
|
||||
"p",
|
||||
null,
|
||||
React.createElement(HitRateGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage })
|
||||
)
|
||||
React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage, gaugeId: "memoryUsageCanvas" })
|
||||
)
|
||||
) : null;
|
||||
|
||||
var hitsHighlight = this.state.highlight.hits ? React.createElement(
|
||||
"div",
|
||||
null,
|
||||
React.createElement(
|
||||
"h3",
|
||||
null,
|
||||
"hit rate"
|
||||
),
|
||||
React.createElement(
|
||||
"p",
|
||||
null,
|
||||
React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage, gaugeId: "hitRateCanvas" })
|
||||
)
|
||||
) : null;
|
||||
|
||||
var keysHighlight = this.state.highlight.keys ? React.createElement(
|
||||
"div",
|
||||
null,
|
||||
React.createElement(
|
||||
"h3",
|
||||
null,
|
||||
"keys"
|
||||
),
|
||||
React.createElement(
|
||||
"p",
|
||||
null,
|
||||
React.createElement(UsageGraph, { chart: this.state.chart, value: this.state.data.used_key_percentage, gaugeId: "keyUsageCanvas" })
|
||||
)
|
||||
) : null;
|
||||
|
||||
return React.createElement(
|
||||
"div",
|
||||
null,
|
||||
memoryHighlight,
|
||||
hitsHighlight,
|
||||
keysHighlight,
|
||||
React.createElement(MemoryUsagePanel, {
|
||||
total: this.state.data.readable.total_memory,
|
||||
used: this.state.data.readable.used_memory,
|
||||
|
|
|
@ -1,48 +1,23 @@
|
|||
var MemoryUsageGraph = React.createClass({
|
||||
var UsageGraph = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
memoryUsageGauge : null
|
||||
gauge : null
|
||||
};
|
||||
},
|
||||
componentDidMount: function() {
|
||||
if (this.props.chart) {
|
||||
this.state.memoryUsageGauge = new Gauge('#memoryUsageCanvas');
|
||||
this.state.memoryUsageGauge.setValue(this.props.value);
|
||||
this.state.gauge = new Gauge('#' + this.props.gaugeId);
|
||||
this.state.gauge.setValue(this.props.value);
|
||||
}
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
if (this.state.memoryUsageGauge != null) {
|
||||
this.state.memoryUsageGauge.setValue(this.props.value);
|
||||
if (this.state.gauge != null) {
|
||||
this.state.gauge.setValue(this.props.value);
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
if (this.props.chart == true) {
|
||||
return(<canvas id="memoryUsageCanvas" width="250" height="250" data-value={this.props.value} />);
|
||||
}
|
||||
return(<p><span className="large">{this.props.value}</span><span>%</span></p>);
|
||||
}
|
||||
});
|
||||
|
||||
var HitRateGraph = React.createClass({
|
||||
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(<canvas id="hitRateCanvas" width="250" height="250" data-value={this.props.value} />);
|
||||
return(<canvas id={this.props.gaugeId} width="250" height="250" data-value={this.props.value} />);
|
||||
}
|
||||
return(<p><span className="large">{this.props.value}</span><span>%</span></p>);
|
||||
}
|
||||
|
@ -102,7 +77,8 @@ var OverviewCounts = React.createClass({
|
|||
getInitialState: function() {
|
||||
return {
|
||||
data : opstate.overview,
|
||||
chart : useCharts
|
||||
chart : useCharts,
|
||||
highlight: highlight
|
||||
};
|
||||
},
|
||||
render: function() {
|
||||
|
@ -122,16 +98,34 @@ var OverviewCounts = React.createClass({
|
|||
/>
|
||||
: ''
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
|
||||
var memoryHighlight = this.state.highlight.memory ? (
|
||||
<div>
|
||||
<h3>memory</h3>
|
||||
<p><MemoryUsageGraph chart={this.state.chart} value={this.state.data.used_memory_percentage} /></p>
|
||||
<p><UsageGraph chart={this.state.chart} value={this.state.data.used_memory_percentage} gaugeId="memoryUsageCanvas"/></p>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
var hitsHighlight = this.state.highlight.hits ? (
|
||||
<div>
|
||||
<h3>hit rate</h3>
|
||||
<p><HitRateGraph chart={this.state.chart} value={this.state.data.hit_rate_percentage} /></p>
|
||||
<p><UsageGraph chart={this.state.chart} value={this.state.data.hit_rate_percentage} gaugeId="hitRateCanvas"/></p>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
var keysHighlight = this.state.highlight.keys ? (
|
||||
<div>
|
||||
<h3>keys</h3>
|
||||
<p><UsageGraph chart={this.state.chart} value={this.state.data.used_key_percentage} gaugeId="keyUsageCanvas"/></p>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
{memoryHighlight}
|
||||
{hitsHighlight}
|
||||
{keysHighlight}
|
||||
<MemoryUsagePanel
|
||||
total={this.state.data.readable.total_memory}
|
||||
used={this.state.data.readable.used_memory}
|
||||
|
|
Loading…
Reference in a new issue