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(); |
