diff options
-rw-r--r-- | conf/config.php | 5 | ||||
-rw-r--r-- | inc/collectd.inc.php | 99 | ||||
-rw-r--r-- | rrd.php | 2 | ||||
-rw-r--r-- | type/Default.class.php | 18 |
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 | ||
25 | function 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 |
23 | function collectd_plugindata($host, $plugin=NULL) { | 43 | function 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 | ||
238 | function 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) |
219 | function collectd_flush($identifier) { | 261 | function 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 | ?> |
@@ -4,7 +4,7 @@ require_once 'conf/common.inc.php'; | |||
4 | require_once 'inc/functions.inc.php'; | 4 | require_once 'inc/functions.inc.php'; |
5 | require_once 'inc/html.inc.php'; | 5 | require_once 'inc/html.inc.php'; |
6 | 6 | ||
7 | if ($file = validateRRDPath($CONFIG['datadir'], $_SERVER['PATH_INFO'])) { | 7 | if ( $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(); |