Skip to content

Commit 40cb199

Browse files
author
linuxitux
committed
Sysstat Graph integration
1 parent 3912539 commit 40cb199

16 files changed

+1460
-53
lines changed

LICENSE

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
License for sere
2+
----------------
3+
4+
The MIT License (MIT)
5+
6+
Copyright (c) 2017 Emiliano Marini
7+
8+
Permission is hereby granted, free of charge, to any person obtaining a copy of
9+
this software and associated documentation files (the "Software"), to deal in
10+
the Software without restriction, including without limitation the rights to
11+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12+
the Software, and to permit persons to whom the Software is furnished to do so,
13+
subject to the following conditions:
14+
15+
The above copyright notice and this permission notice shall be included in all
16+
copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
25+
License for Sysstat Graph
26+
-------------------------
27+
28+
The MIT License (MIT)
29+
30+
Copyright (c) 2015 Peter Mescalchin
31+
32+
Permission is hereby granted, free of charge, to any person obtaining a copy of
33+
this software and associated documentation files (the "Software"), to deal in
34+
the Software without restriction, including without limitation the rights to
35+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
36+
the Software, and to permit persons to whom the Software is furnished to do so,
37+
subject to the following conditions:
38+
39+
The above copyright notice and this permission notice shall be included in all
40+
copies or substantial portions of the Software.
41+
42+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
44+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
45+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
46+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
47+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ CPU utilization, memory and swap usage, I/O transfers, load, network activity an
1313
## Requierements
1414

1515
* PHP >= 5.4
16-
* sysstat >= 10.0.5 (http://pagesperso-orange.fr/sebastien.godard/)
16+
* sysstat == 10.0.5 (http://pagesperso-orange.fr/sebastien.godard/)
1717

1818

1919
### SysStat installation
@@ -34,6 +34,9 @@ On Red Hat and derivatives:
3434
## Configuration
3535

3636
cd /var/www/sere
37+
> data.json
38+
chown www-data:www-data data.json
39+
chmod 750 data.json
3740
cp config.example.php config.php
3841
vi config.php
3942

@@ -44,4 +47,4 @@ Edit the following variables accordingly:
4447
* $iface - network device you want to monitor.
4548
* $samples - number of sar samples for each request, 1 per second.
4649
* $update_interval - number of seconds between updates. It must be greater than the number of samples.
47-
50+
* SYSSTATDATAPATH - location of sarXX files (default is /var/log/sysstat)

buildjsonstructure.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
class buildjsonstructure {
3+
4+
private $networkinterfacelist = array();
5+
private $timepointlist = array();
6+
private $stattypelist = array();
7+
8+
9+
public function __construct(array $inputnetworkinterfacelist,array $inputtimepointlist,array $inputstattypelist) {
10+
11+
$this->networkinterfacelist = $inputnetworkinterfacelist;
12+
$this->timepointlist = $inputtimepointlist;
13+
$this->stattypelist = $inputstattypelist;
14+
}
15+
16+
public function render() {
17+
18+
$json = '{';
19+
20+
// build time point list
21+
$lasttimestamp = $this->getstartofdaytimestamp($this->timepointlist[0]);
22+
23+
// note we put the date in a YYYY-MM-DD and generate a timestamp on the client side to avoid timezone issues
24+
$json .=
25+
'starttime: \'' . date('Y-n-j',$lasttimestamp) . '\',' .
26+
'networkinterfacelist: [\'' . implode('\',\'',$this->networkinterfacelist) . '\'],' .
27+
'timepointlist: [';
28+
29+
$first = true;
30+
foreach ($this->timepointlist as $value) {
31+
$json .= (($first) ? '' : ',') . ($value - $lasttimestamp);
32+
$first = false;
33+
$lasttimestamp = $value;
34+
}
35+
36+
$json .= '],valuelist: {';
37+
38+
// build stat data lists
39+
$firsttype = true;
40+
foreach ($this->stattypelist as $type => $valuelist) {
41+
if (!$firsttype) $json .= ',';
42+
$json .= '\'' . $type . '\': [';
43+
44+
$firstvalue = true;
45+
foreach ($valuelist as $value) {
46+
$json .= (($firstvalue) ? '' : ',') . $value;
47+
$firstvalue = false;
48+
}
49+
50+
$json .= ']';
51+
$firsttype = false;
52+
}
53+
54+
$json .= '}}';
55+
56+
return $json;
57+
}
58+
59+
// getstartofdaytimestamp() takes a timestamp and returns a timestamp for the start of the day
60+
private function getstartofdaytimestamp($inputtimestamp) {
61+
62+
return mktime(
63+
0,0,0,
64+
date('n',$inputtimestamp),
65+
date('j',$inputtimestamp),
66+
date('Y',$inputtimestamp)
67+
);
68+
}
69+
}

config.example.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,10 @@
3232
$graphs = array('cpu','mem','swp','top','lda','ifx','tps','met','upt');
3333

3434
/***********************/
35+
36+
// Sysstat Graph config
37+
define('SYSSTATDATAPATH','/var/log/sysstat');
38+
define('JSONSTRUCTUREFILENAME','data.json');
39+
define('NETWORKINTERFACELIST',serialize(array($iface)));
40+
//define('NETWORKINTERFACELIST',serialize(array('lo',$iface)));
41+

data.json

Whitespace-only changes.

generatestatdata.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
/*
3+
Graph #1
4+
proc/s - Tasks created per second
5+
6+
Graph #2
7+
cswch/s - Context switches per second
8+
9+
Graph #3
10+
%usr - Percentage of CPU utilisation that occurred while executing at the user level
11+
%sys - Percentage of CPU utilisation that occurred while executing at the system level
12+
%iowait - Percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request
13+
14+
Graph #4
15+
kbmemused - Amount of used memory in kilobytes (processor converts to megabytes)
16+
kbswpused - Amount of used swap space in kilobytes (processor converts to megabytes)
17+
18+
Graph #5
19+
runq-sz - Run queue length (number of tasks waiting for run time)
20+
plist-sz - Number of tasks in the process list
21+
22+
Graph #6
23+
ldavg-1 - System load average for the last minute
24+
ldavg-5 - System load average for the past 5 minutes
25+
ldavg-15 - System load average for the past 15 minutes
26+
27+
Graph #n (network)
28+
rxpck/s - Total number of packets received per second
29+
txpck/s - Total number of packets transmitted per second
30+
31+
Graph #n+1 (network)
32+
rxkB/s - Total number of kilobytes received per second
33+
txkB/s - Total number of kilobytes transmitted per second
34+
*/
35+
36+
37+
class generatestatdata {
38+
39+
public function execute() {
40+
41+
// remove any trailing slashes from sysstat data path
42+
$sysstatdatapath = rtrim(SYSSTATDATAPATH,'\//');
43+
44+
// get listing of sar data files on disc, if no files found then no work to do
45+
if (!($sardatafilelist = $this->getsardatafilelist($sysstatdatapath))) {
46+
// no sar data files found
47+
return;
48+
}
49+
50+
if ($this->getjsonreporttimestamp() > $this->getsardatalatesttimestamp($sardatafilelist)) {
51+
// JSON report file is newer than latest sar data file, no work to do
52+
return;
53+
}
54+
55+
// process sar data files and build new JSON report data file
56+
$importstatfile = new importstatfiledata();
57+
58+
foreach ($sardatafilelist as $file) {
59+
// import each sar file from disc
60+
if (!is_file($file)) continue;
61+
$importstatfile->importfile($file);
62+
}
63+
64+
// generate JSON block and write to disc
65+
$buildjsonstructure = new buildjsonstructure(
66+
$importstatfile->getvalidnetworkinterfacelist(),
67+
$importstatfile->gettimepointlist(),
68+
$importstatfile->getstattypelist()
69+
);
70+
71+
$fp = fopen(JSONSTRUCTUREFILENAME,'w');
72+
if ($fp === false) {
73+
die('Error: Unable to create ' . realpath('.') . '/' . JSONSTRUCTUREFILENAME . ' - possible file system permissions issue.');
74+
}
75+
76+
fwrite($fp,$buildjsonstructure->render());
77+
fclose($fp);
78+
}
79+
80+
private function getsardatafilelist($inputdatapath) {
81+
82+
// sysstat data path must exist
83+
if (!is_dir($inputdatapath)) return array();
84+
85+
// fetch all files in data folder
86+
return glob($inputdatapath . '/sar??');
87+
}
88+
89+
private function getsardatalatesttimestamp(array $inputfilelist) {
90+
91+
$timestamp = 0;
92+
foreach ($inputfilelist as $file) {
93+
$filetimestamp = (is_file($file)) ? filemtime($file) : 0;
94+
$timestamp = ($filetimestamp > $timestamp) ? $filetimestamp : $timestamp;
95+
}
96+
97+
// return the timestamp of the latest sar data file found
98+
return $timestamp;
99+
}
100+
101+
private function getjsonreporttimestamp() {
102+
103+
if (is_file(JSONSTRUCTUREFILENAME)) {
104+
// if filesize of JSON structure file is zero (empty file) - then return a zero timestamp to allow new JSON data creation
105+
if (filesize(JSONSTRUCTUREFILENAME) == 0) return 0;
106+
107+
// return file modified timestamp
108+
return filemtime(JSONSTRUCTUREFILENAME);
109+
}
110+
111+
// no JSON structure file found
112+
return 0;
113+
}
114+
}

graphics.php

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function draw() {
1919
case 'cpu':
2020
?>
2121
<div class="metrics">
22-
<h4>CPU</h4>
22+
<h3>CPU</h3>
2323
<canvas id="cpu" width="300" height="160">Your browser doesn't support canvas.</canvas>
2424
</div>
2525
<?php
@@ -28,7 +28,7 @@ function draw() {
2828
case 'mem':
2929
?>
3030
<div class="metrics">
31-
<h4>Memory</h4>
31+
<h3>Memory</h3>
3232
<canvas id="mem" width="300" height="160">Your browser doesn't support canvas.</canvas>
3333
</div>
3434
<?php
@@ -37,7 +37,7 @@ function draw() {
3737
case 'swp':
3838
?>
3939
<div class="metrics">
40-
<h4>Swap</h4>
40+
<h3>Swap</h3>
4141
<canvas id="swp" width="300" height="160">Your browser doesn't support canvas.</canvas>
4242
</div>
4343
<?php
@@ -46,7 +46,7 @@ function draw() {
4646
case 'top':
4747
?>
4848
<div class="metrics">
49-
<h4>Top processes</h4>
49+
<h3>Top processes</h3>
5050
<table id="top" class="toptable"><tr><td>No data.</td></tr></table>
5151
</div>
5252
<?php
@@ -55,7 +55,7 @@ function draw() {
5555
case 'lda':
5656
?>
5757
<div class="metrics">
58-
<h4>Load</h4>
58+
<h3>Load</h3>
5959
<center><p class="bigmetric"><span id="lda_value_big">No data.</span></p></center>
6060
<p class="smallnote">System load average for the last minute.
6161
The load average is calculated as the average number
@@ -69,16 +69,14 @@ function draw() {
6969
case 'ifx':
7070
?>
7171
<div class="metrics">
72-
<h4><?php echo $this->iface; ?></h4>
72+
<h3><?php echo $this->iface; ?></h3>
7373
<center>
74-
<p class="bigmetric">
75-
<table border=0 width="300px">
76-
<tr><td align="right"><p class="bigmetric"><span id="ifr_value_big" style="font-size: 80%;">No data.</span></p></td>
74+
<table class="ifacetable" border=0 width="300px">
75+
<tr><td align="right"><p class="bigmetric"><span id="ifr_value_big">No data.</span></p></td>
7776
<td width="35%"><p><b>&darr;</b> received</p></td></tr>
78-
<tr><td align="right"><p class="bigmetric"><span id="ift_value_big" style="font-size: 80%;">No data.</span></p></td>
77+
<tr><td align="right"><p class="bigmetric"><span id="ift_value_big">No data.</span></p></td>
7978
<td><p><b>&uarr;</b> sent</p></td></tr>
8079
</table>
81-
</p>
8280
</center>
8381
<p class="smallnote">Total number of kilobytes received and transmitted per second.</p>
8482
</div>
@@ -88,7 +86,7 @@ function draw() {
8886
case 'tps':
8987
?>
9088
<div class="metrics">
91-
<h4>I/O</h4>
89+
<h3>I/O</h3>
9290
<center><p class="bigmetric"><span id="tps_value_big">No data.</span></p></center>
9391
<p class="smallnote">Total number of transfers per second that
9492
were issued to physical devices. A transfer
@@ -102,16 +100,16 @@ function draw() {
102100
case 'met':
103101
?>
104102
<div class="metrics">
105-
<h4>Metrics</h4>
103+
<h3>Metrics</h3>
106104
<table id="metricstable" class="metricstable" border="0" width="300px">
107-
<tr><td>CPU</td><td align="right"><span id="cpu_value">No data.</span></td></tr>
108-
<tr><td>TPS</td><td align="right"><span id="tps_value">No data.</span></td></tr>
109-
<tr><td>Memory</td><td align="right"><span id="mem_value">No data.</span></td></tr>
110-
<tr><td>Swap</td><td align="right"><span id="swp_value">No data.</span></td></tr>
111-
<tr><td>Load</td><td align="right"><span id="lda_value">No data.</span></td></tr>
112-
<tr><td>kB received</td><td align="right"><span id="ifr_value">No data.</span></td></tr>
113-
<tr><td>kB sent</td><td align="right"><span id="ift_value">No data.</span></td></tr>
114-
<tr><td>ESTABLISHED</td><td align="right"><span id="connections">No data.</span></td></tr>
105+
<tr><td>CPU</td><td style="text-align: right;"><span id="cpu_value">No data.</span></td></tr>
106+
<tr><td>TPS</td><td style="text-align: right;"><span id="tps_value">No data.</span></td></tr>
107+
<tr><td>Memory</td><td style="text-align: right;"><span id="mem_value">No data.</span></td></tr>
108+
<tr><td>Swap</td><td style="text-align: right;"><span id="swp_value">No data.</span></td></tr>
109+
<tr><td>Load</td><td style="text-align: right;"><span id="lda_value">No data.</span></td></tr>
110+
<tr><td>kB received</td><td style="text-align: right;"><span id="ifr_value">No data.</span></td></tr>
111+
<tr><td>kB sent</td><td style="text-align: right;"><span id="ift_value">No data.</span></td></tr>
112+
<tr><td>ESTABLISHED</td><td style="text-align: right;"><span id="connections">No data.</span></td></tr>
115113
</table>
116114
</div>
117115
<?php
@@ -120,9 +118,9 @@ function draw() {
120118
case 'upt':
121119
?>
122120
<div class="metrics">
123-
<h4>Uptime</h4>
121+
<h3>Uptime</h3>
124122
<table id="uptime" class="toptable"><tr><td>No data.</td></tr></table>
125-
<h4>Load averages</h4>
123+
<h3>Load averages</h3>
126124
<table id="loadaverages" class="toptable"><tr><td>No data.</td></tr></table>
127125
</div>
128126
<?php

img/timenotch.gif

43 Bytes
Loading

img/valuenotch.gif

43 Bytes
Loading

0 commit comments

Comments
 (0)