aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--conf/config.php5
-rw-r--r--inc/collectd.inc.php99
-rw-r--r--rrd.php2
-rw-r--r--type/Default.class.php18
4 files changed, 76 insertions, 48 deletions
diff --git a/conf/config.php b/conf/config.php
index f2fab29..ffa42cf 100644
--- a/conf/config.php
+++ b/conf/config.php
@@ -72,9 +72,14 @@ $CONFIG['max-height'] = $CONFIG['detail-height'] * 2;
72 72
73# collectd's unix socket (unixsock plugin) 73# collectd's unix socket (unixsock plugin)
74# enabled: 'unix:///var/run/collectd-unixsock' 74# enabled: 'unix:///var/run/collectd-unixsock'
75# enabled (rrdcached): 'unix:///var/run/rrdcached.sock'
75# disabled: NULL 76# disabled: NULL
76$CONFIG['socket'] = NULL; 77$CONFIG['socket'] = NULL;
77 78
79# flush rrd data to disk using "collectd" (unixsock plugin)
80# or a "rrdcached" server
81$CONFIG['flush_type'] = 'collectd';
82
78# system default timezone when not set 83# system default timezone when not set
79$CONFIG['default_timezone'] = 'UTC'; 84$CONFIG['default_timezone'] = 'UTC';
80 85
diff --git a/inc/collectd.inc.php b/inc/collectd.inc.php
index 7269e68..e364180 100644
--- a/inc/collectd.inc.php
+++ b/inc/collectd.inc.php
@@ -19,6 +19,26 @@ function collectd_hosts() {
19 return($dir); 19 return($dir);
20} 20}
21 21
22
23# return files in directory. this will recurse into subdirs
24# infinite loop may occur
25function get_host_rrd_files($dir) {
26 $files = array();
27
28 $objects = new RegexIterator(
29 new RecursiveIteratorIterator(
30 new RecursiveDirectoryIterator($dir),
31 RecursiveIteratorIterator::SELF_FIRST),
32 '/\.rrd$/');
33
34 foreach($objects as $object) {
35 $files[] = str_replace($dir.'/', '', $object->getPathname());
36 }
37
38 return $files;
39}
40
41
22# returns an array of plugins/pinstances/types/tinstances 42# returns an array of plugins/pinstances/types/tinstances
23function collectd_plugindata($host, $plugin=NULL) { 43function collectd_plugindata($host, $plugin=NULL) {
24 global $CONFIG; 44 global $CONFIG;
@@ -26,8 +46,8 @@ function collectd_plugindata($host, $plugin=NULL) {
26 if (!is_dir($CONFIG['datadir'].'/'.$host)) 46 if (!is_dir($CONFIG['datadir'].'/'.$host))
27 return false; 47 return false;
28 48
29 chdir($CONFIG['datadir'].'/'.$host); 49 $hostdir = $CONFIG['datadir'].'/'.$host;
30 $files = glob("*/*.rrd"); 50 $files = get_host_rrd_files($hostdir);
31 if (!$files) 51 if (!$files)
32 return false; 52 return false;
33 53
@@ -215,6 +235,28 @@ function build_url($base, $items, $s=NULL) {
215 return $base; 235 return $base;
216} 236}
217 237
238function socket_cmd($socket, $cmd) {
239 $r = fwrite($socket, $cmd, strlen($cmd));
240 if ($r === false || $r != strlen($cmd)) {
241 error_log(sprintf('ERROR: Failed to write full command to unix-socket: %d out of %d written',
242 $r === false ? -1 : $r, strlen($cmd)));
243 return FALSE;
244 }
245
246 $resp = fgets($socket,128);
247 if ($resp === false) {
248 error_log(sprintf('ERROR: Failed to read response from collectd for command: %s',
249 trim($cmd)));
250 return FALSE;
251 }
252
253 $n = (int)$resp;
254 while ($n-- > 0)
255 fgets($socket,128);
256
257 return TRUE;
258}
259
218# tell collectd to FLUSH all data of the identifier(s) 260# tell collectd to FLUSH all data of the identifier(s)
219function collectd_flush($identifier) { 261function collectd_flush($identifier) {
220 global $CONFIG; 262 global $CONFIG;
@@ -226,43 +268,34 @@ function collectd_flush($identifier) {
226 !(is_string($identifier) || is_array($identifier))) 268 !(is_string($identifier) || is_array($identifier)))
227 return FALSE; 269 return FALSE;
228 270
271 if (!is_array($identifier))
272 $identifier = array($identifier);
273
229 $u_errno = 0; 274 $u_errno = 0;
230 $u_errmsg = ''; 275 $u_errmsg = '';
231 if ($socket = @fsockopen($CONFIG['socket'], 0, $u_errno, $u_errmsg)) { 276 if (! $socket = @fsockopen($CONFIG['socket'], 0, $u_errno, $u_errmsg)) {
232 $cmd = 'FLUSH plugin=rrdtool'; 277 error_log(sprintf('ERROR: Failed to open unix-socket to %s (%d: %s)',
233 if (is_array($identifier)) { 278 $CONFIG['socket'], $u_errno, $u_errmsg));
234 foreach ($identifier as $val) 279 return FALSE;
235 $cmd .= sprintf(' identifier="%s"', $val); 280 }
236 } else
237 $cmd .= sprintf(' identifier="%s"', $identifier);
238 $cmd .= "\n";
239
240 $r = fwrite($socket, $cmd, strlen($cmd));
241 if ($r === false || $r != strlen($cmd)) {
242 error_log(sprintf('ERROR: Failed to write full command to unix-socket: %d out of %d written',
243 $r === false ? -1 : $r, strlen($cmd)));
244 return FALSE;
245 }
246 281
247 $resp = fgets($socket); 282 if ($CONFIG['flush_type'] == 'collectd'){
248 if ($resp === false) { 283 $cmd = 'FLUSH';
249 error_log(sprintf('ERROR: Failed to read response from collectd for command: %s', 284 foreach ($identifier as $val)
250 trim($cmd))); 285 $cmd .= sprintf(' identifier="%s"', $val);
251 return FALSE; 286 $cmd .= "\n";
287 socket_cmd($socket, $cmd);
288 }
289 elseif ($CONFIG['flush_type'] == 'rrdcached') {
290 foreach ($identifier as $val) {
291 $cmd = sprintf("FLUSH %s.rrd\n", $val);
292 socket_cmd($socket, $cmd);
252 } 293 }
294 }
253 295
254 $n = (int)$resp; 296 fclose($socket);
255 while ($n-- > 0)
256 fgets($socket);
257
258 fclose($socket);
259 297
260 return TRUE; 298 return TRUE;
261 } else {
262 error_log(sprintf('ERROR: Failed to open unix-socket to collectd: %d: %s',
263 $u_errno, $u_errmsg));
264 return FALSE;
265 }
266} 299}
267 300
268?> 301?>
diff --git a/rrd.php b/rrd.php
index 1b5997b..b4c7f68 100644
--- a/rrd.php
+++ b/rrd.php
@@ -4,7 +4,7 @@ require_once 'conf/common.inc.php';
4require_once 'inc/functions.inc.php'; 4require_once 'inc/functions.inc.php';
5require_once 'inc/html.inc.php'; 5require_once 'inc/html.inc.php';
6 6
7if ($file = validateRRDPath($CONFIG['datadir'], $_SERVER['PATH_INFO'])) { 7if ( $file = validateRRDPath($CONFIG['datadir'], urldecode($_SERVER["QUERY_STRING"])) ) {
8 header('Content-Type: application/octet-stream'); 8 header('Content-Type: application/octet-stream');
9 header('Content-Disposition: attachment; filename='.basename($file)); 9 header('Content-Disposition: attachment; filename='.basename($file));
10 header("Expires: " .date(DATE_RFC822,strtotime($CONFIG['cache']." seconds"))); 10 header("Expires: " .date(DATE_RFC822,strtotime($CONFIG['cache']." seconds")));
diff --git a/type/Default.class.php b/type/Default.class.php
index 5e19e73..2cd8560 100644
--- a/type/Default.class.php
+++ b/type/Default.class.php
@@ -34,7 +34,6 @@ class Type_Default {
34 $this->cache = $config['cache']; 34 $this->cache = $config['cache'];
35 $this->parse_get(); 35 $this->parse_get();
36 $this->rrd_files(); 36 $this->rrd_files();
37 $this->identifiers = $this->file2identifier($this->files);
38 $this->width = GET('x'); 37 $this->width = GET('x');
39 if (empty($this->width)) $this->width = $config['width']; 38 if (empty($this->width)) $this->width = $config['width'];
40 $this->height = GET('y'); 39 $this->height = GET('y');
@@ -122,9 +121,9 @@ class Type_Default {
122 121
123 function parse_filename($file) { 122 function parse_filename($file) {
124 if ($this->graph_type == 'canvas') { 123 if ($this->graph_type == 'canvas') {
125 $file = 'rrd.php/' . str_replace($this->datadir . '/', '', $file); 124 $file = str_replace($this->datadir . '/', '', $file);
126 # rawurlencode all but / 125 # rawurlencode all but /
127 $file = str_replace('%2F', '/', rawurlencode($file)); 126 $file = 'rrd.php?' . str_replace('%2F', '/', rawurlencode($file));
128 } else { 127 } else {
129 # escape characters 128 # escape characters
130 $file = str_replace(array(' ', '(', ')'), array('\ ', '\(', '\)'), $file); 129 $file = str_replace(array(' ', '(', ')'), array('\ ', '\(', '\)'), $file);
@@ -143,10 +142,12 @@ class Type_Default {
143 142
144 $this->tinstances[] = $instance; 143 $this->tinstances[] = $instance;
145 $this->files[$instance] = $filename; 144 $this->files[$instance] = $filename;
145 $this->identifiers[$instance] = preg_replace("#^$this->datadir/(.*)\.rrd$#", '$1', $filename);
146 } 146 }
147 147
148 sort($this->tinstances); 148 sort($this->tinstances);
149 ksort($this->files); 149 ksort($this->files);
150 ksort($this->identifiers);
150 } 151 }
151 152
152 function get_filenames() { 153 function get_filenames() {
@@ -166,17 +167,6 @@ class Type_Default {
166 return $files; 167 return $files;
167 } 168 }
168 169
169 function file2identifier($files) {
170 foreach($files as $key => $file) {
171 if (is_file($file)) {
172 $files[$key] = preg_replace("#^$this->datadir/#u", '', $files[$key]);
173 $files[$key] = preg_replace('#\.rrd$#', '', $files[$key]);
174 }
175 }
176
177 return $files;
178 }
179
180 function rrd_graph($debug = false) { 170 function rrd_graph($debug = false) {
181 if (!$this->colors) 171 if (!$this->colors)
182 $this->rainbow_colors(); 172 $this->rainbow_colors();