Changeset 1293
- Timestamp:
- 08/28/07 00:01:07 (4 years ago)
- Files:
-
- people/jo/multilevel-groups/server/Munin.pm.in (modified) (11 diffs)
- people/jo/multilevel-groups/server/munin-graph.in (modified) (13 diffs)
- people/jo/multilevel-groups/server/munin-update.in (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
people/jo/multilevel-groups/server/Munin.pm.in
r1292 r1293 94 94 "version", "tls_certificate", "tls_private_key", "tls_pem", 95 95 "tls_verify_certificate", "tls_verify_depth", "graph_data_size", 96 "colour", "graph_printf", "ok", "unknown", "realservname" 96 "colour", "graph_printf", "ok", "unknown", "realservname", "cdef_name", 97 "graphable", "process", "realname" 97 98 ); 98 99 … … 100 101 101 102 # Fields to copy when "aliasing" a field 102 my @ copy_fields= ("label", "draw", "type", "rrdfile", "fieldname", "info");103 my @COPY_FIELDS = ("label", "draw", "type", "rrdfile", "fieldname", "info"); 103 104 104 105 … … 121 122 } 122 123 124 # munin_draw_field: Check whether a field will be visible in the graph or not 125 # Parameters: 126 # - $hash: A ref to the hash node for the field 127 # Returns: 128 # - Success: Boolean; true if field will be graphed, false if not 129 # - Failure: undef 123 130 sub munin_draw_field { 124 my $node = shift; 125 my $service = shift; 126 my $field = shift; 127 128 $field =~ s/=.*//; 129 130 print "DEBUG: munin_draw_field: Checking $service -> $field: " . &munin_get_bool_val ($node->{client}->{$service}->{$field.".graph"}, 1) . ".\n" if $DEBUG;; 131 return 0 if (exists $node->{client}->{$service}->{$field.".skipdraw"}); 132 return (&munin_get_bool_val ($node->{client}->{$service}->{$field.".graph"}, 1)); 131 my $hash = shift; 132 133 return 0 if munin_get_bool ($hash, "skipdraw", 0); 134 return 0 if !munin_get_bool ($hash, "graph", 1); 135 return defined $hash->{"label"}; 133 136 } 134 137 … … 418 421 419 422 if (ref ($hash) eq "HASH") { 423 ::logger ("Debug: Searching for $field in " . join ('::', @{munin_get_node_loc ($hash)})); 420 424 foreach my $key (keys %{$hash}) { 421 425 next if $key =~ /^#%#/; … … 517 521 $hash = $hash->{$tmpvar}; 518 522 } 523 } 524 525 # munin_set_var: sets a variable in a hash 526 # Parameters: 527 # - $hash: A ref to the hash to set the variable in 528 # - $var: The name of the variable 529 # - $val: The value to set the variable to 530 # Returns: 531 # - Success: The $hash we were handed 532 # - Failure: undef 533 sub munin_set_var 534 { 535 my $hash = shift; 536 my $var = shift; 537 my $val = shift; 538 539 return munin_set_var_loc ($hash, [$var], $val); 519 540 } 520 541 … … 597 618 } 598 619 620 # munin_get_root_node: Get the root node of the hash tree 621 # Parameters: 622 # - $hash: A hash node to traverse up from 623 # Returns: 624 # - Success: A ref to the root hash node 625 # - Failure: undef 626 sub munin_get_root_node 627 { 628 my $hash = shift; 629 630 return undef if ref ($hash) ne "HASH"; 631 632 while (defined $hash->{'#%#parent'}) { 633 $hash = $hash->{'#%#parent'}; 634 } 635 636 return $hash; 637 } 638 599 639 sub munin_writeconfig_loop 600 640 { … … 608 648 } else { 609 649 next if !defined $pre and $key eq "version"; # Handled separately 650 next if !defined $hash->{$key} or !length $hash->{$key}; 610 651 (my $outstring = $hash->{$key}) =~ s/([^\\])#/$1\\#/g; 611 652 print "Writing: $path $outstring\n" if $DEBUG; … … 656 697 } 657 698 699 # munin_get_picture_filename: Get the full path+name of a picture file 700 # Parameters: 701 # - $hash: A ref to the service hash node 702 # - $scale: The scale (day, week, year, month) 703 # - $sum: [optional] Boolean value, whether it's a sum graph or not. 704 # Returns: 705 # - Success: The file name with full path 706 # - Failure: undef 658 707 sub munin_get_picture_filename { 659 my $config = shift; 660 my $domain = shift; 661 my $name = shift; 662 my $service = shift; 708 my $hash = shift; 663 709 my $scale = shift; 664 710 my $sum = shift; 665 my $dir = $config->{'htmldir'}; 711 my $loc = munin_get_node_loc ($hash); 712 my $ret = munin_get ($hash, 'htmldir'); 666 713 667 714 # Sanitise 668 $dir =~ s/[^\w_\/"'\[\]\(\)+=-]\./_/g; 669 $domain =~ s/[^\w_\/"'\[\]\(\)+=\.-]/_/g; 670 $name =~ s/[^\w_\/"'\[\]\(\)+=\.-]/_/g; 671 $service =~ s/[^\w_\/"'\[\]\(\)+=-]/_/g; 715 $ret =~ s/[^\w_\/"'\[\]\(\)+=-]\./_/g; 716 $hash =~ s/[^\w_\/"'\[\]\(\)+=-]/_/g; 672 717 $scale =~ s/[^\w_\/"'\[\]\(\)+=-]/_/g; 673 674 if (defined $sum and $sum) 675 { 676 return "$dir/$domain/$name-$service-$scale-sum.png"; 677 } 678 else 679 { 680 return "$dir/$domain/$name-$service-$scale.png"; 681 } 682 } 683 684 # munin_get_filename: Get rrd filename for a field 718 @$loc = map { s/\//_/g; $_ } @$loc; 719 @$loc = map { s/^\./_/g; $_ } @$loc; 720 721 my $plugin = pop @$loc or return undef; 722 my $node = pop @$loc or return undef; 723 724 if (@$loc) { # The rest is used as directory names... 725 $ret .= "/" . join ('/', @$loc); 726 } 727 728 if (defined $sum and $sum) { 729 return "$ret/$node-$plugin-$scale-sum.png"; 730 } else { 731 return "$ret/$node-$plugin-$scale-sum.png"; 732 } 733 } 734 735 # munin_path_to_loc: Returns a loc array from a path string 736 # Parameters: 737 # - $path: A path string 738 # Returns: 739 # - Success: A ref to an array with the loc 740 # - Failure: undef 741 sub munin_path_to_loc 742 { 743 my $path = shift; 744 745 my $result = undef; 746 747 if ($path =~ /^\s*([^:]+):(\S+)\s*$/) { 748 my ($leftstring, $rightstring) = ($1, $2); 749 750 my @leftarr = split (/;/, $leftstring); 751 my @rightarr = split (/\./, $rightstring); 752 $result = [@leftarr, @rightarr]; 753 } elsif ($path =~ /^\s*([^;:\.]+)\s*$/) { 754 $result = [$1]; 755 } elsif ($path =~ /^\s*(.+)\.([^\.:;]+)$/) { 756 my ($leftstring, $rightstring) = ($1, $2); 757 758 my @leftarr = split (/;/, $leftstring); 759 my @rightarr = split (/\./, $rightstring); 760 $result = [@leftarr, @rightarr]; 761 } elsif ($path =~ /^\s*(\S+)\s*$/) { 762 my @leftarr = split (/;/, $1); 763 $result = [@leftarr]; 764 } else { 765 ::logger ("Error: munin_path_to_loc: Malformatted variable path \"$path\"."); 766 } 767 768 if (!defined $result) { 769 ::logger ("Error: munin_path_to_loc: Failed converting \"$path\"."); 770 } 771 772 return $result; 773 } 774 775 776 # munin_get_filename: Get rrd filename for a field, without any 777 # bells or whistles. Used by munin-update to 778 # figure out which file to update. 685 779 # Parameters: 686 780 # - $hash: Ref to hash field … … 1012 1106 } 1013 1107 1108 # munin_get_max_label_length: Get the length of the longest labe in a graph 1109 # Parameters: 1110 # - $hash: the graph in question 1111 # - $order: A ref to an array of fields (graph_order) 1112 # Returns: 1113 # - Success: The length of the longest label in the graph 1114 # - Failure: undef 1014 1115 sub munin_get_max_label_length 1015 1116 { 1016 my $node = shift;1017 my $config = shift;1018 my $domain = shift;1019 my $host = shift;1020 1117 my $service = shift; 1021 1118 my $order = shift; 1022 1119 my $result = 0; 1120 my $tot = munin_get ($service, "graph_total"); 1023 1121 1024 1122 for my $field (@$order) { 1025 1123 my $path = undef; 1026 1124 (my $f = $field) =~ s/=.+//; 1027 next if (exists $node->{client}->{$service}->{$f.".process"} and 1028 $node->{client}->{$service}->{$f.".process"} ne "yes"); 1029 next if (exists $node->{client}->{$service}->{$f.".skipdraw"}); 1030 next unless (!exists $node->{client}->{$service}->{$f.".graph"} or 1031 $node->{client}->{$service}->{$f.".graph"} eq "yes"); 1032 if ($result < length ($node->{client}->{$service}->{$f.".label"} || $f)) { 1033 $result = length ($node->{client}->{$service}->{$f.".label"} || $f); 1034 } 1035 if (exists $node->{client}->{$service}->{graph_total} and 1036 length $node->{client}->{$service}->{graph_total} > $result) 1037 { 1038 $result = length $node->{client}->{$service}->{graph_total}; 1039 } 1125 next if (!munin_get_bool ($service->{$f}, "process", 1)); 1126 next if (munin_get_bool ($service->{$f}, "skipdraw", 0)); 1127 next if (!munin_get_bool ($service->{$f}, "graph", 1)); 1128 1129 my $len = length (munin_get ($service->{$f}, "label") || $f); 1130 1131 if ($result < $len) { 1132 $result = $len; 1133 } 1134 } 1135 if (defined $tot and length $tot > $result) { 1136 $result = length $tot; 1040 1137 } 1041 1138 return $result; 1042 1139 } 1043 1140 1141 # munin_get_field_order: Get the field order in a graph 1142 # Parameters: 1143 # - $hash: A hash ref to the service 1144 # Returns: 1145 # - Success: A ref to an array of the field names 1146 # - Failure: undef 1044 1147 sub munin_get_field_order 1045 1148 { 1046 my $node = shift; 1047 my $config = shift; 1048 my $domain = shift; 1049 my $host = shift; 1050 my $service = shift; 1149 my $hash = shift; 1051 1150 my $result = []; 1052 1151 1053 if ($node->{client}->{$service}->{graph_sources}) 1054 { 1055 foreach my $gs (split /\s+/, $node->{client}->{$service}->{'graph_sources'}) 1056 { 1152 return undef if !defined $hash or ref($hash) ne "HASH"; 1153 1154 my $order = munin_get ($hash, "graph_order"); 1155 1156 if (defined $hash->{graph_sources}) { 1157 foreach my $gs (split /\s+/, $hash->{'graph_sources'}) { 1057 1158 push (@$result, "-".$gs); 1058 1159 } 1059 1160 } 1060 if ($node->{client}->{$service}->{graph_order}) 1061 { 1062 push (@$result, split /\s+/, $node->{client}->{$service}->{'graph_order'}); 1161 if (defined $order) { 1162 push (@$result, split /\s+/, $order); 1063 1163 } 1064 1164 1065 for my $key (keys %{$node->{client}->{$service}}) 1066 { 1067 my ($client,$type)=""; 1068 ($client,$type) = split /\./,$key; 1069 if (defined $type and $type eq "label") 1070 { 1071 push @$result,$client if !grep /^\Q$client\E(?:=|$)/, @$result;; 1072 } 1165 for my $fieldnode (@{munin_find_field ($hash, "label")}) { 1166 my $fieldname = munin_get_node_name ($fieldnode); 1167 push @$result,$fieldname if !grep /^\Q$fieldname\E(?:=|$)/, @$result;; 1073 1168 } 1074 1169 … … 1076 1171 } 1077 1172 1173 # munin_get_rrd_filename: Get the name of the rrd file corresponding to a 1174 # field. Checks for lots of bells and whistles. 1175 # This function is the correct one to use when 1176 # figuring out where to fetch data from. 1177 # Parameters: 1178 # - $field: The hash object of the field 1179 # - $path: [optional] The path to the field (as given in graph_order/sum/stack/et al) 1180 # Returns: 1181 # - Success: A string with the filename of the rrd file 1182 # - Failure: undef 1078 1183 sub munin_get_rrd_filename { 1079 my $node = shift;1080 my $config = shift;1081 my $domain = shift;1082 my $name = shift;1083 my $service = shift;1084 1184 my $field = shift; 1085 1185 my $path = shift; 1086 my $result = "unknown"; 1087 1088 if ($node->{client}->{$service}->{$field.".filename"}) 1089 { 1090 $result = $node->{client}->{$service}->{$field.".filename"}; 1091 } 1092 elsif ($path) 1093 { 1094 if (!defined ($node->{client}->{$service}->{$field.".label"})) 1095 { 1096 print "DEBUG: Setting label: $field\n" if $DEBUG; 1097 $node->{client}->{$service}->{$field.".label"} = $field; 1098 } 1099 1100 if ($path =~ /^\s*([^:;]+)[:;]([^:]+):([^:\.]+)[:\.]([^:\.]+)\s*$/) 1101 { 1102 $result = munin_get_filename ($config, $1, $2, $3, $4); 1103 print "\nDEBUG1: Expanding $path...\n" if $DEBUG; 1104 if (! defined $node->{client}->{$service}->{$field."label"}) 1105 { 1106 for my $f (@copy_fields) 1107 { 1108 if (not exists $node->{client}->{$service}->{"$field.$f"} and 1109 exists $config->{'domain'}->{$1}->{'node'}->{$2}->{'client'}->{$3}->{"$4.$f"}) 1110 { 1111 $node->{client}->{$service}->{"$field.$f"} = $config->{'domain'}->{$1}->{'node'}->{$2}->{'client'}->{$3}->{"$4.$f"}; 1112 } 1113 } 1114 } 1115 } 1116 elsif ($path =~ /^\s*([^:]+):([^:\.]+)[:\.]([^:\.]+)\s*$/) 1117 { 1118 print "\nDEBUG2: Expanding $path...\n" if $DEBUG; 1119 $result = munin_get_filename ($config, $domain, $1, $2, $3); 1120 for my $f (@copy_fields) 1121 { 1122 if (not exists $node->{client}->{$service}->{"$field.$f"} and 1123 exists $config->{'domain'}->{$domain}->{'node'}->{$1}->{'client'}->{$2}->{"$3.$f"}) 1124 { 1125 print "DEBUG: Copying $f...\n" if $DEBUG; 1126 $node->{client}->{$service}->{"$field.$f"} = $config->{'domain'}->{$domain}->{'node'}->{$1}->{'client'}->{$2}->{"$3.$f"}; 1127 } 1128 } 1129 } 1130 elsif ($path =~ /^\s*([^:\.]+)[:\.]([^:\.]+)\s*$/) 1131 { 1132 print "\nDEBUG3: Expanding $path...\n" if $DEBUG; 1133 $result = munin_get_filename ($config, $domain, $name, $1, $2); 1134 for my $f (@copy_fields) 1135 { 1136 if (not exists $node->{client}->{$service}->{"$field.$f"} and 1137 exists $node->{client}->{$1}->{"$2.$f"}) 1138 { 1139 $node->{client}->{$service}->{"$field.$f"} = $node->{client}->{$1}->{"$2.$f"}; 1140 } 1141 } 1142 } 1143 elsif ($path =~ /^\s*([^:\.]+)\s*$/) 1144 { 1145 print "\nDEBUG4: Expanding $path...\n" if $DEBUG; 1146 $result = munin_get_filename ($config, $domain, $name, $service, $1); 1147 for my $f (@copy_fields) 1148 { 1149 if (not exists $node->{client}->{$service}->{"$field.$f"} and 1150 exists $node->{client}->{$service}->{"$1.$f"}) 1151 { 1152 $node->{client}->{$service}->{"$field.$f"} = $node->{client}->{$service}->{"$1.$f"}; 1153 } 1154 } 1155 } 1156 } 1157 else 1158 { 1159 print "\nDEBUG5: Doing path...\n" if $DEBUG; 1160 $result = munin_get_filename($config, $domain,$name,$service,$field); 1186 my $result = undef; 1187 my $name = munin_get_node_name ($field); 1188 1189 # If the field has a .filename setting, use it 1190 return $result if $result = munin_get ($field, "filename"); 1191 1192 # Handle custom paths (used in .sum, .stack, graph_order, et al) 1193 if (defined $path and length $path) { 1194 if (!munin_get ($field, "label")) { 1195 print "DEBUG: Setting label: $name\n" if $DEBUG; 1196 munin_set_var_loc ($field, ["label"], $name); 1197 } 1198 1199 my $sourcenode = munin_get_node (munin_get_root_node ($field), munin_path_to_loc ($path)); 1200 $result = munin_get_filename ($sourcenode); 1201 1202 for my $f (@COPY_FIELDS) { 1203 if (not exists $field->{$f} and exists $sourcenode->{$f}) { 1204 print "DEBUG: Copying $f...\n" if $DEBUG; 1205 munin_set_var_loc ($field, [$f], $sourcenode->{$f}); 1206 } 1207 } 1208 } else { 1209 $result = munin_get_filename ($field); 1161 1210 } 1162 1211 return $result; … … 1177 1226 return $dirname if (-e $dirname); 1178 1227 1179 (my $prev = $dirname) =~ s/\/[^\/]+$//; 1180 if (mkdir_p ($prev, $umask)) { 1228 1229 ::logger ("Notice: Created directory \"$dirname\"."); 1230 (my $prev = $dirname) =~ s/\/[^\/]+\/?$//; 1231 if (munin_mkdir_p ($prev, $umask)) { 1181 1232 if (mkdir ($dirname, $umask)) { 1182 1233 return $dirname; people/jo/multilevel-groups/server/munin-graph.in
r1214 r1293 30 30 use Getopt::Long; 31 31 use Time::HiRes; 32 use Data::Dumper qw(Dumper); 32 33 33 34 my $graph_time= Time::HiRes::time; … … 185 186 ); 186 187 187 for my $key ( keys %{$config->{domain}}) { 188 my $domain_time= Time::HiRes::time; 189 mkdir "$config->{htmldir}/$key",0777; 190 logger("Processing domain: $key"); 191 &process_domain($key); 192 $domain_time = sprintf ("%.2f",(Time::HiRes::time - $domain_time)); 193 logger("Processed domain: $key ($domain_time sec)"); 194 print STATS "GD|$key|$domain_time\n" unless $skip_stats; 195 } 196 188 # Make array of what is probably needed to graph 189 my $work_array = []; 190 if (@limit_hosts) { # Limit what to update if needed 191 foreach my $nodename (@limit_hosts) { 192 push @$work_array, map { @{munin_find_field ($_->{$nodename}, "graph_title")} } @{munin_find_field($config, $nodename)}; 193 } 194 } else { # ...else just search for all adresses to update 195 push @$work_array, @{munin_find_field($config, "graph_title")}; 196 } 197 198 199 for my $service (@$work_array) { 200 process_service ($service); 201 } 197 202 198 203 $graph_time = sprintf ("%.2f",(Time::HiRes::time - $graph_time)); … … 203 208 close $log; 204 209 205 sub process_domain {206 my ($domain) = @_;207 for my $key ( keys %{$config->{domain}->{$domain}->{node}}) {208 my $node_time= Time::HiRes::time;209 210 process_node($domain,$key ,$config->{domain}->{$domain}->{node}->{$key} );211 $node_time = sprintf ("%.2f",(Time::HiRes::time - $node_time));212 logger ("Processed node: $key ($node_time sec)");213 print STATS "GN|$domain|$key|$node_time\n" unless $skip_stats;214 215 }216 }217 218 210 sub get_title { 219 my $node = shift;220 211 my $service = shift; 221 212 my $scale = shift; 222 213 223 return ($node->{client}->{$service}->{'graph_title'}? 224 $node->{client}->{$service}->{'graph_title'}:$service) . 225 " - by $scale"; 214 return (munin_get ($service, "graph_title", $service) . " - by $scale"); 226 215 } 227 216 228 217 sub get_custom_graph_args 229 218 { 230 my $node = shift;231 219 my $service = shift; 232 220 my $result = []; 233 221 234 if ($node->{client}->{$service}->{graph_args}) { 235 push @$result, split /\s/,$node->{client}->{$service}->{graph_args}; 222 my $args = munin_get ($service, "graph_args"); 223 if (defined $args) { 224 push @$result, split /\s/,$args; 236 225 return $result; 237 } 238 else 239 { 226 } else { 240 227 return undef; 241 228 } … … 244 231 sub get_vlabel 245 232 { 246 my $node = shift;247 233 my $service = shift; 248 my $scale = shift; 249 250 if ($node->{client}->{$service}->{graph_vlabel}) { 251 (my $res = $node->{client}->{$service}->{graph_vlabel}) =~ s/\$\{graph_period\}/$scale/g; 252 return $res; 253 } 254 elsif ($node->{client}->{$service}->{graph_vtitle}) 255 { 256 return $node->{client}->{$service}->{graph_vtitle}; 257 } 258 return undef; 234 my $scale = munin_get ($service, "graph_period", "second"); 235 my $res = munin_get ($service, "graph_vlabel", munin_get ($service, "graph_vtitle")); 236 237 if (defined $res) { 238 $res =~ s/\$\{graph_period\}/$scale/g; 239 } 240 return $res; 259 241 } 260 242 261 243 sub should_scale 262 244 { 263 my $node = shift;264 245 my $service = shift; 265 266 if (defined $node->{client}->{$service}->{graph_scale}) 267 { 268 return &munin_get_bool_val ($node->{client}->{$service}->{graph_scale}, 1); 269 } 270 elsif (defined $node->{client}->{$service}->{graph_noscale}) 271 { 272 return ! &munin_get_bool_val ($node->{client}->{$service}->{graph_noscale}, 0); 273 } 274 275 return 1; 246 my $ret; 247 248 if (!defined ($ret = munin_get_bool ($service, "graph_scale"))) { 249 $ret = !munin_get_bool ($service, "graph_noscale", 0); 250 } 251 252 return $ret; 276 253 } 277 254 278 255 sub get_header { 279 my $node = shift;280 my $config = shift;281 my $domain = shift;282 my $host = shift;283 256 my $service = shift; 284 257 my $scale = shift; … … 288 261 289 262 # Picture filename 290 push @$result, &munin_get_picture_filename ($config, $domain, $host,$service, $scale, $sum||undef);263 push @$result, munin_get_picture_filename ($service, $scale, $sum||undef); 291 264 292 265 # Title 293 push @$result, ("--title", &get_title ($node,$service, $scale));266 push @$result, ("--title", get_title ($service, $scale)); 294 267 295 268 # When to start the graph … … 297 270 298 271 # Custom graph args, vlabel and graph title 299 if (defined ($tmp_field = &get_custom_graph_args ($node,$service))) {272 if (defined ($tmp_field = get_custom_graph_args ($service))) { 300 273 push (@$result, @{$tmp_field}); 301 274 } 302 if (defined ($tmp_field = &get_vlabel ($node, $service, munin_get ($config, "graph_period", "second", $domain, $host, $service)))) {275 if (defined ($tmp_field = get_vlabel ($service))) { 303 276 push @$result, ("--vertical-label", $tmp_field); 304 277 } 305 278 306 push @$result,"--height", &munin_get ($config, "graph_height", "175", $domain, $host, $service);307 push @$result,"--width", &munin_get ($config, "graph_width", "400", $domain, $host, $service);279 push @$result,"--height", munin_get ($service, "graph_height", "175"); 280 push @$result,"--width", munin_get ($service, "graph_width", "400"); 308 281 push @$result,"--imgformat", "PNG"; 309 282 push @$result,"--lazy" if ($force_lazy); 310 283 311 push (@$result, "--units-exponent", "0") 312 if (! &should_scale ($node, $service)); 284 push (@$result, "--units-exponent", "0") if (! should_scale ($service)); 313 285 314 286 return $result; … … 317 289 sub get_sum_command 318 290 { 319 my $node = shift;320 my $service = shift;321 291 my $field = shift; 322 292 323 if (defined $node->{client}->{$service}->{$field.".special_sum"}) 324 { 325 return $node->{client}->{$service}->{$field.".special_sum"}; 326 } 327 elsif (defined $node->{client}->{$service}->{$field.".sum"}) 328 { 329 return $node->{client}->{$service}->{$field.".sum"}; 330 } 331 332 return undef; 293 if (defined $field->{"special_sum"}) { # Deprecated 294 return $field->{"special_sum"}; 295 } 296 297 return munin_get ($field, "sum"); 333 298 } 334 299 335 300 sub get_stack_command 336 301 { 337 my $node = shift;338 my $service = shift;339 302 my $field = shift; 340 303 341 if (defined $node->{client}->{$service}->{$field.".special_stack"}) 342 { 343 return $node->{client}->{$service}->{$field.".special_stack"}; 344 } 345 elsif (defined $node->{client}->{$service}->{$field.".stack"}) 346 { 347 return $node->{client}->{$service}->{$field.".stack"}; 348 } 349 350 return undef; 304 if (defined $field->{"special_stack"}) { # Deprecated 305 return $field->{"special_stack"}; 306 } 307 308 return munin_get ($field, "stack"); 351 309 } 352 310 353 311 sub expand_specials 354 312 { 355 my $node = shift;356 my $config = shift;357 my $domain = shift;358 my $host = shift;359 313 my $service = shift; 360 314 my $preproc = shift; … … 366 320 for my $field (@$order) { # Search for 'specials'... 367 321 368 if ($field =~ /^-(.+)$/) 369 { 322 if ($field =~ /^-(.+)$/) { 370 323 $field = $1; 371 unless (defined $node->{client}->{$service}->{$field.".graph"} or 372 defined $node->{client}->{$service}->{$field.".skipdraw"}) 373 { 374 $node->{client}->{$service}->{$field.".graph"} = "no"; 375 } 324 munin_set_var_loc ($service, [$field, "graph"], "no"); 376 325 } 377 326 378 327 $fieldnum++; 379 328 my $tmp_field; 380 if (defined ($tmp_field = &get_stack_command ($node, $service, $field))) 381 { 329 if (defined ($tmp_field = &get_stack_command ($service->{$field}))) { 382 330 print "DEBUG: Doing special_stack...\n" if $DEBUG; 383 331 my @spc_stack = (); 384 foreach my $pre (split (/\s+/, $tmp_field)) 385 { 332 foreach my $pre (split (/\s+/, $tmp_field)) { 386 333 (my $name = $pre) =~ s/=.+//; 387 if (!@spc_stack) 388 { 389 $node->{client}->{$service}->{$name.".draw"} = $node->{client}->{$service}->{$field.".draw"}; 390 $node->{client}->{$service}->{$field.".process"} = "no"; 391 } 392 else 393 { 394 $node->{client}->{$service}->{$name.".draw"} = "STACK"; 334 if (!@spc_stack) { 335 munin_set_var_loc ($service->{$name}, ["draw"], munin_get ($service->{$field}, "draw")); 336 munin_set_var_loc ($service->{$field}, ["process"], "no"); 337 } else { 338 munin_set_var_loc ($service->{$name}, ["draw"], "STACK"); 395 339 } 396 340 push (@spc_stack, $name); … … 400 344 push @$result, "$name.cdef"; 401 345 402 $node->{client}->{$service}->{$name.".label"} = $name; 403 $node->{client}->{$service}->{$name.".cdef"} = "$name,UN,0,$name,IF"; 404 if (exists $node->{client}->{$service}->{$field.".cdef"} and !exists $node->{client}->{$service}->{$name.".onlynullcdef"}) 405 { 346 munin_set_var_loc ($service->{$name}, ["label"], $name); 347 munin_set_var_loc ($service->{$name}, ["cdef"], "$name,UN,0,$name,IF"); 348 if (munin_get ($service->{$field}, "cdef") and !munin_get_bool ($service->{$name}, "onlynullcdef", 0)) { 406 349 print "NotOnlynullcdef ($field)...\n" if $DEBUG; 407 $node->{client}->{$service}->{$name.".cdef"} .= "," . 408 $node->{client}->{$service}->{$field.".cdef"}; 409 $node->{client}->{$service}->{$name.".cdef"} =~ s/\b$field\b/$name/g; 410 } 411 else 412 { 350 $service->{$name}->{"cdef"} .= "," . $service->{$field}->{"cdef"}; 351 $service->{$name}->{"cdef"} =~ s/\b$field\b/$name/g; 352 } else { 413 353 print "Onlynullcdef ($field)...\n" if $DEBUG; 414 $node->{client}->{$service}->{$name.".onlynullcdef"} = 1;354 munin_set_var_loc ($service->{$name}, ["onlynullcdef"], 1); 415 355 push @$result, "$name.onlynullcdef"; 416 356 } 417 357 } 418 } 419 elsif (defined ($tmp_field = &get_sum_command ($node, $service, $field))) 420 { 358 } elsif (defined ($tmp_field = &get_sum_command ($service->{$field}))) { 421 359 my @spc_stack = (); 422 360 my $last_name = ""; 423 361 print "DEBUG: Doing special_sum...\n" if $DEBUG; 424 362 425 if (@$order == 1 or 426 @$order == 2 && $node->{client}->{$service}->{$field.".negative"}) 427 { 428 $single = 1; 429 } 363 if (@$order == 1 or (@$order == 2 and munin_get {$field, "negative", 0})) { 364 $single = 1; 365 } 430 366 431 foreach my $pre (split (/\s+/, $tmp_field)) 432 { 367 foreach my $pre (split (/\s+/, $tmp_field)) { 433 368 (my $path = $pre) =~ s/.+=//; 434 369 my $name = "z".$fieldnum."_".scalar (@spc_stack); 435 370 $last_name = $name; 436 371 437 $node->{client}->{$service}->{$name.".cdef"} = "$name,UN,0,$name,IF";438 $node->{client}->{$service}->{$name.".graph"} = "no";439 $node->{client}->{$service}->{$name.".label"} = $name;372 munin_set_var_loc ($service, [$name, "cdef"], "$name,UN,0,$name,IF"); 373 munin_set_var_loc ($service, [$name, "graph"], "no"); 374 munin_set_var_loc ($service, [$name, "label"], $name); 440 375 push @$result, "$name.cdef"; 441 376 push @$result, "$name.graph"; … … 445 380 push (@$preproc, "$name=$pre"); 446 381 } 447 $node->{client}->{$service}->{$last_name.".cdef"} .= 448 "," . join (',+,', @spc_stack[0 .. @spc_stack-2]) . ',+'; 449 if (exists $node->{client}->{$service}->{$field.".cdef"} and 450 length $node->{client}->{$service}->{$field.".cdef"}) 451 { # Oh bugger... 452 my $tc = $node->{client}->{$service}->{$field.".cdef"}; 382 $service->{$last_name}->{"cdef"} .= "," . join (',+,', @spc_stack[0 .. @spc_stack-2]) . ',+'; 383 384 if (my $tc = munin_get ($service->{$field}, "cdef", 0)) { # Oh bugger... 453 385 print "Oh bugger...($field)...\n" if $DEBUG; 454 $tc =~ s/\b$field\b/$node->{client}->{$service}->{$last_name.".cdef"}/; 455 $node->{client}->{$service}->{$last_name.".cdef"} = $tc; 456 } 457 $node->{client}->{$service}->{$field.".process"} = "no"; 458 $node->{client}->{$service}->{$last_name.".draw"} = $node->{client}->{$service}->{$field.".draw"}; 459 $node->{client}->{$service}->{$last_name.".label"} = $node->{client}->{$service}->{$field.".label"}; 460 if (defined $node->{client}->{$service}->{$field.".graph"}) 461 { 462 $node->{client}->{$service}->{$last_name.".graph"} = $node->{client}->{$service}->{$field.".graph"}; 463 } 464 else 465 { 466 $node->{client}->{$service}->{$last_name.".graph"} = "yes"; 467 } 468 if (defined $node->{client}->{$service}->{$field.".negative"}) 469 { 470 $node->{client}->{$service}->{$last_name.".negative"} = $node->{client}->{$service}->{$field.".negative"};; 471 } 472 $node->{client}->{$service}->{$field.".realname"} = $last_name; 473 print "Setting node->{client}->{$service}->{$field} -> realname = $last_name...\n" if $DEBUG; 474 } 475 elsif (defined $node->{client}->{$service}->{$field.".negative"}) 476 { 477 my $nf = $node->{client}->{$service}->{$field.".negative"}; 478 unless (defined $node->{client}->{$service}->{$nf.".graph"} or 479 defined $node->{client}->{$service}->{$nf.".skipdraw"}) 480 { 481 $node->{client}->{$service}->{$nf.".graph"} = "no"; 386 $tc =~ s/\b$field\b/$service->{$last_name}->{"cdef"}/; 387 $service->{$last_name}->{"cdef"} = $tc; 388 } 389 munin_set_var_loc ($service, [$field, "process"], "no"); 390 munin_set_var_loc ($service, [$last_name, "draw"], munin_get ($service->{$field}, "draw")); 391 munin_set_var_loc ($service, [$last_name, "label"], munin_get ($service->{$field}, "label")); 392 munin_set_var_loc ($service, [$last_name, "graph"], munin_get ($service->{$field}, "graph", "yes")); 393 394 if (my $tmp = munin_get($service->{$field}, "negative")) { 395 munin_set_var_loc ($service, [$last_name, "negative"], $tmp); 396 } 397 398 munin_set_var_loc ($service, [$field, "realname"], $last_name); 399 400 } elsif (my $nf = munin_get ($service->{$field}, "negative", 0)) { 401 if (!munin_get_bool ($service->{$nf}, "graph", 1) or munin_get_bool ($service->{$nf}, "skipdraw", 0)) { 402 munin_set_var_loc ($service, [$nf, "graph"], "no"); 482 403 } 483 404 } … … 488 409 sub single_value 489 410 { 490 my $node = shift;491 my $config = shift;492 my $domain = shift;493 my $host = shift;494 411 my $service = shift; 495 my $field = shift; 496 my $order = shift; 497 498 return 1 if @$order == 1; 499 return 1 if (@$order == 2 and $node->{client}->{$service}->{$field.".negative"}); 500 501 my $graphable = 0; 502 if (!defined $node->{client}->{$service}->{"graphable"}) 503 { 504 # foreach my $field (keys %{$node->{client}->{$service}}) 505 foreach my $field (&munin_get_field_order ($node, $config, $domain, $host, $service)) 506 { 507 print "DEBUG: single_value: Checking field \"$field\".\n" if $DEBUG; 508 if ($field =~ /^([^\.]+)\.label/ or $field =~ /=/) 509 { 510 $graphable++ if &munin_draw_field ($node, $service, $1); 511 } 512 } 513 $node->{client}->{$service}->{"graphable"} = $graphable; 514 } 515 return 1 if ($node->{client}->{$service}->{"graphable"} == 1); 516 517 return 0; 412 413 my $graphable = munin_get ($service, "graphable", 0);; 414 if (!$graphable) { 415 foreach my $field (@{munin_get_field_order ($service)}) { 416 logger ("DEBUG: single_value: Checking field \"$field\"."); 417 $graphable++ if munin_draw_field ($service->{$field}); 418 } 419 munin_set_var_loc ($service, ["graphable"], $graphable); 420 } 421 logger ("Debug: service ". join (' :: ', @{munin_get_node_loc ($service)}) ." has $graphable elements."); 422 return ($graphable == 1); 518 423 } 519 424 … … 529 434 530 435 sub process_field { 531 my $node = shift;532 my $service = shift;533 436 my $field = shift; 534 return (&munin_get_bool_val ($node->{client}->{$service}->{$field.".process"}, 1)); 535 } 536 537 sub process_node { 538 my ($domain,$name,$node) = @_; 539 540 # See if we should skip it because of command-line arguments 541 return if (@limit_hosts and not grep (/^$name$/, @limit_hosts)); 437 return munin_get_bool ($field, "process", 1); 438 } 439 440 sub process_service { 441 my ($service) = @_; 542 442 543 443 # Make my graphs 544 logger ("Processing $name") if $DEBUG; 545 for my $service (keys %{$node->{client}}) { 546 my $service_time= Time::HiRes::time; 547 my $lastupdate = 0; 548 my $now = time; 549 my $fnum = 0; 550 my @rrd; 551 my @added = (); 552 553 # See if we should skip the service 554 next if (&skip_service ($node, $service)); 555 556 my $field_count = 0; 557 my $max_field_len = 0; 558 my @field_order = (); 559 my $rrdname; 560 my $force_single_value; 561 562 # munin_set_context($node,$config,$domain,$name,$service); 563 564 @field_order = 565 @{&munin_get_field_order($node, $config, $domain, $name, 566 $service, \$force_single_value)}; 567 568 # Array to keep 'preprocess'ed fields. 569 my @rrd_preprocess = (); 570 print "DEBUG: Expanding specials \"", 571 join("\",\"", @field_order), "\".\n" 572 if $DEBUG; 573 574 @added = 575 @{&expand_specials ($node, $config, $domain, $name, 576 $service, \@rrd_preprocess, \@field_order)}; 577 578 @field_order = (@rrd_preprocess, @field_order); 579 print "DEBUG: Checking field lengths \"", 580 join("\",\"", @rrd_preprocess), "\".\n" 581 if $DEBUG; 582 583 # Get max label length 584 $max_field_len = 585 &munin_get_max_label_length ($node, $config, $domain, $name, 586 $service, \@field_order); 587 # my $global_headers = ($max_field_len >= 16); 588 # Global headers makes the value tables easier to read no matter how 589 # wide the labels are. 590 my $global_headers = 1; 591 592 # Default format for printing under graph. 593 my $avgformat; 594 my $rrdformat=$avgformat="%6.2lf"; 595 596 if (exists $node->{client}->{$service}->{graph_args} and 597 $node->{client}->{$service}->{graph_args} =~ /--base\s+1024/) { 598 # If the base unit is 1024 then 1012.56 is a valid 599 # number to show. That's 7 positions, not 6. 600 $rrdformat=$avgformat="%7.2lf"; 601 } 602 603 if (exists $node->{client}->{$service}->{graph_printf} ) { 604 # Plugin specified complete printf format 605 $rrdformat=$node->{client}->{$service}->{graph_printf}; 606 } 607 608 my $rrdscale = ''; 609 $rrdscale = '%s' 610 if munin_get_bool_val ($node->{client}->{$service}->{graph_scale},1); 611 612 # Array to keep negative data until we're finished with positive. 613 my @rrd_negatives = (); 614 my $filename = "unknown"; 615 my %total_pos; 616 my %total_neg; 617 my $autostacking=0; 618 print "DEBUG: Treating fields \"", join "\",\"", @field_order, "\".\n" if $DEBUG; 619 for my $field (@field_order) { 620 my $path = undef; 621 if ($field =~ s/=(.+)//) { 622 $path = $1; 623 } 624 625 next unless &process_field ($node, $service, $field); 626 print "DEBUG: Processing field \"$field\".\n" if $DEBUG; 627 628 my $fielddraw = munin_get ($config, "draw", "LINE2", $domain, 629 $name, $service, $field); 630 631 if ($field_count == 0 and $fielddraw eq 'STACK') { 632 # Illegal -- first field is a STACK 633 logger ("ERROR: First field (\"$field\") of graph \"$domain\"". 634 ":: \"$name\" :: \"$service\" is STACK. STACK can ". 635 "only be drawn after a LINEx or AREA."); 636 $fielddraw = "LINE2"; 637 } 638 639 if ($fielddraw eq 'AREASTACK') { 640 if ($autostacking==0) { 641 $fielddraw='AREA'; 642 $autostacking=1; 643 } else { 644 $fielddraw='STACK'; 645 } 646 } 647 648 if ($fielddraw =~ /LINESTACK(\d+(?:.\d+)?)/ ) { 649 if ($autostacking==0) { 650 $fielddraw="LINE$1"; 651 $autostacking=1; 652 } else { 653 $fielddraw='STACK'; 654 } 655 } 656 657 # Getting name of rrd file 658 $filename = &munin_get_rrd_filename ($node, $config, $domain, 659 $name, $service, $field, 660 $path); 661 662 my $update = RRDs::last ($filename); 663 $update = 0 if ! defined $update; 664 if ($update > $lastupdate) { 665 $lastupdate = $update; 666 } 667 668 # It does not look like $fieldname.rrdfield is possible to set 669 my $rrdfield = ($node->{client}->{$service}->{$field.".rrdfield"} 670 || "42"); 671 672 my $single_value = $force_single_value || 673 &single_value ($node, $config, $domain, $name, 674 $service, $field, \@field_order); 675 676 my $has_negative = 677 exists $node->{client}->{$service}->{$field.".negative"}; 678 679 # Trim the fieldname to make room for other field names. 680 $rrdname = &get_field_name ($field); 681 if ($rrdname ne $field) { 682 # A change was made 683 set_cdef_name ($node->{client}->{$service}, $field, $rrdname); 684 } 685 686 push (@rrd, "DEF:g$rrdname=" . 687 $filename . ":" . $rrdfield . ":AVERAGE"); 688 push (@rrd, "DEF:i$rrdname=" . 689 $filename . ":" . $rrdfield . ":MIN"); 690 push (@rrd, "DEF:a$rrdname=" . 691 $filename . ":" . $rrdfield . ":MAX"); 692 693 if (exists $node->{client}->{$service}->{$field.".onlynullcdef"} 694 and 695 $node->{client}->{$service}->{$field.".onlynullcdef"}) { 696 push (@rrd, "CDEF:c$rrdname=g$rrdname" . 697 (($now-$update)>900 ? ",POP,UNKN" : "")); 698 } 699 700 if (($node->{client}->{$service}->{$field.".type"}||"GAUGE") 701 ne "GAUGE" 702 and graph_by_minute ($config, $domain, $name, $service)) { 703 push (@rrd, &expand_cdef($node->{client}->{$service}, 704 \$rrdname, "$field,60,*")); 705 } 706 707 if ($node->{client}->{$service}->{$field.".cdef"}) { 708 push (@rrd,&expand_cdef($node->{client}->{$service}, 709 \$rrdname, 710 $node->{client}->{$service}->{$field.".cdef"})); 711 push (@rrd, "CDEF:c$rrdname=g$rrdname"); 712 print "DEBUG: Field name after cdef set to $rrdname\n" if $DEBUG; 713 } elsif (!(exists $node->{client}->{$service}->{$field.".onlynullcdef"} 714 and $node->{client}->{$service}->{$field.".onlynullcdef"})) { 715 push (@rrd, "CDEF:c$rrdname=g$rrdname" . (($now-$update)>900 ? ",POP,UNKN" : "")); 716 } 717 718 next unless &munin_draw_field ($node, $service, $field); 719 print "DEBUG: Drawing field \"$field\".\n" if $DEBUG; 444 my $sname = munin_get_node_name ($service); 445 my $service_time= Time::HiRes::time; 446 my $lastupdate = 0; 447 my $now = time; 448 my $fnum = 0; 449 my @rrd; 450 my @added = (); 451 452 # See if we should skip the service 453 next if (skip_service ($service)); 454 455 my $field_count = 0; 456 my $max_field_len = 0; 457 my @field_order = (); 458 my $rrdname; 459 my $force_single_value; 460 461 @field_order = @{munin_get_field_order($service)}; 462 463 # Array to keep 'preprocess'ed fields. 464 my @rrd_preprocess = (); 465 logger ("Debug: Expanding specials for $sname: \"" . join("\",\"", @field_order) . "\".") if $DEBUG; 466 467 @added = @{&expand_specials ($service, \@rrd_preprocess, \@field_order, \$force_single_value)}; 468 469 @field_order = (@rrd_preprocess, @field_order); 470 logger ("DEBUG: Checking field lengths for $sname: \"" . join("\",\"", @rrd_preprocess) . "\".") if $DEBUG; 471 472 # Get max label length 473 $max_field_len = &munin_get_max_label_length ($service, \@field_order); 474 475 # Global headers makes the value tables easier to read no matter how 476 # wide the labels are. 477 my $global_headers = 1; 478 479 # Default format for printing under graph. 480 my $avgformat; 481 my $rrdformat=$avgformat="%6.2lf"; 482 483 if (munin_get ($service, "graph_args", "") =~ /--base\s+1024/) { 484 # If the base unit is 1024 then 1012.56 is a valid 485 # number to show. That's 7 positions, not 6. 486 $rrdformat=$avgformat="%7.2lf"; 487 } 488 489 # Plugin specified complete printf format 490 $rrdformat = munin_get ($service, "graph_printf", $rrdformat); 491 492 my $rrdscale = ''; 493 if (munin_get_bool ($service, "graph_scale", 1)) { 494 $rrdscale = '%s'; 495 } 496 497 # Array to keep negative data until we're finished with positive. 498 my @rrd_negatives = (); 499 500 my $filename = "unknown"; 501 my %total_pos; 502 my %total_neg; 503 my $autostacking=0; 504 505 logger ("DEBUG: Treating fields \"" . join ("\",\"", @field_order) . "\".") if $DEBUG; 506 for my $fname (@field_order) { 507 my $field = munin_get_node ($service, [$fname]); 508 my $path = undef; 509 510 if ($fname =~ s/=(.+)//) { 511 $path = $1; 512 } 513 514 next if !process_field ($field); 515 logger ("DEBUG: Processing field \"$fname\".") if $DEBUG; 516 517 my $fielddraw = munin_get ($field, "draw", "LINE2"); 518 519 if ($field_count == 0 and $fielddraw eq 'STACK') { 520 # Illegal -- first field is a STACK 521 logger ("ERROR: First field (\"$fname\") of graph " . join (' :: ', munin_get_node_loc ($service)) . 522 " is STACK. STACK can only be drawn after a LINEx or AREA."); 523 $fielddraw = "LINE2"; 524 } 525 526 if ($fielddraw eq 'AREASTACK') { 527 if ($autostacking==0) { 528 $fielddraw='AREA'; 529 $autostacking=1; 530 } else { 531 $fielddraw='STACK'; 532 } 533 } 534 535 if ($fielddraw =~ /LINESTACK(\d+(?:.\d+)?)/ ) { 536 if ($autostacking==0) { 537 $fielddraw="LINE$1"; 538 $autostacking=1; 539 } else { 540 $fielddraw='STACK'; 541 } 542 } 543 544 # Getting name of rrd file 545 $filename = munin_get_rrd_filename ($field, $path); 546 547 my $update = RRDs::last ($filename); 548 $update = 0 if ! defined $update; 549 if ($update > $lastupdate) { 550 $lastupdate = $update; 551 } 552 553 # It does not look like $fieldname.rrdfield is possible to set 554 my $rrdfield = munin_get ($field, "rrdfield", "42"); 555 556 my $single_value = $force_single_value || single_value ($service); 557 558 my $has_negative = munin_get ($field, "negative"); 559 560 # Trim the fieldname to make room for other field names. 561 $rrdname = &get_field_name ($fname); 562 if ($rrdname ne $fname) { 563 # A change was made 564 munin_set_var ($field, "cdef_name", $rrdname); 565 } 566 567 push (@rrd, "DEF:g$rrdname=" . 568 $filename . ":" . $rrdfield . ":AVERAGE"); 569 push (@rrd, "DEF:i$rrdname=" . 570 $filename . ":" . $rrdfield . ":MIN"); 571 push (@rrd, "DEF:a$rrdname=" . 572 $filename . ":" . $rrdfield . ":MAX"); 573 574 if (munin_get_bool ($field, "onlynullcdef", 0)) { 575 push (@rrd, "CDEF:c$rrdname=g$rrdname" . (($now-$update)>900 ? ",POP,UNKN" : "")); 576 } 577 578 if (munin_get ($field, "type", "GAUGE") ne "GAUGE" and graph_by_minute ($service)) { 579 push (@rrd, expand_cdef($service, \$rrdname, "$fname,60,*")); 580 } 581 582 if (my $tmpcdef = munin_get ($field, "cdef")) { 583 push (@rrd,expand_cdef($service, \$rrdname, $tmpcdef)); 584 push (@rrd, "CDEF:c$rrdname=g$rrdname"); 585 logger ("DEBUG: Field name after cdef set to $rrdname") if $DEBUG; 586 } elsif (!munin_get_bool ($field, "onlynullcdef", 0)) { 587 push (@rrd, "CDEF:c$rrdname=g$rrdname" . (($now-$update)>900 ? ",POP,UNKN" : "")); 588 } 589 590 next if !munin_draw_field ($field); 591 logger ("DEBUG: Drawing field \"$fname\".") if $DEBUG; 592 593 if ($single_value) { 594 # Only one field. Do min/max range. 595 push (@rrd, "CDEF:min_max_diff=a$rrdname,i$rrdname,-"); 596 push (@rrd, "CDEF:re_zero=min_max_diff,min_max_diff,-") if !munin_get ($field, "negative"); 597 push (@rrd, "AREA:i$rrdname#ffffff"); 598 push (@rrd, "STACK:min_max_diff$range_colour"); 599 push (@rrd, "LINE2:re_zero#000000") if !munin_get ($field, "negative"); 600 } 601 602 if ($has_negative and !@rrd_negatives) { # Push "global" headers... 603 push (@rrd, "COMMENT:" . (" " x $max_field_len)); 604 push (@rrd, "COMMENT:Cur (-/+)"); 605 push (@rrd, "COMMENT:Min (-/+)"); 606 push (@rrd, "COMMENT:Avg (-/+)"); 607 push (@rrd, "COMMENT:Max (-/+) \\j"); 608 } elsif ($global_headers == 1) { 609 push (@rrd, "COMMENT:" . (" " x $max_field_len)); 610 push (@rrd, "COMMENT: Cur$RRDkludge:"); 611 push (@rrd, "COMMENT:Min$RRDkludge:"); 612 push (@rrd, "COMMENT:Avg$RRDkludge:"); 613 push (@rrd, "COMMENT:Max$RRDkludge: \\j"); 614 $global_headers++; 615 } 616 617 my $colour; 618 619 if (my $tmpcol = munin_get ($field, "colour")) { 620 $colour = "#" . $tmpcol; 621 } elsif ($single_value) { 622 $colour = $single_colour; 623 } else { 624 $colour = $COLOUR[$field_count%@COLOUR]; 625 } 626 627 $field_count++; 628 629 my $tmplabel = munin_get ($field, "label", $fname); 630 631 push (@rrd, $fielddraw . ":g$rrdname" . $colour . ":" . 632 escape ($tmplabel) . (" " x ($max_field_len + 1 - length $tmplabel))); 633 634 # Check for negative fields (typically network (or disk) traffic) 635 if ($has_negative) { 636 my $negfieldname = orig_to_cdef ($service, munin_get ($field, "negative")); 637 my $negfield = $service->{$negfieldname}; 638 if (my $tmpneg = munin_get ($negfield, "realname")) { 639 $negfieldname = $tmpneg; 640 $negfield = $service->{$negfieldname}; 641 } 642 643 if (!@rrd_negatives) { 644 # zero-line, to redraw zero afterwards. 645 push (@rrd_negatives, "CDEF:re_zero=g$negfieldname,UN,0,0,IF"); 646 } 647 648 push (@rrd_negatives, "CDEF:ng$negfieldname=g$negfieldname,-1,*"); 720 649 721 650 if ($single_value) { 722 651 # Only one field. Do min/max range. 723 push (@rrd, "CDEF:min_max_diff=a$rrdname,i$rrdname,-"); 724 push (@rrd, "CDEF:re_zero=min_max_diff,min_max_diff,-") 725 unless ($node->{client}->{$service}->{$field.".negative"}); 726 push (@rrd, "AREA:i$rrdname#ffffff"); 727 push (@rrd, "STACK:min_max_diff$range_colour"); 728 push (@rrd, "LINE2:re_zero#000000") 729 unless ($node->{client}->{$service}->{$field.".negative"}); 730 } 731 732 if ($has_negative and !@rrd_negatives) { # Push "global" headers... 733 push (@rrd, "COMMENT:" . (" " x $max_field_len)); 734 push (@rrd, "COMMENT:Cur (-/+)"); 735 push (@rrd, "COMMENT:Min (-/+)"); 736 push (@rrd, "COMMENT:Avg (-/+)"); 737 push (@rrd, "COMMENT:Max (-/+) \\j"); 738 } elsif ($global_headers == 1) { 739 push (@rrd, "COMMENT:" . (" " x $max_field_len)); 740 push (@rrd, "COMMENT: Cur$RRDkludge:"); 741 push (@rrd, "COMMENT:Min$RRDkludge:"); 742 push (@rrd, "COMMENT:Avg$RRDkludge:"); 743 push (@rrd, "COMMENT:Max$RRDkludge: \\j"); 744 $global_headers++; 745 } 746 747 my $colour; 748 749 if (exists $node->{client}->{$service}->{$field.".colour"}) { 750 $colour = "#". 751 $node->{client}->{$service}->{$field.".colour"}; 752 } elsif ($single_value) { 753 $colour = $single_colour; 754 } else { 755 $colour = $COLOUR[$field_count%@COLOUR]; 756 } 757 758 $field_count++; 759 760 push (@rrd, $fielddraw . ":g$rrdname" . $colour . ":" . 761 (escape ($node->{client}->{$service}->{"$field.label"}) || escape ($field)) 762 . (" " x ($max_field_len + 1 - 763 length ($node->{client}->{$service}->{"$field.label"} || $field)))); 764 765 # Check for negative fields (typically network (or disk) traffic) 766 if ($has_negative) { 767 my $negfield = &orig_to_cdef ($node->{client}->{$service}, $node->{client}->{$service}->{$field.".negative"}); 768 print "DEBUG: negfield = $negfield\n" if $DEBUG; 769 if (exists $node->{client}->{$service}->{$negfield.".realname"}) { 770 $negfield = $node->{client}->{$service}->{$negfield.".realname"}; 771 } 772 773 if (!@rrd_negatives) { 774 # zero-line, to redraw zero afterwards. 775 push (@rrd_negatives, "CDEF:re_zero=g$negfield,UN,0,0,IF"); 776 } 777 778 push (@rrd_negatives, "CDEF:ng$negfield=g$negfield,-1,*"); 779 780 if ($single_value) { 781 # Only one field. Do min/max range. 782 push (@rrd, "CDEF:neg_min_max_diff=i$negfield,a$negfield,-"); 783 push (@rrd, "CDEF:ni$negfield=i$negfield,-1,*"); 784 push (@rrd, "AREA:ni$negfield#ffffff"); 785 push (@rrd, "STACK:neg_min_max_diff$range_colour"); 786 } 787 788 push (@rrd_negatives, $fielddraw . ":ng$negfield" . $colour ); 789 790 # Draw HRULEs 791 my $linedef = munin_get ($config, "line", undef, $domain, $name, $service, $node->{client}->{$service}->{$field.".negative"}); 792 if ($linedef) { 793 my ($number, $ldcolour, $label) = split (/:/, $linedef, 3); 794 push (@rrd_negatives, "HRULE:".$number. 795 ($ldcolour ? "#$ldcolour" : $colour)); 796 797 } elsif ($node->{client}->{$service}->{"$negfield.warn"}) { 798 push (@rrd_negatives, "HRULE:".$node->{client}->{$service}->{$node->{client}->{$service}->{$field.".negative"}.".warn"}. 799 (defined $single_value and $single_value) ? "#ff0000" : $colour); 800 } 801 802 push (@rrd, "GPRINT:c$negfield:LAST:$rrdformat" . $rrdscale . "/\\g"); 803 push (@rrd, "GPRINT:c$rrdname:LAST:$rrdformat" . $rrdscale . ""); 804 push (@rrd, "GPRINT:i$negfield:MIN:$rrdformat" . $rrdscale . "/\\g"); 805 push (@rrd, "GPRINT:i$rrdname:MIN:$rrdformat" . $rrdscale . ""); 806 push (@rrd, "GPRINT:g$negfield:AVERAGE:$avgformat" . $rrdscale . "/\\g"); 807 push (@rrd, "GPRINT:g$rrdname:AVERAGE:$avgformat" . $rrdscale . ""); 808 push (@rrd, "GPRINT:a$negfield:MAX:$rrdformat" . $rrdscale . "/\\g"); 809 push (@rrd, "GPRINT:a$rrdname:MAX:$rrdformat" . $rrdscale . "\\j"); 810 push (@{$total_pos{'min'}}, "i$rrdname"); 811 push (@{$total_pos{'avg'}}, "g$rrdname"); 812 push (@{$total_pos{'max'}}, "a$rrdname"); 813 push (@{$total_neg{'min'}}, "i$negfield"); 814 push (@{$total_neg{'avg'}}, "g$negfield"); 815 push (@{$total_neg{'max'}}, "a$negfield"); 816 } else { 817 push (@rrd, "COMMENT: Cur$RRDkludge:") unless $global_headers; 818 push (@rrd, "GPRINT:c$rrdname:LAST:$rrdformat" . $rrdscale . ""); 819 push (@rrd, "COMMENT: Min$RRDkludge:") unless $global_headers; 820 push (@rrd, "GPRINT:i$rrdname:MIN:$rrdformat" . $rrdscale . ""); 821 push (@rrd, "COMMENT: Avg$RRDkludge:") unless $global_headers; 822 push (@rrd, "GPRINT:g$rrdname:AVERAGE:$avgformat" . $rrdscale . ""); 823 push (@rrd, "COMMENT: Max$RRDkludge:") unless $global_headers; 824 push (@rrd, "GPRINT:a$rrdname:MAX:$rrdformat" . $rrdscale . "\\j"); 825 push (@{$total_pos{'min'}}, "i$rrdname"); 826 push (@{$total_pos{'avg'}}, "g$rrdname"); 827 push (@{$total_pos{'max'}}, "a$rrdname"); 828 } 652 push (@rrd, "CDEF:neg_min_max_diff=i$negfieldname,a$negfieldname,-"); 653 push (@rrd, "CDEF:ni$negfieldname=i$negfieldname,-1,*"); 654 push (@rrd, "AREA:ni$negfieldname#ffffff"); 655 push (@rrd, "STACK:neg_min_max_diff$range_colour"); 656 } 657 658 push (@rrd_negatives, $fielddraw . ":ng$negfieldname" . $colour ); 829 659 830 660 # Draw HRULEs 831 my $linedef = munin_get ($ config, "line", undef, $domain, $name, $service, $field);661 my $linedef = munin_get ($negfield, "line"); 832 662 if ($linedef) { 833 663 my ($number, $ldcolour, $label) = split (/:/, $linedef, 3); 834 $label =~ s/:/\\:/g if defined $label; 835 push (@rrd, "HRULE:".$number. 836 ($ldcolour ? "#$ldcolour" : 837 ((defined $single_value and $single_value) ? 838 "#ff0000" : $colour)). 839 ((defined $label and length ($label)) ? ":$label" : ""), 840 "COMMENT: \\j" 841 ); 842 } elsif ($node->{client}->{$service}->{"$field.warn"}) { 843 push (@rrd,"HRULE:". 844 $node->{client}->{$service}->{"$field.warn"}. 845 ($single_value ? "#ff0000" : $colour)); 846 } 847 } 848 849 if (@rrd_negatives) { 850 push (@rrd, @rrd_negatives); 851 push (@rrd, "LINE2:re_zero#000000"); # Redraw zero. 852 if (exists $node->{client}->{$service}->{graph_total} and 853 exists $total_pos{'min'} and exists $total_neg{'min'} and 854 @{$total_pos{'min'}} and @{$total_neg{'min'}}) { 855 856 push (@rrd, "CDEF:ipostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'min'}}).(",+" x (@{$total_pos{'min'}}-1))); 857 push (@rrd, "CDEF:gpostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'avg'}}).(",+" x (@{$total_pos{'avg'}}-1))); 858 push (@rrd, "CDEF:apostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'max'}}).(",+" x (@{$total_pos{'max'}}-1))); 859 push (@rrd, "CDEF:inegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'min'}}).(",+" x (@{$total_neg{'min'}}-1))); 860 push (@rrd, "CDEF:gnegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'avg'}}).(",+" x (@{$total_neg{'avg'}}-1))); 861 push (@rrd, "CDEF:anegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'max'}}).(",+" x (@{$total_neg{'max'}}-1))); 862 push (@rrd, "CDEF:dpostotal=ipostotal,UN,ipostotal,UNKN,IF"); 863 push (@rrd, "LINE1:dpostotal#000000:" . $node->{client}->{$service}->{graph_total} . (" " x ($max_field_len - length ($node->{client}->{$service}->{graph_total}) + 1))); 864 push (@rrd, "GPRINT:gnegtotal:LAST:$rrdformat" . $rrdscale . "/\\g"); 865 push (@rrd, "GPRINT:gpostotal:LAST:$rrdformat" . $rrdscale . ""); 866 push (@rrd, "GPRINT:inegtotal:MIN:$rrdformat" . $rrdscale . "/\\g"); 867 push (@rrd, "GPRINT:ipostotal:MIN:$rrdformat" . $rrdscale . ""); 868 push (@rrd, "GPRINT:gnegtotal:AVERAGE:$avgformat" . $rrdscale . "/\\g"); 869 push (@rrd, "GPRINT:gpostotal:AVERAGE:$avgformat" . $rrdscale . ""); 870 push (@rrd, "GPRINT:anegtotal:MAX:$rrdformat" . $rrdscale . "/\\g"); 871 push (@rrd, "GPRINT:apostotal:MAX:$rrdformat" . $rrdscale . "\\j"); 872 } 873 } 874 elsif (exists $node->{client}->{$service}->{graph_total} and exists $total_pos{'min'} and @{$total_pos{'min'}}) { 664 push (@rrd_negatives, "HRULE:".$number. 665 ($ldcolour ? "#$ldcolour" : $colour)); 666 667 } elsif (my $tmpwarn = munin_get ($negfield, "warn")) { 668 push (@rrd_negatives, "HRULE:".$negfieldname. 669 (defined $single_value and $single_value) ? "#ff0000" : $colour); 670 } 671 672 push (@rrd, "GPRINT:c$negfieldname:LAST:$rrdformat" . $rrdscale . "/\\g"); 673 push (@rrd, "GPRINT:c$rrdname:LAST:$rrdformat" . $rrdscale . ""); 674 push (@rrd, "GPRINT:i$negfieldname:MIN:$rrdformat" . $rrdscale . "/\\g"); 675 push (@rrd, "GPRINT:i$rrdname:MIN:$rrdformat" . $rrdscale . ""); 676 push (@rrd, "GPRINT:g$negfieldname:AVERAGE:$avgformat" . $rrdscale . "/\\g"); 677 push (@rrd, "GPRINT:g$rrdname:AVERAGE:$avgformat" . $rrdscale . ""); 678 push (@rrd, "GPRINT:a$negfieldname:MAX:$rrdformat" . $rrdscale . "/\\g"); 679 push (@rrd, "GPRINT:a$rrdname:MAX:$rrdformat" . $rrdscale . "\\j"); 680 push (@{$total_pos{'min'}}, "i$rrdname"); 681 push (@{$total_pos{'avg'}}, "g$rrdname"); 682 push (@{$total_pos{'max'}}, "a$rrdname"); 683 push (@{$total_neg{'min'}}, "i$negfieldname"); 684 push (@{$total_neg{'avg'}}, "g$negfieldname"); 685 push (@{$total_neg{'max'}}, "a$negfieldname"); 686 } else { 687 push (@rrd, "COMMENT: Cur$RRDkludge:") unless $global_headers; 688 push (@rrd, "GPRINT:c$rrdname:LAST:$rrdformat" . $rrdscale . ""); 689 push (@rrd, "COMMENT: Min$RRDkludge:") unless $global_headers; 690 push (@rrd, "GPRINT:i$rrdname:MIN:$rrdformat" . $rrdscale . ""); 691 push (@rrd, "COMMENT: Avg$RRDkludge:") unless $global_headers; 692 push (@rrd, "GPRINT:g$rrdname:AVERAGE:$avgformat" . $rrdscale . ""); 693 push (@rrd, "COMMENT: Max$RRDkludge:") unless $global_headers; 694 push (@rrd, "GPRINT:a$rrdname:MAX:$rrdformat" . $rrdscale . "\\j"); 695 push (@{$total_pos{'min'}}, "i$rrdname"); 696 push (@{$total_pos{'avg'}}, "g$rrdname"); 697 push (@{$total_pos{'max'}}, "a$rrdname"); 698 } 699 700 # Draw HRULEs 701 my $linedef = munin_get ($field, "line"); 702 if ($linedef) { 703 my ($number, $ldcolour, $label) = split (/:/, $linedef, 3); 704 $label =~ s/:/\\:/g if defined $label; 705 push (@rrd, "HRULE:".$number. 706 ($ldcolour ? "#$ldcolour" : 707 ((defined $single_value and $single_value) ? 708 "#ff0000" : $colour)). 709 ((defined $label and length ($label)) ? ":$label" : ""), 710 "COMMENT: \\j" 711 ); 712 } elsif (my $tmpwarn = munin_get ($field, "warn")) { 713 push (@rrd,"HRULE:".$tmpwarn.($single_value ? "#ff0000" : $colour)); 714 } 715 } 716 717 my $graphtotal = munin_get ($service, "graph_total"); 718 if (@rrd_negatives) { 719 push (@rrd, @rrd_negatives); 720 push (@rrd, "LINE2:re_zero#000000"); # Redraw zero. 721 if (defined $graphtotal and exists $total_pos{'min'} and 722 exists $total_neg{'min'} and 723 @{$total_pos{'min'}} and @{$total_neg{'min'}}) { 724 875 725 push (@rrd, "CDEF:ipostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'min'}}).(",+" x (@{$total_pos{'min'}}-1))); 876 726 push (@rrd, "CDEF:gpostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'avg'}}).(",+" x (@{$total_pos{'avg'}}-1))); 877 727 push (@rrd, "CDEF:apostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'max'}}).(",+" x (@{$total_pos{'max'}}-1))); 878 728 push (@rrd, "CDEF:inegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'min'}}).(",+" x (@{$total_neg{'min'}}-1))); 729 push (@rrd, "CDEF:gnegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'avg'}}).(",+" x (@{$total_neg{'avg'}}-1))); 730 push (@rrd, "CDEF:anegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'max'}}).(",+" x (@{$total_neg{'max'}}-1))); 879 731 push (@rrd, "CDEF:dpostotal=ipostotal,UN,ipostotal,UNKN,IF"); 880 push (@rrd, "LINE1:dpostotal#000000: " . $node->{client}->{$service}->{graph_total} . (" " x ($max_field_len - length ($node->{client}->{$service}->{graph_total}) + 1)));881 push (@rrd, " COMMENT: Cur$RRDkludge:") unless $global_headers;732 push (@rrd, "LINE1:dpostotal#000000:$graphtotal" . (" " x ($max_field_len - length ($graphtotal) + 1))); 733 push (@rrd, "GPRINT:gnegtotal:LAST:$rrdformat" . $rrdscale . "/\\g"); 882 734 push (@rrd, "GPRINT:gpostotal:LAST:$rrdformat" . $rrdscale . ""); 883 push (@rrd, " COMMENT: Min$RRDkludge:") unless $global_headers;735 push (@rrd, "GPRINT:inegtotal:MIN:$rrdformat" . $rrdscale . "/\\g"); 884 736 push (@rrd, "GPRINT:ipostotal:MIN:$rrdformat" . $rrdscale . ""); 885 push (@rrd, " COMMENT: Avg$RRDkludge:") unless $global_headers;886 push (@rrd, "GPRINT:gpostotal:AVERAGE:$avgformat" . $rrdscale . "");887 push (@rrd, " COMMENT: Max$RRDkludge:") unless $global_headers;737 push (@rrd, "GPRINT:gnegtotal:AVERAGE:$avgformat" . $rrdscale . "/\\g"); 738 push (@rrd, "GPRINT:gpostotal:AVERAGE:$avgformat" . $rrdscale . ""); 739 push (@rrd, "GPRINT:anegtotal:MAX:$rrdformat" . $rrdscale . "/\\g"); 888 740 push (@rrd, "GPRINT:apostotal:MAX:$rrdformat" . $rrdscale . "\\j"); 889 741 } 890 891 for my $time (keys %times) { 892 next unless ($draw{$time}); 893 my @complete = (); 894 if ($RRDkludge) { 895 push (@complete, 896 '--font' ,'LEGEND:7:@@LIBDIR@@/VeraMono.ttf', 897 '--font' ,'UNIT:7:@@LIBDIR@@/VeraMono.ttf', 898 '--font' ,'AXIS:7:@@LIBDIR@@/VeraMono.ttf'); 899 } 900 901 logger ("Processing $name -> $time") if $DEBUG; 902 903 # Do the header (title, vtitle, size, etc...) 904 push @complete, @{&get_header ($node, $config, $domain, $name, $service, $time)}; 905 if ($LINEkluge) { 906 @rrd = map { s/LINE3:/LINE2.2:/; $_; } @rrd; 907 @rrd = map { s/LINE2:/LINE1.6:/; $_; } @rrd; 908 # LINE1 is thin enough. 909 } 910 push @complete, @rrd; 911 912 push (@complete, "COMMENT:Last update$RRDkludge: " . 913 RRDescape(scalar localtime($lastupdate)) . "\\r"); 742 } elsif (defined $graphtotal and exists $total_pos{'min'} and @{$total_pos{'min'}}) { 743 push (@rrd, "CDEF:ipostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'min'}}).(",+" x (@{$total_pos{'min'}}-1))); 744 push (@rrd, "CDEF:gpostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'avg'}}).(",+" x (@{$total_pos{'avg'}}-1))); 745 push (@rrd, "CDEF:apostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'max'}}).(",+" x (@{$total_pos{'max'}}-1))); 746 747 push (@rrd, "CDEF:dpostotal=ipostotal,UN,ipostotal,UNKN,IF"); 748 push (@rrd, "LINE1:dpostotal#000000:$graphtotal" . (" " x ($max_field_len - length ($graphtotal) + 1))); 749 push (@rrd, "COMMENT: Cur$RRDkludge:") unless $global_headers; 750 push (@rrd, "GPRINT:gpostotal:LAST:$rrdformat" . $rrdscale . ""); 751 push (@rrd, "COMMENT: Min$RRDkludge:") unless $global_headers; 752 push (@rrd, "GPRINT:ipostotal:MIN:$rrdformat" . $rrdscale . ""); 753 push (@rrd, "COMMENT: Avg$RRDkludge:") unless $global_headers; 754 push (@rrd, "GPRINT:gpostotal:AVERAGE:$avgformat" . $rrdscale .""); 755 push (@rrd, "COMMENT: Max$RRDkludge:") unless $global_headers; 756 push (@rrd, "GPRINT:apostotal:MAX:$rrdformat" . $rrdscale . "\\j"); 757 } 758 759 for my $time (keys %times) { 760 next unless ($draw{$time}); 761 my $picfilename = munin_get_picture_filename ($service, $time); 762 (my $picdirname = $picfilename) =~ s/\/[^\/]+$//; 763 764 my @complete = (); 765 if ($RRDkludge) { 766 push (@complete, 767 '--font' ,'LEGEND:7:@@LIBDIR@@/VeraMono.ttf', 768 '--font' ,'UNIT:7:@@LIBDIR@@/VeraMono.ttf', 769 '--font' ,'AXIS:7:@@LIBDIR@@/VeraMono.ttf'); 770 } 771 772 # Do the header (title, vtitle, size, etc...) 773 push @complete, @{get_header ($service, $time)}; 774 if ($LINEkluge) { 775 @rrd = map { s/LINE3:/LINE2.2:/; $_; } @rrd; 776 @rrd = map { s/LINE2:/LINE1.6:/; $_; } @rrd; 777 # LINE1 is thin enough. 778 } 779 push @complete, @rrd; 780 781 push (@complete, "COMMENT:Last update$RRDkludge: " . 782 RRDescape(scalar localtime($lastupdate)) . "\\r"); 783 784 if (time - 300 < $lastupdate) { 785 push @complete, "--end", 786 (int($lastupdate/$resolutions{$time}))*$resolutions{$time}; 787 } 788 print "\n\nrrdtool \"graph\" \"", 789 join ("\"\n\t\"",@complete), "\"\n" if $DEBUG; 790 791 # Make sure directory exists 792 munin_mkdir_p ($picdirname, 0777); 793 794 RRDs::graph (@complete); 795 if (my $ERROR = RRDs::error) { 796 logger ("Unable to graph $filename: $ERROR"); 797 } elsif ($list_images) { 798 # Command-line option to list images created 799 print munin_get_picture_filename ($service, $time),"\n"; 800 } 801 } 802 803 if (munin_get_bool ($service, "graph_sums", 0)) { 804 foreach my $time (keys %sumtimes) { 805 my $picfilename = munin_get_picture_filename ($service, $time, 1); 806 (my $picdirname = $picfilename) =~ s/\/[^\/]+$//; 807 next unless ($draw{"sum".$time}); 808 my @rrd_sum; 809 push @rrd_sum, @{get_header ($service, $time, 1)}; 914 810 915 811 if (time - 300 < $lastupdate) { 916 push @complete, "--end", 917 (int($lastupdate/$resolutions{$time}))*$resolutions{$time}; 918 } 919 print "\n\nrrdtool \"graph\" \"", 920 join ("\"\n\t\"",@complete), "\"\n" if $DEBUG; 921 RRDs::graph (@complete); 812 push @rrd_sum, "--end",(int($lastupdate/$resolutions{$time}))*$resolutions{$time}; 813 } 814 push @rrd_sum, @rrd; 815 push (@rrd_sum, "COMMENT:Last update$RRDkludge: " . RRDescape(scalar localtime($lastupdate)) . "\\r"); 816 817 my $labelled = 0; 818 my @defined = (); 819 for (my $index = 0; $index <= $#rrd_sum; $index++) { 820 if ($rrd_sum[$index] =~ /^(--vertical-label|-v)$/) { 821 (my $label = munin_get ($service, "graph_vlabel")) =~ s/\$\{graph_period\}/$sumtimes{$time}[0]/g; 822 splice (@rrd_sum, $index, 2, ("--vertical-label", $label)); 823 $index++; 824 $labelled++; 825 } elsif ($rrd_sum[$index] =~ /^(LINE[123]|STACK|AREA|GPRINT):([^#:]+)([#:].+)$/) { 826 my ($pre, $fname, $post) = ($1, $2, $3); 827 next if $fname eq "re_zero"; 828 if ($post =~ /^:AVERAGE/) { 829 splice (@rrd_sum, $index, 1, $pre . ":x$fname" . $post); 830 $index++; 831 next; 832 } 833 next if grep /^x$fname$/, @defined; 834 push @defined, "x$fname"; 835 my @replace; 836 837 if (munin_get ($service->{$fname}, "type", "GAUGE") ne "GAUGE") { 838 if ($time eq "week") { 839 # Every plot is half an hour. Add two plots and multiply, to get per hour 840 if (graph_by_minute ($service)) { 841 # Already multiplied by 60 842 push @replace, "CDEF:x$fname=PREV($fname),UN,0,PREV($fname),IF,$fname,+,5,*,6,*"; 843 } else { 844 push @replace, "CDEF:x$fname=PREV($fname),UN,0,PREV($fname),IF,$fname,+,300,*,6,*"; 845 } 846 } else { 847 # Every plot is one day exactly. Just multiply. 848 if (graph_by_minute ($service)) { 849 # Already multiplied by 60 850 push @replace, "CDEF:x$fname=$fname,5,*,288,*"; 851 } else { 852 push @replace, "CDEF:x$fname=$fname,300,*,288,*"; 853 } 854 } 855 } 856 push @replace, $pre . ":x$fname" . $post; 857 splice (@rrd_sum, $index, 1, @replace); 858 $index++; 859 } elsif ($rrd_sum[$index] =~ /^(--lower-limit|--upper-limit|-l|-u)$/) { 860 $index++; 861 $rrd_sum[$index] = $rrd_sum[$index] * 300 * $sumtimes{$time}->[1]; 862 } 863 } 864 865 unless ($labelled) { 866 my $label = munin_get ($service, "graph_vlabel_sum_$time", $sumtimes{$time}->[0]); 867 unshift @rrd_sum, "--vertical-label", $label; 868 } 869 870 print "\n\nrrdtool \"graph\" \"", join ("\"\n\t\"",@rrd_sum), "\"\n" if $DEBUG; 871 872 # Make sure directory exists 873 munin_mkdir_p ($picdirname, 0777); 874 875 RRDs::graph (@rrd_sum); 876 922 877 if (my $ERROR = RRDs::error) { 923 878 logger ("Unable to graph $filename: $ERROR"); 924 879 } elsif ($list_images) { 925 880 # Command-line option to list images created 926 print &munin_get_picture_filename ($config, $domain, $name, 927 $service, $time),"\n"; 928 } 929 } 930 931 if (&munin_get_bool_val ($node->{client}->{$service}->{"graph_sums"}, 0)) { 932 foreach my $time (keys %sumtimes) { 933 next unless ($draw{"sum".$time}); 934 my @rrd_sum; 935 push @rrd_sum, @{&get_header ($node, $config, $domain, $name, $service, $time, 1)}; 936 937 if (time - 300 < $lastupdate) { 938 push @rrd_sum, "--end",(int($lastupdate/$resolutions{$time}))*$resolutions{$time}; 939 } 940 push @rrd_sum, @rrd; 941 push (@rrd_sum, "COMMENT:Last update$RRDkludge: " . RRDescape(scalar localtime($lastupdate)) . "\\r"); 942 943 my $labelled = 0; 944 my @defined = (); 945 for (my $index = 0; $index <= $#rrd_sum; $index++) { 946 if ($rrd_sum[$index] =~ /^(--vertical-label|-v)$/) { 947 (my $label = $node->{client}->{$service}->{graph_vlabel}) =~ s/\$\{graph_period\}/$sumtimes{$time}[0]/g; 948 splice (@rrd_sum, $index, 2, ("--vertical-label", $label)); 949 $index++; 950 $labelled++; 951 } elsif ($rrd_sum[$index] =~ /^(LINE[123]|STACK|AREA|GPRINT):([^#:]+)([#:].+)$/) { 952 my ($pre, $fname, $post) = ($1, $2, $3); 953 next if $fname eq "re_zero"; 954 if ($post =~ /^:AVERAGE/) { 955 splice (@rrd_sum, $index, 1, $pre . ":x$fname" . $post); 956 $index++; 957 next; 958 } 959 next if grep /^x$fname$/, @defined; 960 push @defined, "x$fname"; 961 my @replace; 962 963 if (!defined ($node->{client}->{$service}->{$fname.".type"}) or 964 $node->{client}->{$service}->{$fname.".type"} ne "GAUGE") { 965 if ($time eq "week") { 966 # Every plot is half an hour. Add two plots and multiply, to get per hour 967 if (graph_by_minute ($config, $domain, $name, $service)) { 968 # Already multiplied by 60 969 push @replace, "CDEF:x$fname=PREV($fname),UN,0,PREV($fname),IF,$fname,+,5,*,6,*"; 970 } else { 971 push @replace, "CDEF:x$fname=PREV($fname),UN,0,PREV($fname),IF,$fname,+,300,*,6,*"; 972 } 973 } else { 974 # Every plot is one day exactly. Just multiply. 975 if (graph_by_minute ($config, $domain, $name, $service)) { 976 # Already multiplied by 60 977 push @replace, "CDEF:x$fname=$fname,5,*,288,*"; 978 } else { 979 push @replace, "CDEF:x$fname=$fname,300,*,288,*"; 980 } 981 } 982 } 983 push @replace, $pre . ":x$fname" . $post; 984 splice (@rrd_sum, $index, 1, @replace); 985 $index++; 986 } elsif ($rrd_sum[$index] =~ /^(--lower-limit|--upper-limit|-l|-u)$/) { 987 $index++; 988 $rrd_sum[$index] = $rrd_sum[$index] * 300 * $sumtimes{$time}->[1]; 989 } 990 } 991 992 unless ($labelled) { 993 my $label = $node->{client}->{$service}->{"graph_vlabel_sum_$time"} || $sumtimes{$time}->[0]; 994 unshift @rrd_sum, "--vertical-label", $label; 995 } 996 997 print "\n\nrrdtool \"graph\" \"", join ("\"\n\t\"",@rrd_sum), "\"\n" if $DEBUG; 998 RRDs::graph (@rrd_sum); 999 1000 if (my $ERROR = RRDs::error) { 1001 logger ("Unable to graph $filename: $ERROR"); 1002 } elsif ($list_images) { 1003 # Command-line option to list images created 1004 print &munin_get_picture_filename ($config, $domain, $name, $service, $time, 1), "\n"; 1005 } 1006 } 1007 } 1008 1009 $service_time = sprintf ("%.2f",(Time::HiRes::time - $service_time)); 1010 logger ("Graphed service : $service ($service_time sec * 4)"); 1011 print STATS "GS|$domain|$name|$service|$service_time\n" unless $skip_stats; 1012 1013 foreach (@added) { 1014 delete $node->{client}->{$service}->{$_} 1015 if exists $node->{client}->{$service}->{$_}; 1016 } 1017 @added = (); 1018 } 881 print munin_get_picture_filename ($service, $time, 1),"\n"; 882 } 883 } 884 } 885 886 $service_time = sprintf ("%.2f",(Time::HiRes::time - $service_time)); 887 logger ("Graphed service : $sname ($service_time sec * 4)"); 888 print STATS "GS|$service_time\n" unless $skip_stats; 889 890 foreach (@added) { 891 delete $service->{$_} if exists $service->{$_}; 892 } 893 @added = (); 1019 894 } 1020 895 1021 896 sub graph_by_minute { 1022 my $config = shift;1023 my $domain = shift;1024 my $name = shift;1025 897 my $service = shift; 1026 898 1027 return (munin_get ($ config, "graph_period", "second", $domain, $name, $service) eq "minute");899 return (munin_get ($service, "graph_period", "second") eq "minute"); 1028 900 } 1029 901 1030 902 sub orig_to_cdef { 903 my $service = shift; 904 my $fieldname = shift; 905 906 return undef unless ref ($service) eq "HASH"; 907 908 if (defined $service->{$fieldname}->{"cdef_name"}) { 909 return orig_to_cdef ($service, $service->{$fieldname}->{"cdef_name"}); 910 } 911 return $fieldname; 912 } 913 914 sub skip_service { 1031 915 my $service = shift; 1032 my $field = shift; 1033 1034 if (defined $service->{$field.".cdef_name"}) 1035 { 1036 return &orig_to_cdef ($service, $service->{$field.".cdef_name"}); 1037 } 1038 return $field; 1039 } 1040 1041 sub set_cdef_name { 1042 my $service = shift; 1043 my $field = shift; 1044 my $new = shift; 1045 1046 $service->{$field.".cdef_name"} = $new; 1047 print "DEBUG: set_cdef_name from $field to $new.\n" if $DEBUG; 1048 } 1049 1050 sub skip_service { 1051 my $node = shift; 1052 my $service = shift; 1053 1054 # Check to make sure that service exists 1055 return 1 unless (ref $node->{client}->{$service}); 916 917 # Always graph if --force is present 918 return 0 if $force_graphing; 1056 919 1057 920 # See if we should skip it because of conf-options 1058 return 1 if ($node->{client}->{$service}->{'graph'} and 1059 ($node->{client}->{$service}->{'graph'} eq "no" || 1060 ($node->{client}->{$service}->{'graph'} eq "on-demand") && !$force_graphing)); 1061 1062 # See if we should skip it because of command-line arguments 1063 return 1 if (@limit_services and not grep (/^$service$/, @limit_services)); 921 return 1 if (munin_get ($service, "graph", "yes") eq "on-demand" or 922 !munin_get_bool ($service, "graph", 1)); 1064 923 1065 924 # Don't skip … … 1089 948 } 1090 949 1091 &set_cdef_name ($service, $$cfield_ref, $new_field);950 munin_set_var_loc ($service, [$$cfield_ref, "cdef_name"], $new_field); 1092 951 $$cfield_ref = $new_field; 1093 952 people/jo/multilevel-groups/server/munin-update.in
r1292 r1293 1010 1010 } 1011 1011 } 1012 munin_set_var_loc ($newconf, [ "graph_order"], join(' ',@graph_order));1012 munin_set_var_loc ($newconf, [$servname, "graph_order"], join(' ',@graph_order)); 1013 1013 } 1014 1014 return 0 unless $socket;
