From: Sebastian Harl Date: Sat, 7 Mar 2009 17:03:42 +0000 (+0100) Subject: Merge branch 'sh/collectd-4.5' into sh/collectd-4.6 X-Git-Tag: collectd-4.6.2~5 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=6d86a97190a193863aadc252f20f6b9dba61c263;hp=49cf50f058fc3a7322899b4eca4223dd71bc605a;p=collectd.git Merge branch 'sh/collectd-4.5' into sh/collectd-4.6 Conflicts: contrib/collection3/lib/Collectd/Graph/Common.pm src/postgresql_default.conf --- diff --git a/README b/README index a6a53544..b6417411 100644 --- a/README +++ b/README @@ -541,12 +541,24 @@ Crosscompiling that the compiled binary actually behaves as it should, but since NANs are likely never passed to the libm you have a good chance to be lucky. + Likewise, collectd needs to know the layout of doubles in memory, in order + to craft uniform network packets over different architectures. For this, it + needs to know how to convert doubles into the memory layout used by x86. The + configure script tries to figure this out by compiling and running a few + small test programs. This is of course not possible when cross-compiling. + You can use the `--with-fp-layout' option to tell the configure script which + conversion method to assume. Valid arguments are: + + * `nothing' (12345678 -> 12345678) + * `endianflip' (12345678 -> 87654321) + * `intswap' (12345678 -> 56781234) + Contact ------- - For questions, bugreports, development information and basically all other - concerns please send an email to collectd's mailinglist at + For questions, bug reports, development information and basically all other + concerns please send an email to collectd's mailing list at . For live discussion and more personal contact visit us in IRC, we're in @@ -560,5 +572,6 @@ Author Sebastian tokkee Harl , and many contributors (see `AUTHORS'). - Please send bugreports and patches to the mailinglist, see `Contact' above. + Please send bug reports and patches to the mailing list, see `Contact' + above. diff --git a/contrib/collection3/bin/.htaccess b/contrib/collection3/bin/.htaccess new file mode 100644 index 00000000..1695f503 --- /dev/null +++ b/contrib/collection3/bin/.htaccess @@ -0,0 +1,2 @@ +Options +ExecCGI +AddHandler cgi-script .cgi diff --git a/contrib/collection3/etc/collection.conf b/contrib/collection3/etc/collection.conf index cc13b4c3..b7e76b2b 100644 --- a/contrib/collection3/etc/collection.conf +++ b/contrib/collection3/etc/collection.conf @@ -1,3 +1,4 @@ +#DataDir "/var/lib/collectd/rrd" GraphWidth 400 #UnixSockAddr "/var/run/collectd-unixsock" diff --git a/contrib/collection3/lib/Collectd/Graph/Common.pm b/contrib/collection3/lib/Collectd/Graph/Common.pm index fd1f7b72..0deefd63 100644 --- a/contrib/collection3/lib/Collectd/Graph/Common.pm +++ b/contrib/collection3/lib/Collectd/Graph/Common.pm @@ -5,11 +5,11 @@ use warnings; use vars (qw($ColorCanvas $ColorFullBlue $ColorHalfBlue)); -use Collectd::Unixsock; - +use Collectd::Unixsock (); use Carp (qw(confess cluck)); use CGI (':cgi'); use Exporter; +use Collectd::Graph::Config (qw(gc_get_scalar)); $ColorCanvas = 'FFFFFF'; $ColorFullBlue = '0000FF'; @@ -43,7 +43,7 @@ $ColorHalfBlue = 'B7B7F7'; flush_files )); -our $DataDir = '/var/lib/collectd/rrd'; +our $DefaultDataDir = '/var/lib/collectd/rrd'; return (1); @@ -146,6 +146,7 @@ sub filename_to_ident sub ident_to_filename { my $ident = shift; + my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir); my $ret = ''; @@ -155,7 +156,7 @@ sub ident_to_filename } else { - $ret .= "$DataDir/"; + $ret .= "$data_dir/"; } if (!$ident->{'hostname'}) @@ -257,12 +258,13 @@ sub get_all_hosts { my $dh; my @ret = (); + my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir); - opendir ($dh, "$DataDir") or confess ("opendir ($DataDir): $!"); + opendir ($dh, "$data_dir") or confess ("opendir ($data_dir): $!"); while (my $entry = readdir ($dh)) { next if ($entry =~ m/^\./); - next if (!-d "$DataDir/$entry"); + next if (!-d "$data_dir/$entry"); push (@ret, sanitize_hostname ($entry)); } closedir ($dh); @@ -286,6 +288,7 @@ sub get_all_plugins my @hosts = @_; my $ret = {}; my $dh; + my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir); if (!@hosts) { @@ -295,14 +298,14 @@ sub get_all_plugins for (@hosts) { my $host = $_; - opendir ($dh, "$DataDir/$host") or next; + opendir ($dh, "$data_dir/$host") or next; while (my $entry = readdir ($dh)) { my $plugin; my $plugin_instance = ''; next if ($entry =~ m/^\./); - next if (!-d "$DataDir/$host/$entry"); + next if (!-d "$data_dir/$host/$entry"); if ($entry =~ m#^([^-]+)-(.+)$#) { @@ -338,7 +341,8 @@ sub get_all_plugins sub get_files_for_host { my $host = sanitize_hostname (shift); - return (get_files_from_directory ("$DataDir/$host", 2)); + my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir); + return (get_files_from_directory ("$data_dir/$host", 2)); } # get_files_for_host sub _filter_ident @@ -384,6 +388,7 @@ sub get_files_by_ident my $ident = shift; my $all_files; my @ret = (); + my $data_dir = gc_get_scalar ('DataDir', $DefaultDataDir); #if ($ident->{'hostname'}) #{ @@ -391,7 +396,7 @@ sub get_files_by_ident #} #else #{ - $all_files = get_files_from_directory ($DataDir, 3); + $all_files = get_files_from_directory ($data_dir, 3); #} @ret = grep { _filter_ident ($ident, $_) == 0 } (@$all_files); diff --git a/contrib/collection3/lib/Collectd/Graph/Config.pm b/contrib/collection3/lib/Collectd/Graph/Config.pm index d20be359..42582a7e 100644 --- a/contrib/collection3/lib/Collectd/Graph/Config.pm +++ b/contrib/collection3/lib/Collectd/Graph/Config.pm @@ -6,7 +6,7 @@ Collectd::Graph::Config - Parse the collection3 config file. =cut -# Copyright (C) 2008 Florian octo Forster +# Copyright (C) 2008,2009 Florian octo Forster # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software @@ -27,7 +27,6 @@ use warnings; use Carp (qw(cluck confess)); use Exporter (); use Config::General ('ParseConfig'); -use Collectd::Graph::Type (); @Collectd::Graph::Config::ISA = ('Exporter'); @Collectd::Graph::Config::EXPORT_OK = (qw(gc_read_config gc_get_config diff --git a/contrib/collection3/lib/Collectd/Graph/Type/Df.pm b/contrib/collection3/lib/Collectd/Graph/Type/Df.pm index b4eb8b1c..0fbd0d35 100644 --- a/contrib/collection3/lib/Collectd/Graph/Type/Df.pm +++ b/contrib/collection3/lib/Collectd/Graph/Type/Df.pm @@ -1,5 +1,20 @@ package Collectd::Graph::Type::Df; +# Copyright (C) 2008,2009 Florian octo Forster +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; only version 2 of the License is applicable. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + use strict; use warnings; use base ('Collectd::Graph::Type'); @@ -43,7 +58,7 @@ sub getRRDArgs my $faded_green = get_faded_color ('00ff00'); my $faded_red = get_faded_color ('ff0000'); - return (['-t', 'Free space (' . $ident->{'type_instance'} . ')', '-v', 'Bytes', '-l', '0', + return (['-t', 'Diskspace (' . $ident->{'type_instance'} . ')', '-v', 'Bytes', '-l', '0', "DEF:free_min=${filename}:free:MIN", "DEF:free_avg=${filename}:free:AVERAGE", "DEF:free_max=${filename}:free:MAX", diff --git a/contrib/collection3/lib/Collectd/Graph/Type/GenericIO.pm b/contrib/collection3/lib/Collectd/Graph/Type/GenericIO.pm index 58b7566e..7ed915ba 100644 --- a/contrib/collection3/lib/Collectd/Graph/Type/GenericIO.pm +++ b/contrib/collection3/lib/Collectd/Graph/Type/GenericIO.pm @@ -1,5 +1,20 @@ package Collectd::Graph::Type::GenericIO; +# Copyright (C) 2008,2009 Florian octo Forster +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; only version 2 of the License is applicable. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + use strict; use warnings; use base ('Collectd::Graph::Type'); @@ -92,20 +107,32 @@ sub getRRDArgs } push (@ret, + "CDEF:avg_rx_bytes=avg_rx,8,/", + "VDEF:global_min_rx=min_rx,MINIMUM", + "VDEF:global_avg_rx=avg_rx,AVERAGE", + "VDEF:global_max_rx=max_rx,MAXIMUM", + "VDEF:global_tot_rx=avg_rx_bytes,TOTAL", + "CDEF:avg_tx_bytes=avg_tx,8,/", + "VDEF:global_min_tx=min_tx,MINIMUM", + "VDEF:global_avg_tx=avg_tx,AVERAGE", + "VDEF:global_max_tx=max_tx,MAXIMUM", + "VDEF:global_tot_tx=avg_tx_bytes,TOTAL"); + + push (@ret, "CDEF:overlap=avg_rx,avg_tx,LT,avg_rx,avg_tx,IF", "AREA:avg_rx#${rx_color_bg}", "AREA:avg_tx#${tx_color_bg}", "AREA:overlap#${overlap_color}", "LINE1:avg_rx#${rx_color_fg}:${rx_ds_name}", - "GPRINT:min_rx:MIN:${format} Min,", - "GPRINT:avg_rx:AVERAGE:${format} Avg,", - "GPRINT:max_rx:MAX:${format} Max,", - "GPRINT:avg_rx:LAST:${format} Last\\l", + "GPRINT:global_min_rx:${format} Min,", + "GPRINT:global_avg_rx:${format} Avg,", + "GPRINT:global_max_rx:${format} Max,", + "GPRINT:global_tot_rx:ca. ${format} Total\\l", "LINE1:avg_tx#${tx_color_fg}:${tx_ds_name}", - "GPRINT:min_tx:MIN:${format} Min,", - "GPRINT:avg_tx:AVERAGE:${format} Avg,", - "GPRINT:max_tx:MAX:${format} Max,", - "GPRINT:avg_tx:LAST:${format} Last\\l"); + "GPRINT:global_min_tx:${format} Min,", + "GPRINT:global_avg_tx:${format} Avg,", + "GPRINT:global_max_tx:${format} Max,", + "GPRINT:global_tot_tx:ca. ${format} Total\\l"); return (\@ret); } # getRRDArgs diff --git a/contrib/collection3/lib/Collectd/Graph/Type/GenericStacked.pm b/contrib/collection3/lib/Collectd/Graph/Type/GenericStacked.pm index a1a3e1cd..36c900a2 100644 --- a/contrib/collection3/lib/Collectd/Graph/Type/GenericStacked.pm +++ b/contrib/collection3/lib/Collectd/Graph/Type/GenericStacked.pm @@ -1,5 +1,20 @@ package Collectd::Graph::Type::GenericStacked; +# Copyright (C) 2008,2009 Florian octo Forster +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; only version 2 of the License is applicable. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + use strict; use warnings; use base ('Collectd::Graph::Type'); @@ -49,6 +64,19 @@ sub getRRDArgs my $colors = $obj->{'rrd_colors'} || {}; my @ret = ('-t', $rrd_title, @$rrd_opts); + my $ignore_unknown = $obj->{'ignore_unknown'} || 0; + if ($ignore_unknown) + { + if ($ignore_unknown =~ m/^(yes|true|on)$/i) + { + $ignore_unknown = 1; + } + else + { + $ignore_unknown = 0; + } + } + if (defined $obj->{'rrd_vertical'}) { push (@ret, '-v', $obj->{'rrd_vertical'}); @@ -59,6 +87,23 @@ sub getRRDArgs sort_idents_by_type_instance ($idents, $obj->{'custom_order'}); } + if ($ignore_unknown) + { + my $new_idents = []; + for (@$idents) + { + if (exists ($obj->{'ds_names'}{$_->{'type_instance'}})) + { + push (@$new_idents, $_); + } + } + + if (@$new_idents) + { + $idents = $new_idents; + } + } + $obj->{'ds_names'} ||= {}; my @names = map { $obj->{'ds_names'}{$_->{'type_instance'}} || $_->{'type_instance'} } (@$idents); @@ -86,13 +131,13 @@ sub getRRDArgs if ($i == (@$idents - 1)) { push (@ret, - "CDEF:cdef${i}=avg${i}"); + "CDEF:cdef${i}=avg${i},UN,0,avg${i},IF"); } else { my $j = $i + 1; push (@ret, - "CDEF:cdef${i}=cdef${j},avg${i},+"); + "CDEF:cdef${i}=avg${i},UN,0,avg${i},IF,cdef${j},+"); } } diff --git a/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm b/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm index c5fe613f..a9e85f57 100644 --- a/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm +++ b/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm @@ -6,7 +6,7 @@ Collectd::Graph::TypeLoader - Load a module according to the "type" =cut -# Copyright (C) 2008 Florian octo Forster +# Copyright (C) 2008,2009 Florian octo Forster # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software @@ -34,7 +34,7 @@ use Collectd::Graph::Type (); @Collectd::Graph::TypeLoader::EXPORT_OK = ('tl_load_type'); our @ArrayMembers = (qw(data_sources rrd_opts custom_order)); -our @ScalarMembers = (qw(rrd_title rrd_format rrd_vertical scale)); +our @ScalarMembers = (qw(rrd_title rrd_format rrd_vertical scale ignore_unknown)); our @DSMappedMembers = (qw(ds_names rrd_colors)); our %MemberToConfigMap = @@ -47,7 +47,8 @@ our %MemberToConfigMap = rrd_vertical => 'rrdverticallabel', rrd_colors => 'color', scale => 'scale', # GenericIO only - custom_order => 'order' # GenericStacked only + custom_order => 'order', # GenericStacked only + ignore_unknown => 'ignoreunknown' # GenericStacked only ); return (1); @@ -57,8 +58,8 @@ sub _create_object my $module = shift; my $obj; - local $SIG{__WARN__} = sub {}; - local $SIG{__DIE__} = sub {}; + local $SIG{__WARN__} = sub { print STDERR "WARNING: " . join (', ', @_) . "\n"; }; + local $SIG{__DIE__} = sub { print STDERR "FATAL: " . join (', ', @_) . "\n"; }; eval <{'script'} = $script; - push (@$Scripts, $opts); + if (ref ($opts) eq 'ARRAY') + { + for (@$opts) + { + my $opt = $_; + $opt->{'script'} = $script; + push (@$Scripts, $opt); + } + } + else + { + $opts->{'script'} = $script; + push (@$Scripts, $opts); + } } } # for (keys %$scripts) } # handle_config_script diff --git a/contrib/php-collection/browser.js b/contrib/php-collection/browser.js index 6f4d8ec8..a343cba8 100644 --- a/contrib/php-collection/browser.js +++ b/contrib/php-collection/browser.js @@ -496,17 +496,93 @@ function GraphMoveDown(graph) { } } -function GraphListFromCookie() { +function GraphListFromCookie(lname) { if (document.cookie.length > 0) { - cookies = document.cookie.split('; '); + var cname= 'graphLst'+lname+'='; + var cookies = document.cookie.split('; '); for (i = 0; i < cookies.length; i++) - if (cookies[i].substring(0, 9) == 'graphLst=') - return cookies[i].substring(9).split('/'); + if (cookies[i].substring(0, cname.length) == cname) + return cookies[i].substring(cname.length).split('/'); } return new Array(); } +function GraphListNameSort(a, b) { + if (a[0] > b[0]) + return 1 + else if (a[0] < b[0]) + return -1; + else + return 0; +} + +function GraphListRefresh() { + var select = document.getElementById('GraphList'); + var childCnt = select.childNodes.length; + var oldValue = select.selectedIndex > 0 ? select.options[select.selectedIndex].value : '/'; + while (childCnt > 0) + select.removeChild(select.childNodes[--childCnt]); + + // Determine available names + var options = new Array(); + if (document.cookie.length > 0) { + var cookies = document.cookie.split('; '); + for (i = 0; i < cookies.length; i++) + if (cookies[i].substring(0, 8) == 'graphLst') { + var p = cookies[i].indexOf('='); + if (p < 0) + continue; + options.push(new Array(cookies[i].substring(8, p), cookies[i].substring(p+1).split('/').length)); + } + } + options.sort(GraphListNameSort); + + var optCnt = options ? options.length : 0; + if (optCnt == 0) { + select.setAttribute('disabled', 'disabled'); + return -1; + } else { + select.removeAttribute('disabled'); + for (i = 0; i < optCnt; i++) { + newOption = document.createElement("option"); + newOption.value = options[i][0]; + if (newOption.value == oldValue) + newOption.setAttribute('selected', 'selected'); + if (options[i][1] == 1) + newOption.appendChild(document.createTextNode(newOption.value+' (1 graph)')); + else + newOption.appendChild(document.createTextNode(newOption.value+' ('+options[i][1]+' graphs)')); + select.appendChild(newOption); + } + return select.selectedIndex; + } +} + +function GraphListCheckName(doalert) { + var lname = document.getElementById('GraphListName'); + if (lname) { + if (lname.value.match(/^[a-zA-Z0-9_-]+$/)) { + lname.style.backgroundColor = ''; + return lname.value; + } else { + lname.style.backgroundColor = '#ffdddd'; + if (doalert && lname.value.length == 0) + alert('Graph list name is empty.\n\n'+ + 'Please fill in a name and try again.'); + else if (doalert) + alert('Graph list name contains non-permitted character.\n\n'+ + 'Only anlphanumerical characters (a-z, A-Z, 0-9), hyphen (-) and underscore (_) are permitted.\n'+ + 'Please correct and try again.'); + lname.focus(); + } + } + return ''; +} + function GraphSave() { + var lstName = GraphListCheckName(true); + if (lstName.length == 0) + return; if (graphList.length > 0) { // Save graph list to cookie var str = ''; @@ -517,20 +593,37 @@ function GraphSave() { str += graphList[i].substring(g+1); } - document.cookie = 'graphLst='+str; - if (GraphListFromCookie().length == 0) - alert("Failed to save graph list to cookie."); + document.cookie = 'graphLst'+lstName+'='+str; + if (GraphListFromCookie(lstName).length == 0) + alert("Failed to save graph list '"+lstName+"' to cookie."); else alert("Successfully saved current graph list."); } else { - document.cookie = 'graphLst=; expires='+new Date().toGMTString(); + document.cookie = 'graphLst'+lstName+'=; expires='+new Date().toGMTString(); alert("Cleared saved graph list."); } + GraphListRefresh(); +} + +function GraphDrop() { + var cname = document.getElementById('GraphList'); + if (cname && cname.selectedIndex >= 0) { + cname = cname.options[cname.selectedIndex].value; + document.cookie = 'graphLst'+cname+'=; expires='+new Date().toGMTString(); + GraphListRefresh(); + } else + return; } function GraphLoad() { + var cname = document.getElementById('GraphList'); + if (cname && cname.selectedIndex >= 0) + cname = cname.options[cname.selectedIndex].value; + else + return; // Load graph list from cookie - var grLst = GraphListFromCookie(); + var grLst = GraphListFromCookie(cname); + var oldLength = graphList.length; for (i = 0; i < grLst.length; i++) { var host = ''; var plugin = ''; @@ -571,8 +664,8 @@ function GraphLoad() { GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic); } if (grLst.length == 0) - alert("No list found for loading."); - else if (grLst.length != graphList.length) + alert("No list '"+cname+"' found for loading."); + else if (grLst.length + oldLength != graphList.length) alert("Could not load all graphs, probably damaged cookie."); } diff --git a/contrib/php-collection/definitions.php b/contrib/php-collection/definitions.php index 16dd2e6e..cb3e803e 100644 --- a/contrib/php-collection/definitions.php +++ b/contrib/php-collection/definitions.php @@ -1575,6 +1575,19 @@ function load_graph_definitions($logarithmic = false, $tinylegend = false) { $MetaGraphDefs['apache_scoreboard'] = 'meta_graph_apache_scoreboard'; $MetaGraphDefs['mysql_commands'] = 'meta_graph_mysql_commands'; $MetaGraphDefs['mysql_handler'] = 'meta_graph_mysql_commands'; + $MetaGraphDefs['tcp_connections'] = 'meta_graph_tcp_connections'; + $MetaGraphDefs['dns_opcode'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_qtype'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_rcode'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_request'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_resolver'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_update'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_zops'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_response'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_query'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_reject'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_notify'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_transfer'] = 'meta_graph_dns_event'; if (function_exists('load_graph_definitions_local')) load_graph_definitions_local($logarithmic, $tinylegend); @@ -1705,13 +1718,20 @@ function meta_graph_memory($host, $plugin, $plugin_instance, $type, $type_instan $files = array(); $opts['colors'] = array( + // Linux - System memoery 'free' => '00e000', 'cached' => '0000ff', 'buffered' => 'ffb000', - 'used' => 'ff0000' + 'used' => 'ff0000', + // Bind - Server memory + 'TotalUse' => '00e000', + 'InUse' => 'ff0000', + 'BlockSize' => '8888dd', + 'ContextSize' => '444499', + 'Lost' => '222222' ); - $type_instances = array('free', 'cached', 'buffered', 'used'); + $type_instances = array('free', 'cached', 'buffered', 'used', 'TotalUse', 'InUse', 'BlockSize', 'ContextSize', 'Lost'); while (list($k, $inst) = each($type_instances)) { $file = ''; foreach ($config['datadirs'] as $datadir) @@ -2030,10 +2050,40 @@ function meta_graph_tcp_connections($host, $plugin, $plugin_instance, $type, $ty if ($file == '') continue; - $sources[] = array('name'=>$inst, 'file'=>$file, 'ds'=>'count'); + $sources[] = array('name'=>$inst, 'file'=>$file, 'ds'=>'value'); } return collectd_draw_meta_stack($opts, $sources); } +function meta_graph_dns_event($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { + global $config; + $sources = array(); + + $title = "$host/$plugin".(!is_null($plugin_instance) ? "-$plugin_instance" : '')."/$type"; + if (!isset($opts['title'])) + $opts['title'] = $title; + $opts['rrd_opts'] = array('-v', 'Events', '-r', '-l', '0'); + + $files = array(); +// $opts['colors'] = array( +// ); + +// $type_instances = array('IQUERY', 'NOTIFY'); + while (list($k, $inst) = each($type_instances)) { + $file = ''; + $title = $opts['title']; + foreach ($config['datadirs'] as $datadir) + if (is_file($datadir.'/'.$title.'-'.$inst.'.rrd')) { + $file = $datadir.'/'.$title.'-'.$inst.'.rrd'; + break; + } + if ($file == '') + continue; + + $sources[] = array('name'=>$inst, 'file'=>$file); + } + return collectd_draw_meta_stack($opts, $sources); +} + ?> diff --git a/contrib/php-collection/functions.php b/contrib/php-collection/functions.php index 9fb6116f..f555751a 100644 --- a/contrib/php-collection/functions.php +++ b/contrib/php-collection/functions.php @@ -260,17 +260,6 @@ function collectd_flush($identifier) { if (is_null($identifier) || (is_array($identifier) && count($identifier) == 0) || !(is_string($identifier) || is_array($identifier))) return false; - if (is_null($host) || !is_string($host) || strlen($host) == 0) - return false; - if (is_null($plugin) || !is_string($plugin) || strlen($plugin) == 0) - return false; - if (is_null($pinst) || !is_string($pinst)) - return false; - if (is_null($type) || !is_string($type) || strlen($type) == 0) - return false; - if (is_null($tinst) || (is_array($tinst) && count($tinst) == 0) || !(is_string($tinst) || is_array($tinst))) - return false; - $u_errno = 0; $u_errmsg = ''; if ($socket = @fsockopen($config['collectd_sock'], 0, $u_errno, $u_errmsg)) { @@ -385,6 +374,10 @@ function rrd_strip_quotes($str) { return $str; } +function rrd_escape($str) { + return str_replace(array('\\', ':'), array('\\\\', '\\:'), $str); +} + /** * Determine useful information about RRD file * @file Name of RRD file to analyse @@ -506,11 +499,11 @@ function collectd_draw_rrd($host, $plugin, $pinst = null, $type, $tinst = null, if (strlen($k) > $l_max) $l_max = strlen($k); if ($has_min) - $graph[] = sprintf('DEF:%s_min=%s:%s:MIN', $k, $rrdinfo['filename'], $k); + $graph[] = sprintf('DEF:%s_min=%s:%s:MIN', $k, rrd_escape($rrdinfo['filename']), $k); if ($has_avg) - $graph[] = sprintf('DEF:%s_avg=%s:%s:AVERAGE', $k, $rrdinfo['filename'], $k); + $graph[] = sprintf('DEF:%s_avg=%s:%s:AVERAGE', $k, rrd_escape($rrdinfo['filename']), $k); if ($has_max) - $graph[] = sprintf('DEF:%s_max=%s:%s:MAX', $k, $rrdinfo['filename'], $k); + $graph[] = sprintf('DEF:%s_max=%s:%s:MAX', $k, rrd_escape($rrdinfo['filename']), $k); } if ($has_min && $has_max || $has_min && $has_avg || $has_avg && $has_max) { $n = 1; @@ -582,7 +575,7 @@ function collectd_draw_generic($timespan, $host, $plugin, $pinst = null, $type, continue; $file = str_replace(":", "\\:", $file); - $rrd_args = str_replace('{file}', $file, $rrd_args); + $rrd_args = str_replace('{file}', rrd_escape($file), $rrd_args); $rrdgraph = array_merge($rrd_cmd, $rrd_args); $cmd = RRDTOOL; @@ -623,7 +616,7 @@ function collectd_draw_meta_stack(&$opts, &$sources) { $max_inst_name = 0; foreach($sources as &$inst_data) { - $inst_name = $inst_data['name']; + $inst_name = str_replace('!', '_', $inst_data['name']); $file = $inst_data['file']; $ds = isset($inst_data['ds']) ? $inst_data['ds'] : 'value'; @@ -633,9 +626,9 @@ function collectd_draw_meta_stack(&$opts, &$sources) { if (!is_file($file)) continue; - $cmd[] = 'DEF:'.$inst_name.'_min='.$file.':'.$ds.':MIN'; - $cmd[] = 'DEF:'.$inst_name.'_avg='.$file.':'.$ds.':AVERAGE'; - $cmd[] = 'DEF:'.$inst_name.'_max='.$file.':'.$ds.':MAX'; + $cmd[] = 'DEF:'.$inst_name.'_min='.rrd_escape($file).':'.$ds.':MIN'; + $cmd[] = 'DEF:'.$inst_name.'_avg='.rrd_escape($file).':'.$ds.':AVERAGE'; + $cmd[] = 'DEF:'.$inst_name.'_max='.rrd_escape($file).':'.$ds.':MAX'; $cmd[] = 'CDEF:'.$inst_name.'_nnl='.$inst_name.'_avg,UN,0,'.$inst_name.'_avg,IF'; } $inst_data = end($sources); @@ -644,16 +637,16 @@ function collectd_draw_meta_stack(&$opts, &$sources) { $inst_data1 = end($sources); while (($inst_data0 = prev($sources)) !== false) { - $inst_name0 = $inst_data0['name']; - $inst_name1 = $inst_data1['name']; + $inst_name0 = str_replace('!', '_', $inst_data0['name']); + $inst_name1 = str_replace('!', '_', $inst_data1['name']); $cmd[] = 'CDEF:'.$inst_name0.'_stk='.$inst_name0.'_nnl,'.$inst_name1.'_stk,+'; $inst_data1 = $inst_data0; } foreach($sources as &$inst_data) { - $inst_name = $inst_data['name']; - $legend = sprintf('%s', $inst_name); + $inst_name = str_replace('!', '_', $inst_data['name']); + $legend = sprintf('%s', $inst_data['name']); while (strlen($legend) < $max_inst_name) $legend .= ' '; $number_format = isset($opts['number_format']) ? $opts['number_format'] : '%6.1lf'; @@ -710,7 +703,7 @@ function collectd_draw_meta_line(&$opts, &$sources) { $max_inst_name = 0; foreach ($sources as &$inst_data) { - $inst_name = $inst_data['name']; + $inst_name = str_replace('!', '_', $inst_data['name']); $file = $inst_data['file']; $ds = isset($inst_data['ds']) ? $inst_data['ds'] : 'value'; @@ -720,13 +713,13 @@ function collectd_draw_meta_line(&$opts, &$sources) { if (!is_file($file)) continue; - $cmd[] = 'DEF:'.$inst_name.'_min='.$file.':'.$ds.':MIN'; - $cmd[] = 'DEF:'.$inst_name.'_avg='.$file.':'.$ds.':AVERAGE'; - $cmd[] = 'DEF:'.$inst_name.'_max='.$file.':'.$ds.':MAX'; + $cmd[] = 'DEF:'.$inst_name.'_min='.rrd_escape($file).':'.$ds.':MIN'; + $cmd[] = 'DEF:'.$inst_name.'_avg='.rrd_escape($file).':'.$ds.':AVERAGE'; + $cmd[] = 'DEF:'.$inst_name.'_max='.rrd_escape($file).':'.$ds.':MAX'; } foreach ($sources as &$inst_data) { - $inst_name = $inst_data['name']; + $inst_name = str_replace('!', '_', $inst_data['name']); $legend = sprintf('%s', $inst_name); while (strlen($legend) < $max_inst_name) $legend .= ' '; diff --git a/contrib/php-collection/graph.php b/contrib/php-collection/graph.php index e5365768..17749e06 100644 --- a/contrib/php-collection/graph.php +++ b/contrib/php-collection/graph.php @@ -112,6 +112,13 @@ function error400($title, $msg) { return error(400, "Bad request", $title, $msg); } +/** + * Incomplete / invalid request + */ +function error500($title, $msg) { + return error(500, "Internal error", $title, $msg); +} + // Process input arguments $host = read_var('host', $_GET, null); if (is_null($host)) diff --git a/contrib/php-collection/index.php b/contrib/php-collection/index.php index 1f788fc9..1abf40d5 100644 --- a/contrib/php-collection/index.php +++ b/contrib/php-collection/index.php @@ -90,7 +90,7 @@ var graph_url = ''; -
+

Collectd browser for system statistics graphs

Hide graph selection tool
@@ -137,9 +137,18 @@ var graph_url = ''; + + + + + + + + + +
- - -
Graph list favorites:S
LD
diff --git a/src/postgresql_default.conf b/src/postgresql_default.conf index d289ded5..83a32c77 100644 --- a/src/postgresql_default.conf +++ b/src/postgresql_default.conf @@ -141,14 +141,14 @@ - Statement "SELECT sum(heap_blks_read) AS heap_read, \ - sum(heap_blks_hit) AS heap_hit, \ - sum(idx_blks_read) AS idx_read, \ - sum(idx_blks_hit) AS idx_hit, \ - sum(toast_blks_read) AS toast_read, \ - sum(toast_blks_hit) AS toast_hit, \ - sum(tidx_blks_read) AS tidx_read, \ - sum(tidx_blks_hit) AS tidx_hit \ + Statement "SELECT coalesce(sum(heap_blks_read), 0) AS heap_read, \ + coalesce(sum(heap_blks_hit), 0) AS heap_hit, \ + coalesce(sum(idx_blks_read), 0) AS idx_read, \ + coalesce(sum(idx_blks_hit), 0) AS idx_hit, \ + coalesce(sum(toast_blks_read), 0) AS toast_read, \ + coalesce(sum(toast_blks_hit), 0) AS toast_hit, \ + coalesce(sum(tidx_blks_read), 0) AS tidx_read, \ + coalesce(sum(tidx_blks_hit), 0) AS tidx_hit \ FROM pg_statio_user_tables;" diff --git a/src/rrdtool.c b/src/rrdtool.c index debb7bd4..b80e1109 100644 --- a/src/rrdtool.c +++ b/src/rrdtool.c @@ -279,6 +279,7 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data) rrd_cache_t *cache_entry; char **values; int values_num; + int status; int i; pthread_mutex_lock (&queue_lock); @@ -286,7 +287,6 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data) while (true) { struct timespec ts_wait; - int status; while ((flushq_head == NULL) && (queue_head == NULL) && (do_shutdown == 0)) @@ -361,17 +361,28 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data) * we make a copy of it's values */ pthread_mutex_lock (&cache_lock); - c_avl_get (cache, queue_entry->filename, (void *) &cache_entry); + status = c_avl_get (cache, queue_entry->filename, + (void *) &cache_entry); - values = cache_entry->values; - values_num = cache_entry->values_num; + if (status == 0) + { + values = cache_entry->values; + values_num = cache_entry->values_num; - cache_entry->values = NULL; - cache_entry->values_num = 0; - cache_entry->flags = FLAG_NONE; + cache_entry->values = NULL; + cache_entry->values_num = 0; + cache_entry->flags = FLAG_NONE; + } pthread_mutex_unlock (&cache_lock); + if (status != 0) + { + sfree (queue_entry->filename); + sfree (queue_entry); + continue; + } + /* Update `tv_next_update' */ if (write_rate > 0.0) { @@ -625,6 +636,15 @@ static int rrd_cache_insert (const char *filename, pthread_mutex_lock (&cache_lock); + /* This shouldn't happen, but it did happen at least once, so we'll be + * careful. */ + if (cache == NULL) + { + pthread_mutex_unlock (&cache_lock); + WARNING ("rrdtool plugin: cache == NULL."); + return (-1); + } + c_avl_get (cache, filename, (void *) &rc); if (rc == NULL) diff --git a/src/snmp.c b/src/snmp.c index 998c4b64..352075f2 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -696,6 +696,7 @@ static void csnmp_host_open_session (host_definition_t *host) } } /* void csnmp_host_open_session */ +/* TODO: Check if negative values wrap around. Problem: negative temperatures. */ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, double scale, double shift) { diff --git a/src/utils_avltree.c b/src/utils_avltree.c index 9f0b7968..3e258e95 100644 --- a/src/utils_avltree.c +++ b/src/utils_avltree.c @@ -581,6 +581,8 @@ int c_avl_get (c_avl_tree_t *t, const void *key, void **value) { c_avl_node_t *n; + assert (t != NULL); + n = search (t, key); if (n == NULL) return (-1);