Project

General

Profile

Download (8.86 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * graph_cpu.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2004-2006 T. Lechat <dev@lechat.org>
8
 * Copyright (c) 2004-2006 Jonathan Watt <jwatt@jwatt.org>
9
 * All rights reserved.
10
 *
11
 * originally based on m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14
 *
15
 * Redistribution and use in source and binary forms, with or without
16
 * modification, are permitted provided that the following conditions are met:
17
 *
18
 * 1. Redistributions of source code must retain the above copyright notice,
19
 *    this list of conditions and the following disclaimer.
20
 *
21
 * 2. Redistributions in binary form must reproduce the above copyright
22
 *    notice, this list of conditions and the following disclaimer in
23
 *    the documentation and/or other materials provided with the
24
 *    distribution.
25
 *
26
 * 3. All advertising materials mentioning features or use of this software
27
 *    must display the following acknowledgment:
28
 *    "This product includes software developed by the pfSense Project
29
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
30
 *
31
 * 4. The names "pfSense" and "pfSense Project" must not be used to
32
 *    endorse or promote products derived from this software without
33
 *    prior written permission. For written permission, please contact
34
 *    coreteam@pfsense.org.
35
 *
36
 * 5. Products derived from this software may not be called "pfSense"
37
 *    nor may "pfSense" appear in their names without prior written
38
 *    permission of the Electric Sheep Fencing, LLC.
39
 *
40
 * 6. Redistributions of any form whatsoever must retain the following
41
 *    acknowledgment:
42
 *
43
 * "This product includes software developed by the pfSense Project
44
 * for use in the pfSense software distribution (http://www.pfsense.org/).
45
 *
46
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
47
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
50
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
57
 * OF THE POSSIBILITY OF SUCH DAMAGE.
58
 */
59

    
60
##|+PRIV
61
##|*IDENT=page-diagnostics-cpuutilization
62
##|*NAME=Diagnostics: CPU Utilization
63
##|*DESCR=Allow access to the 'Diagnostics: CPU Utilization' page.
64
##|*MATCH=graph_cpu.php*
65
##|*MATCH=stats.php*
66
##|-PRIV
67

    
68
require_once("guiconfig.inc");
69

    
70
header("Last-Modified: " . gmdate("D, j M Y H:i:s") . " GMT");
71
header("Expires: " . gmdate("D, j M Y H:i:s", time()) . " GMT");
72
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP/1.1
73
header("Pragma: no-cache"); // HTTP/1.0
74
header("Content-type: image/svg+xml");
75

    
76
/********* Other conf *******/
77

    
78
$nb_plot = 120;  // maximum number of data points to plot in the graph
79
$fetch_link = "stats.php?stats=cpu";
80

    
81
//SVG attributes
82
$attribs['axis']='fill="black" stroke="black"';
83
$attribs['cpu']='fill="#FF0000" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="7"';
84
$attribs['graph_cpu']='fill="none" stroke="#FF0000" stroke-opacity="0.8"';
85
$attribs['legend']='fill="black" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4"';
86
$attribs['grid_txt']='fill="gray" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="6"';
87
$attribs['grid']='stroke="gray" stroke-opacity="0.5"';
88
$attribs['error']='fill="blue" font-family="Arial" font-size="4"';
89
$attribs['collect_initial']='fill="gray" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4"';
90

    
91
$height=100;  // SVG internal height : do not modify
92
$width=200;   // SVG internal width  : do not modify
93

    
94
/********* Graph DATA **************/
95
print('<?xml version="1.0" encoding="UTF-8"?>' . "\n");?>
96
<svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt);">
97
	<g id="graph">
98
		<rect id="bg" x1="0" y1="0" width="100%" height="100%" fill="white"/>
99
		<line id="axis_x" x1="0" y1="0" x2="0" y2="100%" <?=$attribs['axis']?>/>
100
		<line id="axis_y" x1="0" y1="100%" x2="100%" y2="100%" <?=$attribs['axis']?>/>
101
		<polygon id="axis_arrow_x" <?=$attribs['axis']?> points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
102
		<path id="graph_cpu" d="" <?=$attribs['graph_cpu']?>/>
103
		<path id="grid" d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" <?=$attribs['grid']?>/>
104
		<text id="grid_txt1" x="100%" y="25%" <?=$attribs['grid_txt']?> text-anchor="end">75%</text>
105
		<text id="grid_txt2" x="100%" y="50%" <?=$attribs['grid_txt']?> text-anchor="end">50%</text>
106
		<text id="grid_txt3" x="100%" y="75%" <?=$attribs['grid_txt']?> text-anchor="end">25%</text>
107
		<text id="graph_cpu_txt" x="4" y="8" <?=$attribs['cpu']?>> </text>
108
		<text id="error" x="50%" y="50%" visibility="hidden" <?=$attribs['error']?> text-anchor="middle"><?=gettext("Cannot get CPU load"); ?></text>
109
		<text id="collect_initial" x="50%" y="50%" visibility="hidden" <?=$attribs['collect_initial']?> text-anchor="middle"><?=gettext("Collecting initial data, please wait"); ?>...</text>
110
	</g>
111
	<script type="text/ecmascript">
112
		<![CDATA[
113

    
114
/**
115
 * getURL is a proprietary Adobe function, but it's simplicity has made it very
116
 * popular. If getURL is undefined we spin our own by wrapping XMLHttpRequest.
117
 */
118
if (typeof getURL == 'undefined') {
119
	getURL = function(url, callback) {
120
		if (!url) {
121
			throw '<?=gettext("No URL for getURL"); ?>';
122
		}
123

    
124
		try {
125
			if (typeof callback.operationComplete == 'function') {
126
				callback = callback.operationComplete;
127
			}
128
		} catch (e) {}
129
		if (typeof callback != 'function') {
130
			throw '<?=gettext("No callback function for getURL"); ?>';
131
		}
132

    
133
		var http_request = null;
134
		if (typeof XMLHttpRequest != 'undefined') {
135
			http_request = new XMLHttpRequest();
136
		} else if (typeof ActiveXObject != 'undefined') {
137
			try {
138
				http_request = new ActiveXObject('Msxml2.XMLHTTP');
139
			} catch (e) {
140
				try {
141
					http_request = new ActiveXObject('Microsoft.XMLHTTP');
142
				} catch (e) {}
143
			}
144
		}
145
		if (!http_request) {
146
			throw '<?=gettext("Both getURL and XMLHttpRequest are undefined"); ?>';
147
		}
148

    
149
		http_request.onreadystatechange = function() {
150
			if (http_request.readyState == 4) {
151
				callback( { success : true,
152
					content : http_request.responseText,
153
					contentType : http_request.getResponseHeader("Content-Type") } );
154
			}
155
		}
156
		http_request.open('GET', url, true);
157
		http_request.send(null);
158
	}
159
}
160

    
161
var SVGDoc = null;
162
var last_cpu_total = 0;
163
var last_cpu_idle = 0;
164
var diff_cpu_total = 0;
165
var diff_cpu_idle = 0;
166
var cpu_data = new Array();
167

    
168
var max_num_points = <?=$nb_plot?>;  // maximum number of plot data points
169
var step = <?=$width?> / max_num_points;  // plot X division size
170
var scale = <?=$height?> / 100;
171

    
172
function init(evt) {
173
	SVGDoc = evt.target.ownerDocument;
174
	fetch_data();
175
}
176

    
177
function fetch_data() {
178
	getURL('<?=$fetch_link?>', plot_cpu_data);
179
}
180

    
181
function plot_cpu_data(obj) {
182
	if (!obj.success) {
183
		return handle_error();  // getURL failed to get current CPU load data
184
	}
185

    
186
	var cpu = parseInt(obj.content);
187
	if (!isNumber(cpu)) {
188
		return handle_error();
189
	}
190

    
191
	switch (cpu_data.length) {
192
		case 0:
193
			SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible');
194
			cpu_data[0] = cpu;
195
			fetch_data();
196
			return;
197
		case 1:
198
			SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden');
199
			break;
200
		case max_num_points:
201
			// shift plot to left if the maximum number of plot points has been reached
202
			var i = 0;
203
			while (i < max_num_points) {
204
				cpu_data[i] = cpu_data[++i];
205
			}
206
			--cpu_data.length;
207
	}
208

    
209
	cpu_data[cpu_data.length] = cpu;
210

    
211
	var path_data = "M 0 " + (<?=$height?> - (cpu_data[0] * scale));
212
	for (var i = 1; i < cpu_data.length; ++i) {
213
		var x = step * i;
214
		var y_cpu = <?=$height?> - (cpu_data[i] * scale);
215
		path_data += " L" + x + " " + y_cpu;
216
	}
217

    
218
	SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'hidden');
219
	SVGDoc.getElementById('graph_cpu_txt').firstChild.data = cpu + '%';
220
	SVGDoc.getElementById('graph_cpu').setAttributeNS(null, "d", path_data);
221

    
222
	fetch_data();
223
}
224

    
225
function handle_error() {
226
	SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
227
	fetch_data();
228
}
229

    
230
function isNumber(a) {
231
	return typeof a == 'number' && isFinite(a);
232
}
233

    
234
		]]>
235
	</script>
236
</svg>
(62-62/227)