-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph.php
249 lines (207 loc) · 8.81 KB
/
graph.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
<?php
/* $Id: graph.php 2183 2010-01-07 16:09:55Z d_pocock $ */
include_once "./eval_config.php";
include_once "./get_context.php";
include_once "./functions.php";
if ($_GET["ccache"] == 1) {
if ($clustername == "") $clustername = "unspecified";
$img_filename = $img_cache_dir.$clustername."_".$graph_report.".png";
get_image_cache($img_filename);
exit;
}
# RFM - Added all the isset() tests to eliminate "undefined index"
# messages in ssl_error_log.
# Graph specific variables
# ATD - No need for escapeshellcmd or rawurldecode on $size or $graph. Not used directly in rrdtool calls.
$size = isset($_GET["z"]) && in_array( $_GET[ 'z' ], $graph_sizes_keys )
? $_GET["z"]
: NULL;
# ATD - TODO, should encapsulate these custom graphs in some type of container, then this code could check list of defined containers for valid graph labels.
$graph = isset($_GET["g"]) ? sanitize ( $_GET["g"] ) : NULL;
$grid = isset($_GET["G"]) ? sanitize ( $_GET["G"] ) : NULL;
$self = isset($_GET["me"]) ? sanitize ( $_GET["me"] ) : NULL;
$vlabel = isset($_GET["vl"]) ? sanitize ( $_GET["vl"] ) : NULL;
$value = isset($_GET["v"]) ? sanitize ( $_GET["v"] ) : NULL;
$max = isset($_GET["x"]) ? clean_number ( sanitize ($_GET["x"] ) ) : NULL;
$min = isset($_GET["n"]) ? clean_number ( sanitize ($_GET["n"] ) ) : NULL;
$sourcetime = isset($_GET["st"]) ? clean_number ( sanitize( $_GET["st"] ) ) : NULL;
$load_color = isset($_GET["l"]) && is_valid_hex_color( rawurldecode( $_GET[ 'l' ] ) )
? sanitize ( $_GET["l"] ) : NULL;
$summary = isset( $_GET["su"] ) ? 1 : 0;
$debug = isset( $_GET['debug'] ) ? clean_number ( sanitize( $_GET["debug"] ) ) : 0;
$command = '';
if ($_GET["mode"] == "zoom") {
$start = isset($_GET["start"]) ? clean_number ( sanitize ($_GET["start"] ) ): NULL;
$end = isset($_GET["end"]) ? clean_number ( sanitize ($_GET["end"] ) ): NULL;
}
# Assumes we have a $start variable (set in get_context.php).
# $graph_sizes and $graph_sizes_keys defined in conf.php. Add custom sizes there.
$size = in_array( $size, $graph_sizes_keys ) ? $size : 'default';
$height = $graph_sizes[ $size ][ 'height' ];
$width = $graph_sizes[ $size ][ 'width' ];
$fudge_0 = $graph_sizes[ $size ][ 'fudge_0' ];
$fudge_1 = $graph_sizes[ $size ][ 'fudge_1' ];
$fudge_2 = $graph_sizes[ $size ][ 'fudge_2' ];
#
# Since the $command variable is explicitly set to an empty string, above, do we really need
# this check anymore? --jb Jan 2008
#
# This security fix was brought to my attention by Peter Vreugdenhil <petervre@sci.kun.nl>
# Dont want users specifying their own malicious command via GET variables e.g.
# http://ganglia.mrcluster.org/graph.php?graph=blob&command=whoami;cat%20/etc/passwd
#
if($command) {
error_log("Command variable sent, exiting!");
exit();
}
switch ($context)
{
case "meta":
$rrd_dir = "$rrds/__SummaryInfo__";
break;
case "grid":
$rrd_dir = "$rrds/$grid/__SummaryInfo__";
break;
case "cluster":
$rrd_dir = "$rrds/$clustername/__SummaryInfo__";
break;
case "host":
$rrd_dir = "$rrds/$clustername/$hostname";
break;
default:
exit;
}
# Set some standard defaults that don't need to change much
$rrdtool_graph = array(
'start' => $start,
'end' => $end,
'width' => $width,
'height' => $height,
);
if ($debug) {
error_log("Graph [$graph] in context [$context]");
}
/* If we have $graph, then a specific report was requested, such as "network_report" or
* "cpu_report. These graphs usually have some special logic and custom handling required,
* instead of simply plotting a single metric. If $graph is not set, then we are (hopefully),
* plotting a single metric, and will use the commands in the metric.php file.
*
* With modular graphs, we look for a "${graph}.php" file, and if it exists, we
* source it, and call a pre-defined function name. The current scheme for the function
* names is: 'graph_' + <name_of_report>. So a 'cpu_report' would call graph_cpu_report(),
* which would be found in the cpu_report.php file.
*
* These functions take the $rrdtool_graph array as an argument. This variable is
* PASSED BY REFERENCE, and will be modified by the various functions. Each key/value
* pair represents an option/argument, as passed to the rrdtool program. Thus,
* $rrdtool_graph['title'] will refer to the --title option for rrdtool, and pass the array
* value accordingly.
*
* There are two exceptions to: the 'extras' and 'series' keys in $rrdtool_graph. These are
* assigned to $extras and $series respectively, and are treated specially. $series will contain
* the various DEF, CDEF, RULE, LINE, AREA, etc statements that actually plot the charts. The
* rrdtool program requires that this come *last* in the argument string; we make sure that it
* is put in it's proper place. The $extras variable is used for other arguemnts that may not
* fit nicely for other reasons. Complicated requests for --color, or adding --ridgid, for example.
* It is simply a way for the graph writer to add an arbitrary options when calling rrdtool, and to
* forcibly override other settings, since rrdtool will use the last version of an option passed.
* (For example, if you call 'rrdtool' with two --title statements, the second one will be used.)
*
* See $graphdir/sample.php for more documentation, and details on the
* common variables passed and used.
*/
// No report requested, so use 'metric'
if (!$graph) {
$graph = 'metric';
}
$graph_file = "$graphdir/$graph.php";
if ( is_readable($graph_file) ) {
include_once($graph_file);
$graph_function = "graph_${graph}";
$graph_function($rrdtool_graph); // Pass by reference call, $rrdtool_graph modified inplace
} else {
/* Bad stuff happened. */
error_log("Tried to load graph file [$graph_file], but failed. Invalid graph, aborting.");
exit();
}
# Calculate time range.
if ($sourcetime)
{
$end = $sourcetime;
# Get_context makes start negative.
$start = $sourcetime + $start;
}
# Fix from Phil Radden, but step is not always 15 anymore.
if ($range=="month")
$rrdtool_graph['end'] = floor($rrdtool_graph['end'] / 672) * 672;
# Tidy up the title a bit
switch ($context) {
case 'meta':
$title = "$self Grid";
break;
case 'cluster':
$title = "$clustername Cluster";
break;
case 'grid':
$title = "$gridname Grid";
break;
case 'host':
if (!$summary)
$title = null ;
break;
default:
$title = $clustername;
break;
}
if ($context != 'host') {
$rrdtool_graph['title'] = $rrdtool_graph['title'] . " last $range";
}
if (isset($title)) {
$rrdtool_graph['title'] = "$title " . $rrdtool_graph['title'];
}
//--------------------------------------------------------------------------------------
// We must have a 'series' value, or this is all for naught
if (!array_key_exists('series', $rrdtool_graph) || !strlen($rrdtool_graph['series']) ) {
error_log("\$series invalid for this graph request ".$_SERVER['PHP_SELF']);
exit();
}
$command = RRDTOOL . " graph - $rrd_options ";
$command .= "--color 'BACK#E0E0E0' --color 'SHADEA#FFFFFF' --color 'SHADEB#FFFFFF'";
#$command .= "--color 'BACK#E0E0E0' --color 'SHADEA#FFFFFF' --color 'SHADEB#FFFFFF' --watermark '$clustername'";
// The order of the other arguments isn't important, except for the
// 'extras' and 'series' values. These two require special handling.
// Otherwise, we just loop over them later, and tack $extras and
// $series onto the end of the command.
foreach (array_keys ($rrdtool_graph) as $key) {
if (preg_match('/extras|series/', $key))
continue;
$value = $rrdtool_graph[$key];
if (preg_match('/\W/', $value)) {
//more than alphanumerics in value, so quote it
$value = "'$value'";
}
$command .= " --$key $value";
}
// And finish up with the two variables that need special handling.
// See above for how these are created
$command .= array_key_exists('extras', $rrdtool_graph) ? ' '.$rrdtool_graph['extras'].' ' : '';
$command .= " $rrdtool_graph[series]";
//error_log("Final command: $command");
# Did we generate a command? Run it.
if($command) {
/*Make sure the image is not cached*/
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header ("Pragma: no-cache"); // HTTP/1.0
if ($debug>2) {
header ("Content-type: text/html");
print "<html><body>";
print htmlentities( $command );
print "</body></html>";
} else {
header ("Content-type: image/gif");
passthru($command);
}
}
?>