root / plugins / virtualization / libvirt @ c5ab6538
Historique | Voir | Annoter | Télécharger (50,5 ko)
| 1 | 964579f7 | Espen Braastad | #!/usr/bin/perl -w |
|---|---|---|---|
| 2 | # $Id: libvirt 24900 2010-03-30 13:50:40Z espen $ |
||
| 3 | # |
||
| 4 | # Copyright (C) 2010 Espen Braastad |
||
| 5 | # |
||
| 6 | # This program is free software; you can redistribute it and/or |
||
| 7 | # modify it under the terms of the GNU General Public License |
||
| 8 | # as published by the Free Software Foundation; version 2 dated June, |
||
| 9 | # 1991. |
||
| 10 | # |
||
| 11 | # This program is distributed in the hope that it will be useful, |
||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 14 | # GNU General Public License for more details. |
||
| 15 | # |
||
| 16 | # You should have received a copy of the GNU General Public License |
||
| 17 | # along with this program; if not, write to the Free Software |
||
| 18 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||
| 19 | # |
||
| 20 | # |
||
| 21 | # This multigraph plugin monitors libvirt resource usage. |
||
| 22 | # |
||
| 23 | # Configuration variables: |
||
| 24 | # |
||
| 25 | # General variables: |
||
| 26 | # address - to libvirt (default "xen:///") |
||
| 27 | # username - to libvirt (default: "") |
||
| 28 | # password - to libvirt (default: "") |
||
| 29 | # tmpfile - to cache values (default: "/var/lib/munin/plugin-state/libvirt") |
||
| 30 | # |
||
| 31 | # Variables to enable or disable graphs: |
||
| 32 | # show_cpu_used - 1 to enable, 0 to disable [default = 1] |
||
| 33 | # show_disk_traffic - 1 to enable, 0 to disable [default = 1] |
||
| 34 | # show_disk_utilization - 1 to enable, 0 to disable [default = 1] |
||
| 35 | # show_disk_latency - 1 to enable, 0 to disable [default = 1] |
||
| 36 | # show_memory_allocated - 1 to enable, 0 to disable [default = 1] |
||
| 37 | # show_network_traffic - 1 to enable, 0 to disable [default = 1] |
||
| 38 | # show_network_drops - 1 to enable, 0 to disable [default = 1] |
||
| 39 | # |
||
| 40 | # Requirements: |
||
| 41 | # RHEL5: perl-Sys-Virt.x86_64 |
||
| 42 | # |
||
| 43 | # Revision 1.4 2010/03/30 espen |
||
| 44 | # Added graphs for i/o utilization |
||
| 45 | # |
||
| 46 | # Revision 1.3 2010/03/29 espen |
||
| 47 | # Added graphs for i/o latency |
||
| 48 | # |
||
| 49 | # Revision 1.2 2010/03/19 espen |
||
| 50 | # Added support for enable/disable graphs from plugin-conf.d. |
||
| 51 | # Added graphs for disk errors and network drops. |
||
| 52 | # |
||
| 53 | # Revision 1.1 2010/03/14 espen |
||
| 54 | # Added support for monitoring network (bits) and disk (bytes) usage. |
||
| 55 | # |
||
| 56 | # Revision 1.0 2010/03/11 espen |
||
| 57 | # Initial version. Support for cpu and memory per domain. |
||
| 58 | # |
||
| 59 | #%# family=auto |
||
| 60 | #%# capabilities=autoconf |
||
| 61 | |||
| 62 | use strict; |
||
| 63 | use XML::Twig; |
||
| 64 | use Sys::Virt; |
||
| 65 | use Sys::Virt::Domain; |
||
| 66 | use File::stat; |
||
| 67 | use Storable; |
||
| 68 | use Time::localtime; |
||
| 69 | |||
| 70 | my $address = $ENV{address} || "xen:///";
|
||
| 71 | my $username = $ENV{username} || "";
|
||
| 72 | my $password = $ENV{password} || "";
|
||
| 73 | my $tmpfile = $ENV{tmpfile} || "/var/lib/munin/plugin-state/libvirt";
|
||
| 74 | my $decimals=5; |
||
| 75 | |||
| 76 | my %show=(); |
||
| 77 | |||
| 78 | # Reading values from plugin-conf.d or set defaults. |
||
| 79 | $show{'cpu_used'} = $ENV{show_cpu_used} || 1;
|
||
| 80 | $show{'disk_traffic'} = $ENV{show_disk_traffic} || 1;
|
||
| 81 | $show{'disk_utilization'} = $ENV{show_disk_utilization} || 1;
|
||
| 82 | $show{'disk_latency'} = $ENV{show_disk_latency} || 1;
|
||
| 83 | $show{'disk_errors'} = $ENV{show_disk_errors} || 1;
|
||
| 84 | $show{'memory_allocated'} = $ENV{show_memory_allocated} || 1;
|
||
| 85 | $show{'network_traffic'} = $ENV{show_network_traffic} || 1;
|
||
| 86 | $show{'network_drops'} = $ENV{show_network_drops} || 1;
|
||
| 87 | |||
| 88 | sub init() {
|
||
| 89 | my $type=undef; |
||
| 90 | |||
| 91 | if ($ARGV[0] and $ARGV[0] eq "config"){
|
||
| 92 | $type="config"; |
||
| 93 | } |
||
| 94 | if ($ARGV[0] and $ARGV[0] eq "autoconf"){
|
||
| 95 | &autoconf(); |
||
| 96 | exit; |
||
| 97 | } |
||
| 98 | if(!$ARGV[0]){
|
||
| 99 | $type="fetch"; |
||
| 100 | } |
||
| 101 | |||
| 102 | if(!defined($type)){
|
||
| 103 | print "Argument not supported, see the howto.\n"; |
||
| 104 | } |
||
| 105 | |||
| 106 | # Connecting to libvirt |
||
| 107 | my $vmm=&connect(); |
||
| 108 | |||
| 109 | my @domains = $vmm->list_domains(); |
||
| 110 | |||
| 111 | my %hash=(); |
||
| 112 | |||
| 113 | my $node = $vmm->get_node_info(); |
||
| 114 | # 'model' => 'x86_64', |
||
| 115 | # 'threads' => 2, |
||
| 116 | # 'cores' => 4, |
||
| 117 | # 'memory' => 33545216, |
||
| 118 | # 'mhz' => 2261, |
||
| 119 | # 'sockets' => 2, |
||
| 120 | # 'nodes' => 1, |
||
| 121 | # 'cpus' => 16 |
||
| 122 | |||
| 123 | foreach my $domain (@domains) {
|
||
| 124 | |||
| 125 | my $name = $domain->get_name(); |
||
| 126 | $hash{$name}{'name'} = $name;
|
||
| 127 | $hash{$name}{'id'} = $domain->get_id();
|
||
| 128 | $hash{$name}{'info'} = $domain->get_info();
|
||
| 129 | $hash{$name}{'maxvcpus'} = $domain->get_max_vcpus();
|
||
| 130 | $hash{$name}{'maxmem'} = $domain->get_max_memory();
|
||
| 131 | $hash{$name}{'type'} = $domain->get_os_type();
|
||
| 132 | $hash{$name}{'scheduler'} = $domain->get_scheduler_type();
|
||
| 133 | $hash{$name}{'xml'} = parse_xml($domain->get_xml_description());
|
||
| 134 | $hash{$name}{'label'} = clean_label($name);
|
||
| 135 | |||
| 136 | # Calculate cputime used in percent |
||
| 137 | if(defined($hash{$name}{'info'}{'cpuTime'}) && defined($node->{'cpus'})){
|
||
| 138 | $hash{$name}{'info'}{'cpuPercentage'} = sprintf("%d",1.0e-7 * $hash{$name}{'info'}{'cpuTime'} / $node->{'cpus'});
|
||
| 139 | } |
||
| 140 | |||
| 141 | # Calculate bytes |
||
| 142 | if(defined($hash{$name}{'info'}{'memory'})){
|
||
| 143 | $hash{$name}{'info'}{'memory_bytes'} = 1024 * $hash{$name}{'info'}{'memory'};
|
||
| 144 | } |
||
| 145 | |||
| 146 | # Extract network usage |
||
| 147 | if(defined($hash{$name}{'xml'}{'devices'}{'interface'}{'bridge'})){
|
||
| 148 | my $vif_id=0; |
||
| 149 | for my $vif (keys %{$hash{$name}{'xml'}{'devices'}{'interface'}{'bridge'}}){
|
||
| 150 | $hash{$name}{'devices'}{'network'}{$vif}=$domain->interface_stats($vif);
|
||
| 151 | |||
| 152 | # The interface number on this $VM. Will be used as ID later in labels |
||
| 153 | $hash{$name}{'devices'}{'network'}{$vif}{'vif_id'}=$vif_id;
|
||
| 154 | $vif_id++; |
||
| 155 | } |
||
| 156 | } |
||
| 157 | |||
| 158 | # Extract block device usage |
||
| 159 | if(defined($hash{$name}{'xml'}{'devices'}{'disk'}{'block'})){
|
||
| 160 | for my $block (keys %{$hash{$name}{'xml'}{'devices'}{'disk'}{'block'}}){
|
||
| 161 | $hash{$name}{'devices'}{'block'}{$block}=$domain->block_stats($block);
|
||
| 162 | } |
||
| 163 | } |
||
| 164 | |||
| 165 | # Gather data later used to calculate latency and utilization |
||
| 166 | if(defined($hash{$name}{'xml'}{'devices'}{'disk'}{'block'})){
|
||
| 167 | for my $block (keys %{$hash{$name}{'xml'}{'devices'}{'disk'}{'block'}}){
|
||
| 168 | if(defined($hash{$name}{'devices'}{'block'}{$block})){
|
||
| 169 | my $source_dev=$hash{$name}{'xml'}{'devices'}{'disk'}{'block'}{$block}{'source'};
|
||
| 170 | $hash{$name}{'devices'}{'block'}{$block}{'source'}{$source_dev}=read_diskstats($source_dev);
|
||
| 171 | } |
||
| 172 | } |
||
| 173 | } |
||
| 174 | } |
||
| 175 | |||
| 176 | my $prev_time=&get_prev_time($tmpfile); |
||
| 177 | my $time=time(); |
||
| 178 | my $prev_state_ref=undef; |
||
| 179 | |||
| 180 | # Cache the result to disk if we graphs that require cache are enabled |
||
| 181 | if($show{'disk_latency'} == 1 || $show{'disk_utilization'} == 1){
|
||
| 182 | if(-e $tmpfile){
|
||
| 183 | $prev_state_ref=retrieve($tmpfile); |
||
| 184 | } |
||
| 185 | |||
| 186 | store(\%hash,$tmpfile); |
||
| 187 | } |
||
| 188 | |||
| 189 | # |
||
| 190 | # Disk utilization |
||
| 191 | # |
||
| 192 | |||
| 193 | if($show{'disk_utilization'} == 1){
|
||
| 194 | |||
| 195 | # |
||
| 196 | # Disk utilization, top level |
||
| 197 | # |
||
| 198 | |||
| 199 | if($type eq "config"){
|
||
| 200 | print "multigraph libvirt_disk_utilization\n"; |
||
| 201 | #print "graph_order rd wr\n"; |
||
| 202 | print "graph_title Disk utilization per domain in percent\n"; |
||
| 203 | print "graph_vlabel %\n"; |
||
| 204 | print "graph_category Virtualization\n"; |
||
| 205 | print "graph_args -l 0 --base 1000 --upper-limit 100\n"; |
||
| 206 | #print "graph_width 550\n"; |
||
| 207 | |||
| 208 | for my $vm (sort keys %hash) {
|
||
| 209 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 210 | print $hash{$vm}{'label'} . ".label " . $hash{$vm}{'name'} . "\n";
|
||
| 211 | print $hash{$vm}{'label'} . ".info The maximum I/O utilization in percent on " . $hash{$vm}{'name'} . ". If the time spent for I/O is close to 1000 msec for a given second, the device is nearly 100% saturated. If the virtual machine have more than one disk, the value from the disk with the highest utilization is being shown.\n";
|
||
| 212 | print $hash{$vm}{'label'} . ".min 0\n";
|
||
| 213 | print $hash{$vm}{'label'} . ".draw LINE2\n";
|
||
| 214 | } |
||
| 215 | } |
||
| 216 | print "\n"; |
||
| 217 | |||
| 218 | } elsif($type eq "fetch"){
|
||
| 219 | print "multigraph libvirt_disk_utilization\n"; |
||
| 220 | for my $vm (sort keys %hash) {
|
||
| 221 | if(defined($hash{$vm}{'devices'}{'block'}) && defined($prev_state_ref->{$vm}->{'devices'}->{'block'})){
|
||
| 222 | |||
| 223 | my $utilization=0; |
||
| 224 | |||
| 225 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 226 | |||
| 227 | if(defined($prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device})){
|
||
| 228 | |||
| 229 | for my $source_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}}){
|
||
| 230 | |||
| 231 | for my $slave_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}}){
|
||
| 232 | |||
| 233 | my $prev_ms_spent_doing_io=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'io_ticks'};
|
||
| 234 | my $cur_ms_spent_doing_io=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'io_ticks'};
|
||
| 235 | |||
| 236 | if($cur_ms_spent_doing_io > $prev_ms_spent_doing_io){
|
||
| 237 | my $ticks=$cur_ms_spent_doing_io-$prev_ms_spent_doing_io; |
||
| 238 | my $interval_ms=($time-$prev_time)*1000; |
||
| 239 | if($interval_ms > 0){
|
||
| 240 | my $dev_utilization=($ticks/$interval_ms)*100; |
||
| 241 | |||
| 242 | # Will only print show the highest utilization on each VM on the top level graph |
||
| 243 | if($dev_utilization > $utilization){
|
||
| 244 | $utilization=sprintf("%.${decimals}f",$dev_utilization);
|
||
| 245 | } |
||
| 246 | } |
||
| 247 | } |
||
| 248 | } |
||
| 249 | } |
||
| 250 | } |
||
| 251 | } |
||
| 252 | print $hash{$vm}{'label'} . ".value " . $utilization . "\n";
|
||
| 253 | } |
||
| 254 | } |
||
| 255 | print "\n"; |
||
| 256 | } |
||
| 257 | |||
| 258 | # |
||
| 259 | # Disk utilization, second level |
||
| 260 | # |
||
| 261 | |||
| 262 | for my $vm (sort keys %hash) {
|
||
| 263 | my $devices=0; |
||
| 264 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 265 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 266 | $devices++; |
||
| 267 | } |
||
| 268 | } |
||
| 269 | if($type eq "config"){
|
||
| 270 | print "multigraph libvirt_disk_utilization." . $hash{$vm}{'label'} . "\n";
|
||
| 271 | #print "graph_order rd wr\n"; |
||
| 272 | print "graph_title Disk utilization on " . $vm . " in percent\n"; |
||
| 273 | print "graph_vlabel %\n"; |
||
| 274 | print "graph_category Virtualization\n"; |
||
| 275 | print "graph_args -l 0 --base 1000 --upper-limit 100\n"; |
||
| 276 | #print "graph_width 550\n"; |
||
| 277 | |||
| 278 | if($devices>0){
|
||
| 279 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 280 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 281 | print $hash{$vm}{'label'} . "_" . $device . ".label " . $device . "\n";
|
||
| 282 | print $hash{$vm}{'label'} . "_" . $device . ".info The maximum I/O utilization in percent on " . $device . ". If the time spent for I/O is close to 1000 msec for a given second, the device is nearly 100% saturated.\n";
|
||
| 283 | print $hash{$vm}{'label'} . "_" . $device . ".min 0\n";
|
||
| 284 | print $hash{$vm}{'label'} . "_" . $device . ".draw LINE2\n";
|
||
| 285 | } |
||
| 286 | } |
||
| 287 | } |
||
| 288 | print "\n"; |
||
| 289 | |||
| 290 | } elsif($type eq "fetch"){
|
||
| 291 | if($devices > 0){
|
||
| 292 | print "multigraph libvirt_disk_utilization." . $hash{$vm}{'label'} . "\n";
|
||
| 293 | if(defined($hash{$vm}{'devices'}{'block'}) && defined($prev_state_ref->{$vm}->{'devices'}->{'block'})){
|
||
| 294 | |||
| 295 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 296 | |||
| 297 | my $utilization=0; |
||
| 298 | |||
| 299 | if(defined($prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device})){
|
||
| 300 | |||
| 301 | for my $source_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}}){
|
||
| 302 | |||
| 303 | for my $slave_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}}){
|
||
| 304 | |||
| 305 | my $prev_ms_spent_doing_io=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'io_ticks'};
|
||
| 306 | my $cur_ms_spent_doing_io=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'io_ticks'};
|
||
| 307 | |||
| 308 | if($cur_ms_spent_doing_io > $prev_ms_spent_doing_io){
|
||
| 309 | my $ticks=$cur_ms_spent_doing_io-$prev_ms_spent_doing_io; |
||
| 310 | my $interval_ms=($time-$prev_time)*1000; |
||
| 311 | if($interval_ms > 0){
|
||
| 312 | my $dev_utilization=($ticks/$interval_ms)*100; |
||
| 313 | $utilization=sprintf("%.${decimals}f",$dev_utilization);
|
||
| 314 | } |
||
| 315 | } |
||
| 316 | } |
||
| 317 | } |
||
| 318 | } |
||
| 319 | print $hash{$vm}{'label'} . "_" . $device . ".value " . $utilization . "\n";
|
||
| 320 | } |
||
| 321 | } |
||
| 322 | print "\n"; |
||
| 323 | } |
||
| 324 | } |
||
| 325 | } |
||
| 326 | } |
||
| 327 | |||
| 328 | # |
||
| 329 | # Disk latency |
||
| 330 | # |
||
| 331 | |||
| 332 | if($show{'disk_latency'} == 1){
|
||
| 333 | |||
| 334 | # |
||
| 335 | # Disk latency, top level |
||
| 336 | # |
||
| 337 | |||
| 338 | if($type eq "config"){
|
||
| 339 | print "multigraph libvirt_disk_latency\n"; |
||
| 340 | #print "graph_order rd wr\n"; |
||
| 341 | print "graph_title Disk latency per domain in seconds\n"; |
||
| 342 | print "graph_args --base 1000\n"; |
||
| 343 | print "graph_vlabel read (-) / write (+)\n"; |
||
| 344 | print "graph_category Virtualization\n"; |
||
| 345 | #print "graph_width 550\n"; |
||
| 346 | |||
| 347 | for my $vm (sort keys %hash) {
|
||
| 348 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 349 | |||
| 350 | # Will only graph the domains with one or more block device |
||
| 351 | my $devices=0; |
||
| 352 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 353 | $devices++; |
||
| 354 | } |
||
| 355 | if($devices > 0){
|
||
| 356 | print $hash{$vm}{'label'} . "_rd.label " . $hash{$vm}{'name'} . "_rd\n";
|
||
| 357 | print $hash{$vm}{'label'} . "_rd.info I/O latency in seconds on " . $hash{$vm}{'name'} . "\n";
|
||
| 358 | print $hash{$vm}{'label'} . "_rd.min 0\n";
|
||
| 359 | print $hash{$vm}{'label'} . "_rd.draw LINE2\n";
|
||
| 360 | print $hash{$vm}{'label'} . "_rd.graph no\n";
|
||
| 361 | |||
| 362 | print $hash{$vm}{'label'} . "_wr.label " . $hash{$vm}{'name'} . "\n";
|
||
| 363 | print $hash{$vm}{'label'} . "_wr.info I/O latency in seconds on " . $hash{$vm}{'name'} . "\n";
|
||
| 364 | print $hash{$vm}{'label'} . "_wr.min 0\n";
|
||
| 365 | print $hash{$vm}{'label'} . "_wr.draw LINE2\n";
|
||
| 366 | print $hash{$vm}{'label'} . "_wr.negative " . $hash{$vm}{'label'} . "_rd\n";
|
||
| 367 | } |
||
| 368 | } |
||
| 369 | } |
||
| 370 | print "\n"; |
||
| 371 | |||
| 372 | } elsif($type eq "fetch"){
|
||
| 373 | print "multigraph libvirt_disk_latency\n"; |
||
| 374 | for my $vm (sort keys %hash) {
|
||
| 375 | if(defined($hash{$vm}{'devices'}{'block'}) && defined($prev_state_ref->{$vm}->{'devices'}->{'block'})){
|
||
| 376 | |||
| 377 | my $prev_total_time_spent_writing=0; |
||
| 378 | my $prev_total_time_spent_reading=0; |
||
| 379 | my $prev_total_ios_read=0; |
||
| 380 | my $prev_total_ios_written=0; |
||
| 381 | my $cur_total_time_spent_writing=0; |
||
| 382 | my $cur_total_time_spent_reading=0; |
||
| 383 | my $cur_total_ios_read=0; |
||
| 384 | my $cur_total_ios_written=0; |
||
| 385 | |||
| 386 | my $devices=0; |
||
| 387 | |||
| 388 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 389 | $devices++; |
||
| 390 | |||
| 391 | if(defined($prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device})){
|
||
| 392 | |||
| 393 | for my $source_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}}){
|
||
| 394 | |||
| 395 | for my $slave_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}}){
|
||
| 396 | |||
| 397 | my $prev_time_spent_writing=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'write_ticks'};
|
||
| 398 | my $prev_time_spent_reading=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'read_ticks'};
|
||
| 399 | my $prev_ios_read=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'read_ios'};
|
||
| 400 | my $prev_ios_written=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'write_ios'};
|
||
| 401 | |||
| 402 | my $cur_time_spent_writing=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'write_ticks'};
|
||
| 403 | my $cur_time_spent_reading=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'read_ticks'};
|
||
| 404 | my $cur_ios_read=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'read_ios'};
|
||
| 405 | my $cur_ios_written=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'write_ios'};
|
||
| 406 | |||
| 407 | $prev_total_time_spent_writing+=$prev_time_spent_writing; |
||
| 408 | $prev_total_time_spent_reading+=$prev_time_spent_reading; |
||
| 409 | $prev_total_ios_read+=$prev_ios_read; |
||
| 410 | $prev_total_ios_written+=$prev_ios_written; |
||
| 411 | |||
| 412 | $cur_total_time_spent_writing+=$cur_time_spent_writing; |
||
| 413 | $cur_total_time_spent_reading+=$cur_time_spent_reading; |
||
| 414 | $cur_total_ios_read+=$cur_ios_read; |
||
| 415 | $cur_total_ios_written+=$cur_ios_written; |
||
| 416 | } |
||
| 417 | } |
||
| 418 | } |
||
| 419 | } |
||
| 420 | |||
| 421 | my $read_latency=0; |
||
| 422 | my $write_latency=0; |
||
| 423 | |||
| 424 | if($prev_total_time_spent_reading > 0 && $prev_total_ios_read > 0 && ($cur_total_ios_read-$prev_total_ios_read) > 0){
|
||
| 425 | $read_latency=(($cur_total_time_spent_reading-$prev_total_time_spent_reading)/($cur_total_ios_read-$prev_total_ios_read))/1000; |
||
| 426 | } |
||
| 427 | |||
| 428 | if($prev_total_time_spent_writing > 0 && $prev_total_ios_written > 0 && ($cur_total_ios_written-$prev_total_ios_written) > 0){
|
||
| 429 | $write_latency=(($cur_total_time_spent_writing-$prev_total_time_spent_writing)/($cur_total_ios_written-$prev_total_ios_written))/1000; |
||
| 430 | } |
||
| 431 | |||
| 432 | if($devices > 0){
|
||
| 433 | print $hash{$vm}{'label'} . "_rd.value " . $read_latency . "\n";
|
||
| 434 | print $hash{$vm}{'label'} . "_wr.value " . $write_latency . "\n";
|
||
| 435 | } |
||
| 436 | } |
||
| 437 | } |
||
| 438 | print "\n"; |
||
| 439 | } |
||
| 440 | |||
| 441 | # |
||
| 442 | # Disk latency, second level |
||
| 443 | # |
||
| 444 | |||
| 445 | for my $vm (sort keys %hash) {
|
||
| 446 | my $devices=0; |
||
| 447 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 448 | $devices++; |
||
| 449 | } |
||
| 450 | if($devices > 0){
|
||
| 451 | if($type eq "config"){
|
||
| 452 | print "multigraph libvirt_disk_latency.$hash{$vm}{'label'}\n";
|
||
| 453 | #print "graph_order rd wr\n"; |
||
| 454 | print "graph_title Disk latency per vbd on $vm in seconds\n"; |
||
| 455 | print "graph_args --base 1000\n"; |
||
| 456 | print "graph_vlabel read (-) / write (+)\n"; |
||
| 457 | print "graph_category Virtualization\n"; |
||
| 458 | #print "graph_width 550\n"; |
||
| 459 | |||
| 460 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 461 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 462 | |||
| 463 | print $hash{$vm}{'label'} . "_" . $device . "_rd.label " . $device . "_rd\n";
|
||
| 464 | print $hash{$vm}{'label'} . "_" . $device . "_rd.info I/O latency in seconds on " . $hash{$vm}{'name'} . ":" . $device . "\n";
|
||
| 465 | print $hash{$vm}{'label'} . "_" . $device . "_rd.min 0\n";
|
||
| 466 | print $hash{$vm}{'label'} . "_" . $device . "_rd.draw LINE2\n";
|
||
| 467 | print $hash{$vm}{'label'} . "_" . $device . "_rd.graph no\n";
|
||
| 468 | |||
| 469 | print $hash{$vm}{'label'} . "_" . $device . "_wr.label " . $device . "\n";
|
||
| 470 | print $hash{$vm}{'label'} . "_" . $device . "_wr.info I/O latency in seconds on " . $hash{$vm}{'name'} . ":" . $device . "\n";
|
||
| 471 | print $hash{$vm}{'label'} . "_" . $device . "_wr.min 0\n";
|
||
| 472 | print $hash{$vm}{'label'} . "_" . $device . "_wr.draw LINE2\n";
|
||
| 473 | print $hash{$vm}{'label'} . "_" . $device . "_wr.negative " . $hash{$vm}{'label'} . "_" . $device . "_rd\n";
|
||
| 474 | } |
||
| 475 | print "\n"; |
||
| 476 | } |
||
| 477 | |||
| 478 | } elsif($type eq "fetch"){
|
||
| 479 | print "multigraph libvirt_disk_latency.$hash{$vm}{'label'}\n";
|
||
| 480 | if(defined($hash{$vm}{'devices'}{'block'}) && defined($prev_state_ref->{$vm}->{'devices'}->{'block'})){
|
||
| 481 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 482 | |||
| 483 | if(defined($prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device})){
|
||
| 484 | |||
| 485 | for my $source_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}}){
|
||
| 486 | |||
| 487 | my $prev_total_time_spent_writing=0; |
||
| 488 | my $prev_total_time_spent_reading=0; |
||
| 489 | my $prev_total_ios_read=0; |
||
| 490 | my $prev_total_ios_written=0; |
||
| 491 | my $cur_total_time_spent_writing=0; |
||
| 492 | my $cur_total_time_spent_reading=0; |
||
| 493 | my $cur_total_ios_read=0; |
||
| 494 | my $cur_total_ios_written=0; |
||
| 495 | |||
| 496 | for my $slave_device (keys %{$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}}){
|
||
| 497 | |||
| 498 | my $prev_time_spent_writing=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'write_ticks'};
|
||
| 499 | my $prev_time_spent_reading=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'read_ticks'};
|
||
| 500 | my $prev_ios_read=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'read_ios'};
|
||
| 501 | my $prev_ios_written=$prev_state_ref->{$vm}->{'devices'}->{'block'}->{$device}->{'source'}->{$source_device}->{'slaves'}->{$slave_device}->{'write_ios'};
|
||
| 502 | |||
| 503 | my $cur_time_spent_writing=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'write_ticks'};
|
||
| 504 | my $cur_time_spent_reading=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'read_ticks'};
|
||
| 505 | my $cur_ios_read=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'read_ios'};
|
||
| 506 | my $cur_ios_written=$hash{$vm}{'devices'}{'block'}{$device}{'source'}{$source_device}{'slaves'}{$slave_device}{'write_ios'};
|
||
| 507 | |||
| 508 | $prev_total_time_spent_writing+=$prev_time_spent_writing; |
||
| 509 | $prev_total_time_spent_reading+=$prev_time_spent_reading; |
||
| 510 | $prev_total_ios_read+=$prev_ios_read; |
||
| 511 | $prev_total_ios_written+=$prev_ios_written; |
||
| 512 | |||
| 513 | $cur_total_time_spent_writing+=$cur_time_spent_writing; |
||
| 514 | $cur_total_time_spent_reading+=$cur_time_spent_reading; |
||
| 515 | $cur_total_ios_read+=$cur_ios_read; |
||
| 516 | $cur_total_ios_written+=$cur_ios_written; |
||
| 517 | } |
||
| 518 | |||
| 519 | my $read_latency=0; |
||
| 520 | my $write_latency=0; |
||
| 521 | |||
| 522 | if($prev_total_time_spent_reading > 0 && $prev_total_ios_read > 0 && ($cur_total_ios_read-$prev_total_ios_read) > 0){
|
||
| 523 | $read_latency=(($cur_total_time_spent_reading-$prev_total_time_spent_reading)/($cur_total_ios_read-$prev_total_ios_read))/1000; |
||
| 524 | } |
||
| 525 | |||
| 526 | if($prev_total_time_spent_writing > 0 && $prev_total_ios_written > 0 && ($cur_total_ios_written-$prev_total_ios_written) > 0){
|
||
| 527 | $write_latency=(($cur_total_time_spent_writing-$prev_total_time_spent_writing)/($cur_total_ios_written-$prev_total_ios_written))/1000; |
||
| 528 | } |
||
| 529 | |||
| 530 | print $hash{$vm}{'label'} . "_" . $device . "_rd.value " . $read_latency . "\n";
|
||
| 531 | print $hash{$vm}{'label'} . "_" . $device . "_wr.value " . $write_latency . "\n";
|
||
| 532 | |||
| 533 | } |
||
| 534 | } |
||
| 535 | } |
||
| 536 | } |
||
| 537 | } |
||
| 538 | print "\n"; |
||
| 539 | } |
||
| 540 | } |
||
| 541 | } |
||
| 542 | |||
| 543 | if($show{'disk_traffic'} == 1){
|
||
| 544 | |||
| 545 | # |
||
| 546 | # Disk used, top level |
||
| 547 | # |
||
| 548 | |||
| 549 | if($type eq "config"){
|
||
| 550 | print "multigraph libvirt_disk\n"; |
||
| 551 | #print "graph_order rd wr\n"; |
||
| 552 | print "graph_title Disk traffic per domain in bytes\n"; |
||
| 553 | print "graph_args --base 1000\n"; |
||
| 554 | print "graph_vlabel bytes read (-) / written (+) per \${graph_period}\n";
|
||
| 555 | print "graph_category Virtualization\n"; |
||
| 556 | #print "graph_width 550\n"; |
||
| 557 | |||
| 558 | for my $vm (sort keys %hash) {
|
||
| 559 | my $devices=0; |
||
| 560 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 561 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 562 | $devices++; |
||
| 563 | } |
||
| 564 | } |
||
| 565 | |||
| 566 | if($devices > 0){
|
||
| 567 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 568 | |||
| 569 | print $hash{$vm}{'label'} . "_rd_bytes.label " . $hash{$vm}{'name'} . "\n";
|
||
| 570 | print $hash{$vm}{'label'} . "_rd_bytes.type COUNTER\n";
|
||
| 571 | print $hash{$vm}{'label'} . "_rd_bytes.info The number of bytes read by " . $hash{$vm}{'name'} . "\n";
|
||
| 572 | print $hash{$vm}{'label'} . "_rd_bytes.min 0\n";
|
||
| 573 | print $hash{$vm}{'label'} . "_rd_bytes.draw LINE2\n";
|
||
| 574 | print $hash{$vm}{'label'} . "_rd_bytes.graph no\n";
|
||
| 575 | |||
| 576 | print $hash{$vm}{'label'} . "_wr_bytes.label " . $hash{$vm}{'name'} . "\n";
|
||
| 577 | print $hash{$vm}{'label'} . "_wr_bytes.type COUNTER\n";
|
||
| 578 | print $hash{$vm}{'label'} . "_wr_bytes.info The number of bytes written by " . $hash{$vm}{'name'} . "\n";
|
||
| 579 | print $hash{$vm}{'label'} . "_wr_bytes.min 0\n";
|
||
| 580 | print $hash{$vm}{'label'} . "_wr_bytes.draw LINE2\n";
|
||
| 581 | print $hash{$vm}{'label'} . "_wr_bytes.negative " . $hash{$vm}{'label'} . "_rd_bytes\n";
|
||
| 582 | } |
||
| 583 | } |
||
| 584 | } |
||
| 585 | print "\n"; |
||
| 586 | |||
| 587 | } elsif($type eq "fetch"){
|
||
| 588 | print "multigraph libvirt_disk\n"; |
||
| 589 | for my $vm (sort keys %hash) {
|
||
| 590 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 591 | my $total_read=0; |
||
| 592 | my $total_write=0; |
||
| 593 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 594 | $total_read+=$hash{$vm}{'devices'}{'block'}{$device}{'rd_bytes'};
|
||
| 595 | $total_write+=$hash{$vm}{'devices'}{'block'}{$device}{'wr_bytes'};
|
||
| 596 | } |
||
| 597 | print $hash{$vm}{'label'} . "_rd_bytes.value " . $total_read . "\n";
|
||
| 598 | print $hash{$vm}{'label'} . "_wr_bytes.value " . $total_write . "\n";
|
||
| 599 | } |
||
| 600 | } |
||
| 601 | print "\n"; |
||
| 602 | } |
||
| 603 | |||
| 604 | # |
||
| 605 | # Disk used, second level |
||
| 606 | # |
||
| 607 | |||
| 608 | for my $vm (sort keys %hash) {
|
||
| 609 | my $devices=0; |
||
| 610 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 611 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 612 | $devices++; |
||
| 613 | } |
||
| 614 | } |
||
| 615 | |||
| 616 | if($devices > 0){
|
||
| 617 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 618 | if($type eq "config"){
|
||
| 619 | print "multigraph libvirt_disk.bytes_" . $hash{$vm}{'label'} . "\n";
|
||
| 620 | #print "graph_order rd wr\n"; |
||
| 621 | print "graph_title Disk traffic for " . $hash{$vm}{'name'} . "\n";
|
||
| 622 | print "graph_args --base 1000\n"; |
||
| 623 | print "graph_vlabel bytes read (-) / written (+) per \${graph_period}\n";
|
||
| 624 | print "graph_category Virtualization\n"; |
||
| 625 | #print "graph_width 550\n"; |
||
| 626 | |||
| 627 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 628 | print $device . "_rd_bytes.label " . $device . "_rd\n"; |
||
| 629 | print $device . "_rd_bytes.type COUNTER\n"; |
||
| 630 | print $device . "_rd_bytes.info The number of bytes read by " . $hash{$vm}{'name'} . "\n";
|
||
| 631 | print $device . "_rd_bytes.min 0\n"; |
||
| 632 | print $device . "_rd_bytes.graph no\n"; |
||
| 633 | |||
| 634 | print $device . "_wr_bytes.label " . $device . "\n"; |
||
| 635 | print $device . "_wr_bytes.type COUNTER\n"; |
||
| 636 | print $device . "_wr_bytes.info The number of bytes written by " . $hash{$vm}{'name'} . "\n";
|
||
| 637 | print $device . "_wr_bytes.min 0\n"; |
||
| 638 | print $device . "_wr_bytes.draw LINE2\n"; |
||
| 639 | print $device . "_wr_bytes.negative " . $device . "_rd_bytes\n"; |
||
| 640 | } |
||
| 641 | print "\n"; |
||
| 642 | |||
| 643 | } elsif($type eq "fetch"){
|
||
| 644 | print "multigraph libvirt_disk.bytes_" . $hash{$vm}{'label'} . "\n";
|
||
| 645 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 646 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 647 | print $device . "_rd_bytes.value " . $hash{$vm}{'devices'}{'block'}{$device}{'rd_bytes'} . "\n";
|
||
| 648 | print $device . "_wr_bytes.value " . $hash{$vm}{'devices'}{'block'}{$device}{'wr_bytes'} . "\n";
|
||
| 649 | } |
||
| 650 | } |
||
| 651 | print "\n"; |
||
| 652 | } |
||
| 653 | } |
||
| 654 | } |
||
| 655 | } |
||
| 656 | } |
||
| 657 | |||
| 658 | # |
||
| 659 | # Disk errors |
||
| 660 | # |
||
| 661 | # errs -> Some kind of error count |
||
| 662 | |||
| 663 | |||
| 664 | if($show{'disk_errors'} == 1){
|
||
| 665 | |||
| 666 | # |
||
| 667 | # Disk errors, top level |
||
| 668 | # |
||
| 669 | |||
| 670 | if($type eq "config"){
|
||
| 671 | print "multigraph libvirt_disk_errs\n"; |
||
| 672 | print "graph_title Disk errors per domain\n"; |
||
| 673 | print "graph_args --base 1000\n"; |
||
| 674 | print "graph_category Virtualization\n"; |
||
| 675 | |||
| 676 | for my $vm (sort keys %hash) {
|
||
| 677 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 678 | my $devices=0; |
||
| 679 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 680 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 681 | $devices++; |
||
| 682 | } |
||
| 683 | } |
||
| 684 | if($devices > 0){
|
||
| 685 | print $hash{$vm}{'label'} . "_errs.label " . $hash{$vm}{'name'} . "\n";
|
||
| 686 | print $hash{$vm}{'label'} . "_errs.type COUNTER\n";
|
||
| 687 | print $hash{$vm}{'label'} . "_errs.info The number of errors by " . $hash{$vm}{'name'} . "\n";
|
||
| 688 | print $hash{$vm}{'label'} . "_errs.min 0\n";
|
||
| 689 | print $hash{$vm}{'label'} . "_errs.draw LINE2\n";
|
||
| 690 | } |
||
| 691 | } |
||
| 692 | } |
||
| 693 | print "\n"; |
||
| 694 | |||
| 695 | } elsif($type eq "fetch"){
|
||
| 696 | print "multigraph libvirt_disk_errs\n"; |
||
| 697 | for my $vm (sort keys %hash) {
|
||
| 698 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 699 | my $errs=0; |
||
| 700 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 701 | $errs+=$hash{$vm}{'devices'}{'block'}{$device}{'errs'};
|
||
| 702 | } |
||
| 703 | print $hash{$vm}{'label'} . "_errs.value " . $errs . "\n";
|
||
| 704 | } |
||
| 705 | } |
||
| 706 | print "\n"; |
||
| 707 | } |
||
| 708 | |||
| 709 | # |
||
| 710 | # Disk errors, second level |
||
| 711 | # |
||
| 712 | |||
| 713 | for my $vm (sort keys %hash) {
|
||
| 714 | my $devices=0; |
||
| 715 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 716 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 717 | $devices++; |
||
| 718 | } |
||
| 719 | } |
||
| 720 | if($devices > 0){
|
||
| 721 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 722 | if($type eq "config"){
|
||
| 723 | print "multigraph libvirt_disk_errs." . $hash{$vm}{'label'} . "\n";
|
||
| 724 | print "graph_title Disk errors for " . $hash{$vm}{'name'} . "\n";
|
||
| 725 | print "graph_args --base 1000\n"; |
||
| 726 | print "graph_category Virtualization\n"; |
||
| 727 | |||
| 728 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 729 | |||
| 730 | print $device . "_errs.label " . $device . "\n"; |
||
| 731 | print $device . "_errs.type COUNTER\n"; |
||
| 732 | print $device . "_errs.info The number of errors by " . $hash{$vm}{'name'} . " on defice " . $device . "\n";
|
||
| 733 | print $device . "_errs.min 0\n"; |
||
| 734 | print $device . "_errs.draw LINE2\n"; |
||
| 735 | } |
||
| 736 | print "\n"; |
||
| 737 | |||
| 738 | } elsif($type eq "fetch"){
|
||
| 739 | print "multigraph libvirt_disk_errs." . $hash{$vm}{'label'} . "\n";
|
||
| 740 | if(defined($hash{$vm}{'devices'}{'block'})){
|
||
| 741 | for my $device (keys %{$hash{$vm}{'devices'}{'block'}}){
|
||
| 742 | print $device . "_errs.value " . $hash{$vm}{'devices'}{'block'}{$device}{'errs'} . "\n";
|
||
| 743 | } |
||
| 744 | } |
||
| 745 | print "\n"; |
||
| 746 | } |
||
| 747 | } |
||
| 748 | } |
||
| 749 | } |
||
| 750 | } |
||
| 751 | |||
| 752 | # |
||
| 753 | # Network used |
||
| 754 | # |
||
| 755 | |||
| 756 | if($show{'network_traffic'} == 1){
|
||
| 757 | |||
| 758 | # |
||
| 759 | # Network used, top level |
||
| 760 | # |
||
| 761 | |||
| 762 | if($type eq "config"){
|
||
| 763 | print "multigraph libvirt_network\n"; |
||
| 764 | print "graph_title Network traffic per domain in bytes\n"; |
||
| 765 | print "graph_args --base 1000\n"; |
||
| 766 | print "graph_vlabel Bytes in (-) / out (+) per \${graph_period}\n";
|
||
| 767 | print "graph_category Virtualization\n"; |
||
| 768 | #print "graph_width 550\n"; |
||
| 769 | |||
| 770 | for my $vm (sort keys %hash) {
|
||
| 771 | if(defined($hash{$vm}{'devices'}{'network'})){
|
||
| 772 | |||
| 773 | print $hash{$vm}{'label'} . "_rx_bytes.label " . $hash{$vm}{'name'} . "_rx\n";
|
||
| 774 | print $hash{$vm}{'label'} . "_rx_bytes.type DERIVE\n";
|
||
| 775 | print $hash{$vm}{'label'} . "_rx_bytes.info The number of bytes read by " . $hash{$vm}{'name'} . " in total.\n";
|
||
| 776 | print $hash{$vm}{'label'} . "_rx_bytes.min 0\n";
|
||
| 777 | print $hash{$vm}{'label'} . "_rx_bytes.draw LINE2\n";
|
||
| 778 | print $hash{$vm}{'label'} . "_rx_bytes.graph no\n";
|
||
| 779 | #print $hash{$vm}{'label'} . "_rx_bytes.cdef " . $hash{$vm}{'label'} . "_rx_bytes,8,*\n";
|
||
| 780 | |||
| 781 | print $hash{$vm}{'label'} . "_tx_bytes.label " . $hash{$vm}{'name'} . "\n";
|
||
| 782 | print $hash{$vm}{'label'} . "_tx_bytes.type DERIVE\n";
|
||
| 783 | print $hash{$vm}{'label'} . "_tx_bytes.info The number of bytes written by " . $hash{$vm}{'name'} . " in total.\n";
|
||
| 784 | print $hash{$vm}{'label'} . "_tx_bytes.min 0\n";
|
||
| 785 | print $hash{$vm}{'label'} . "_tx_bytes.draw LINE2\n";
|
||
| 786 | print $hash{$vm}{'label'} . "_tx_bytes.negative " . $hash{$vm}{'label'} . "_rx_bytes\n";
|
||
| 787 | #print $hash{$vm}{'label'} . "_tx_bytes.cdef " . $hash{$vm}{'label'} . "_tx_bytes,8,*\n";
|
||
| 788 | } |
||
| 789 | } |
||
| 790 | print "\n"; |
||
| 791 | |||
| 792 | } elsif($type eq "fetch"){
|
||
| 793 | print "multigraph libvirt_network\n"; |
||
| 794 | for my $vm (sort keys %hash) {
|
||
| 795 | if(defined($hash{$vm}{'devices'}{'network'})){
|
||
| 796 | my $read=0; |
||
| 797 | my $write=0; |
||
| 798 | for my $vif (keys %{$hash{$vm}{'devices'}{'network'}}){
|
||
| 799 | $read+=$hash{$vm}{'devices'}{'network'}{$vif}{'rx_bytes'};
|
||
| 800 | $write+=$hash{$vm}{'devices'}{'network'}{$vif}{'tx_bytes'};
|
||
| 801 | } |
||
| 802 | print $hash{$vm}{'label'} . "_rx_bytes.value " . $read . "\n";
|
||
| 803 | print $hash{$vm}{'label'} . "_tx_bytes.value " . $write . "\n";
|
||
| 804 | } |
||
| 805 | } |
||
| 806 | print "\n"; |
||
| 807 | } |
||
| 808 | |||
| 809 | # |
||
| 810 | # Network used, second level |
||
| 811 | # |
||
| 812 | |||
| 813 | for my $vm (sort keys %hash) {
|
||
| 814 | if(defined($hash{$vm}{'devices'}{'network'})){
|
||
| 815 | if($type eq "config"){
|
||
| 816 | print "multigraph libvirt_network.bytes_" . $hash{$vm}{'label'} . "\n";
|
||
| 817 | print "graph_title Network traffic for " . $vm . "\n"; |
||
| 818 | print "graph_args --base 1000\n"; |
||
| 819 | print "graph_vlabel Bits in (-) / out (+) per \${graph_period}\n";
|
||
| 820 | print "graph_category Virtualization\n"; |
||
| 821 | #print "graph_width 550\n"; |
||
| 822 | |||
| 823 | for my $vif (keys %{$hash{$vm}{'devices'}{'network'}}){
|
||
| 824 | my $vif_id=$hash{$vm}{'devices'}{'network'}{$vif}{'vif_id'};
|
||
| 825 | |||
| 826 | print "rx_bytes_" . $vif_id . ".label " . $vif . "_rx\n"; |
||
| 827 | print "rx_bytes_" . $vif_id . ".type DERIVE\n"; |
||
| 828 | print "rx_bytes_" . $vif_id . ".info The number of bytes read by " . $hash{$vm}{'name'} . "\n";
|
||
| 829 | print "rx_bytes_" . $vif_id . ".min 0\n"; |
||
| 830 | print "rx_bytes_" . $vif_id . ".graph no\n"; |
||
| 831 | print "rx_bytes_" . $vif_id . ".cdef rx_bytes_" . $vif_id . ",8,*\n"; |
||
| 832 | |||
| 833 | print "tx_bytes_" . $vif_id . ".label " . $vif . "\n"; |
||
| 834 | print "tx_bytes_" . $vif_id . ".type DERIVE\n"; |
||
| 835 | print "tx_bytes_" . $vif_id . ".info The number of bits written by " . $hash{$vm}{'name'} . "\n";
|
||
| 836 | print "tx_bytes_" . $vif_id . ".min 0\n"; |
||
| 837 | print "tx_bytes_" . $vif_id . ".draw LINE2\n"; |
||
| 838 | print "tx_bytes_" . $vif_id . ".negative rx_bytes_" . $vif_id . "\n"; |
||
| 839 | print "tx_bytes_" . $vif_id . ".cdef tx_bytes_" . $vif_id . ",8,*\n"; |
||
| 840 | } |
||
| 841 | print "\n"; |
||
| 842 | |||
| 843 | } elsif($type eq "fetch"){
|
||
| 844 | print "multigraph libvirt_network.bytes_" . $hash{$vm}{'label'} . "\n";
|
||
| 845 | for my $vif (keys %{$hash{$vm}{'devices'}{'network'}}){
|
||
| 846 | my $vif_id=$hash{$vm}{'devices'}{'network'}{$vif}{'vif_id'};
|
||
| 847 | print "rx_bytes_" . $vif_id . ".value " . $hash{$vm}{'devices'}{'network'}{$vif}{'rx_bytes'} . "\n";
|
||
| 848 | print "tx_bytes_" . $vif_id . ".value " . $hash{$vm}{'devices'}{'network'}{$vif}{'tx_bytes'} . "\n";
|
||
| 849 | } |
||
| 850 | print "\n"; |
||
| 851 | } |
||
| 852 | } |
||
| 853 | } |
||
| 854 | } |
||
| 855 | |||
| 856 | # |
||
| 857 | # Network drops and errors |
||
| 858 | # |
||
| 859 | # rx_drop -> Total packets drop at reception |
||
| 860 | # tx_drop -> Total packets dropped at transmission. |
||
| 861 | |||
| 862 | if($show{'network_drops'} == 1){
|
||
| 863 | |||
| 864 | # |
||
| 865 | # Network drops, top level |
||
| 866 | # |
||
| 867 | |||
| 868 | if($type eq "config"){
|
||
| 869 | print "multigraph libvirt_network_drop\n"; |
||
| 870 | print "graph_title Network packets dropped per domain\n"; |
||
| 871 | print "graph_args --base 1000\n"; |
||
| 872 | print "graph_vlabel Count in (-) / out (+) per \${graph_period}\n";
|
||
| 873 | print "graph_category Virtualization\n"; |
||
| 874 | #print "graph_width 550\n"; |
||
| 875 | |||
| 876 | for my $vm (sort keys %hash) {
|
||
| 877 | if(defined($hash{$vm}{'devices'}{'network'})){
|
||
| 878 | |||
| 879 | print $hash{$vm}{'label'} . "_rx_drop.label " . $hash{$vm}{'name'} . "_rx\n";
|
||
| 880 | print $hash{$vm}{'label'} . "_rx_drop.type DERIVE\n";
|
||
| 881 | print $hash{$vm}{'label'} . "_rx_drop.info The number of packets dropped at reception by " . $hash{$vm}{'name'} . "\n";
|
||
| 882 | print $hash{$vm}{'label'} . "_rx_drop.min 0\n";
|
||
| 883 | print $hash{$vm}{'label'} . "_rx_drop.draw LINE2\n";
|
||
| 884 | print $hash{$vm}{'label'} . "_rx_drop.graph no\n";
|
||
| 885 | |||
| 886 | print $hash{$vm}{'label'} . "_tx_drop.label " . $hash{$vm}{'name'} . "\n";
|
||
| 887 | print $hash{$vm}{'label'} . "_tx_drop.type DERIVE\n";
|
||
| 888 | print $hash{$vm}{'label'} . "_tx_drop.info The number of packets dropped at transmission by " . $hash{$vm}{'name'} . "\n";
|
||
| 889 | print $hash{$vm}{'label'} . "_tx_drop.min 0\n";
|
||
| 890 | print $hash{$vm}{'label'} . "_tx_drop.draw LINE2\n";
|
||
| 891 | print $hash{$vm}{'label'} . "_tx_drop.negative " . $hash{$vm}{'label'} . "_rx_drop\n";
|
||
| 892 | } |
||
| 893 | } |
||
| 894 | print "\n"; |
||
| 895 | |||
| 896 | } elsif($type eq "fetch"){
|
||
| 897 | print "multigraph libvirt_network_drop\n"; |
||
| 898 | for my $vm (sort keys %hash) {
|
||
| 899 | if(defined($hash{$vm}{'devices'}{'network'})){
|
||
| 900 | my $rx_drop=0; |
||
| 901 | my $tx_drop=0; |
||
| 902 | for my $vif (keys %{$hash{$vm}{'devices'}{'network'}}){
|
||
| 903 | $rx_drop+=$hash{$vm}{'devices'}{'network'}{$vif}{'rx_drop'};
|
||
| 904 | $tx_drop+=$hash{$vm}{'devices'}{'network'}{$vif}{'tx_drop'};
|
||
| 905 | } |
||
| 906 | |||
| 907 | print $hash{$vm}{'label'} . "_rx_drop.value " . $rx_drop . "\n";
|
||
| 908 | print $hash{$vm}{'label'} . "_tx_drop.value " . $tx_drop . "\n";
|
||
| 909 | |||
| 910 | } |
||
| 911 | } |
||
| 912 | print "\n"; |
||
| 913 | } |
||
| 914 | |||
| 915 | # |
||
| 916 | # Network drops, second level |
||
| 917 | # |
||
| 918 | |||
| 919 | for my $vm (sort keys %hash) {
|
||
| 920 | if(defined($hash{$vm}{'devices'}{'network'})){
|
||
| 921 | if($type eq "config"){
|
||
| 922 | print "multigraph libvirt_network_drop." . $hash{$vm}{'label'} . "\n";
|
||
| 923 | print "graph_title Network packeds dropped by " . $vm . "\n"; |
||
| 924 | print "graph_args --base 1000\n"; |
||
| 925 | print "graph_vlabel Count in (-) / out (+) per \${graph_period}\n";
|
||
| 926 | print "graph_category Virtualization\n"; |
||
| 927 | #print "graph_width 550\n"; |
||
| 928 | |||
| 929 | for my $vif (keys %{$hash{$vm}{'devices'}{'network'}}){
|
||
| 930 | my $vif_id=$hash{$vm}{'devices'}{'network'}{$vif}{'vif_id'};
|
||
| 931 | |||
| 932 | print "rx_drop_" . $vif_id . ".label " . $vif . "_rx\n"; |
||
| 933 | print "rx_drop_" . $vif_id . ".type DERIVE\n"; |
||
| 934 | print "rx_drop_" . $vif_id . ".info The number of packets dropped by " . $hash{$vm}{'name'} . ", nic " . $vif_id . "\n";
|
||
| 935 | print "rx_drop_" . $vif_id . ".min 0\n"; |
||
| 936 | print "rx_drop_" . $vif_id . ".graph no\n"; |
||
| 937 | |||
| 938 | print "tx_drop_" . $vif_id . ".label " . $vif . "\n"; |
||
| 939 | print "tx_drop_" . $vif_id . ".type DERIVE\n"; |
||
| 940 | print "tx_drop_" . $vif_id . ".info The number of packets dropped by " . $hash{$vm}{'name'} . ", nic " . $vif_id . "\n";
|
||
| 941 | print "tx_drop_" . $vif_id . ".min 0\n"; |
||
| 942 | print "tx_drop_" . $vif_id . ".draw LINE2\n"; |
||
| 943 | print "tx_drop_" . $vif_id . ".negative rx_drop_" . $vif_id . "\n"; |
||
| 944 | } |
||
| 945 | print "\n"; |
||
| 946 | |||
| 947 | } elsif($type eq "fetch"){
|
||
| 948 | print "multigraph libvirt_network_drop." . $hash{$vm}{'label'} . "\n";
|
||
| 949 | for my $vif (keys %{$hash{$vm}{'devices'}{'network'}}){
|
||
| 950 | my $vif_id=$hash{$vm}{'devices'}{'network'}{$vif}{'vif_id'};
|
||
| 951 | print "rx_drop_" . $vif_id . ".value " . $hash{$vm}{'devices'}{'network'}{$vif}{'rx_drop'} . "\n";
|
||
| 952 | print "tx_drop_" . $vif_id . ".value " . $hash{$vm}{'devices'}{'network'}{$vif}{'tx_drop'} . "\n";
|
||
| 953 | } |
||
| 954 | print "\n"; |
||
| 955 | } |
||
| 956 | } |
||
| 957 | } |
||
| 958 | } |
||
| 959 | |||
| 960 | # |
||
| 961 | # CPU used |
||
| 962 | # |
||
| 963 | |||
| 964 | if($show{'cpu_used'} == 1){
|
||
| 965 | |||
| 966 | # |
||
| 967 | # CPU used, top level |
||
| 968 | # |
||
| 969 | |||
| 970 | if($type eq "config"){
|
||
| 971 | print "multigraph libvirt_cpu\n"; |
||
| 972 | print "graph_title Cpu time used per domain in percent\n"; |
||
| 973 | print "graph_args --base 1000 -r --lower-limit 0 --upper-limit 100\n"; |
||
| 974 | print "graph_category Virtualization\n"; |
||
| 975 | #print "graph_width 550\n"; |
||
| 976 | |||
| 977 | my $draw="AREA"; |
||
| 978 | for my $vm (sort keys %hash) {
|
||
| 979 | print $hash{$vm}{'label'} . "_time.label " . $hash{$vm}{'name'} . "\n";
|
||
| 980 | print $hash{$vm}{'label'} . "_time.type DERIVE\n";
|
||
| 981 | print $hash{$vm}{'label'} . "_time.info The cpu time used by " . $hash{$vm}{'name'} . " in percent of the total available cpu time on the physical node.\n";
|
||
| 982 | print $hash{$vm}{'label'} . "_time.min 0\n";
|
||
| 983 | print $hash{$vm}{'label'} . "_time.draw $draw\n";
|
||
| 984 | $draw="STACK" if $draw eq "AREA"; |
||
| 985 | } |
||
| 986 | print "\n"; |
||
| 987 | |||
| 988 | } elsif($type eq "fetch"){
|
||
| 989 | print "multigraph libvirt_cpu\n"; |
||
| 990 | for my $vm (sort keys %hash) {
|
||
| 991 | print $hash{$vm}{'label'} . "_time.value " . $hash{$vm}{'info'}{'cpuPercentage'} . "\n";
|
||
| 992 | } |
||
| 993 | print "\n"; |
||
| 994 | } |
||
| 995 | |||
| 996 | # |
||
| 997 | # CPU used, second level (pr virtual machine) |
||
| 998 | # |
||
| 999 | |||
| 1000 | if($type eq "config"){
|
||
| 1001 | for my $vm (sort keys %hash) {
|
||
| 1002 | print "multigraph libvirt_cpu.vm_" . $hash{$vm}{'label'} . "\n";
|
||
| 1003 | print "graph_title Cpu time used by " . $hash{$vm}{'name'} . " in percent\n";
|
||
| 1004 | print "graph_args --base 1000\n"; |
||
| 1005 | print "graph_category Virtualization\n"; |
||
| 1006 | #print "graph_width 550\n"; |
||
| 1007 | |||
| 1008 | print "time.label " . $hash{$vm}{'name'} . " (" . $hash{$vm}{'type'} . ")\n";
|
||
| 1009 | print "time.type DERIVE\n"; |
||
| 1010 | print "time.info The cpu time used by " . $hash{$vm}{'name'} . " in percent of the total available cpu time on the physical node. This domain has access to " . $hash{$vm}{'info'}{'nrVirtCpu'} . " VCPU(s) now, and $hash{$vm}{'maxvcpus'} at maximum. The scheduler for this domain is " . $hash{$vm}{'scheduler'} . ".\n";
|
||
| 1011 | print "time.min 0\n"; |
||
| 1012 | print "time.draw AREA\n"; |
||
| 1013 | print "\n"; |
||
| 1014 | } |
||
| 1015 | |||
| 1016 | } elsif($type eq "fetch"){
|
||
| 1017 | for my $vm (sort keys %hash) {
|
||
| 1018 | print "multigraph libvirt_cpu.vm_" . $hash{$vm}{'label'} . "\n";
|
||
| 1019 | print "time.value " . $hash{$vm}{'info'}{'cpuPercentage'} . "\n";
|
||
| 1020 | print "\n"; |
||
| 1021 | } |
||
| 1022 | } |
||
| 1023 | } |
||
| 1024 | |||
| 1025 | # |
||
| 1026 | # Memory allocation |
||
| 1027 | # |
||
| 1028 | |||
| 1029 | if($show{'memory_allocated'} == 1){
|
||
| 1030 | |||
| 1031 | # |
||
| 1032 | # Memory allocation, top level |
||
| 1033 | # |
||
| 1034 | |||
| 1035 | if($type eq "config"){
|
||
| 1036 | print "multigraph libvirt_mem\n"; |
||
| 1037 | print "graph_title Memory allocated per domain\n"; |
||
| 1038 | print "graph_args --base 1000\n"; |
||
| 1039 | print "graph_category Virtualization\n"; |
||
| 1040 | #print "graph_width 550\n"; |
||
| 1041 | |||
| 1042 | my $draw="AREA"; |
||
| 1043 | for my $vm (sort keys %hash) {
|
||
| 1044 | print $hash{$vm}{'label'} . "_alloc.label " . $hash{$vm}{'name'} . "\n";
|
||
| 1045 | print $hash{$vm}{'label'} . "_alloc.type GAUGE\n";
|
||
| 1046 | print $hash{$vm}{'label'} . "_alloc.info Memory allocation per domain.\n";
|
||
| 1047 | print $hash{$vm}{'label'} . "_alloc.min 0\n";
|
||
| 1048 | print $hash{$vm}{'label'} . "_alloc.draw $draw\n";
|
||
| 1049 | $draw="STACK" if $draw eq "AREA"; |
||
| 1050 | } |
||
| 1051 | print "\n"; |
||
| 1052 | |||
| 1053 | } elsif($type eq "fetch"){
|
||
| 1054 | print "multigraph libvirt_mem\n"; |
||
| 1055 | for my $vm (sort keys %hash) {
|
||
| 1056 | print $hash{$vm}{'label'} . "_alloc.value " . $hash{$vm}{'info'}{'memory_bytes'} . "\n";
|
||
| 1057 | } |
||
| 1058 | print "\n"; |
||
| 1059 | } |
||
| 1060 | |||
| 1061 | # |
||
| 1062 | # Memory allocated, second level (pr virtual machine) |
||
| 1063 | # |
||
| 1064 | |||
| 1065 | if($type eq "config"){
|
||
| 1066 | for my $vm (sort keys %hash) {
|
||
| 1067 | print "multigraph libvirt_mem.vm_" . $hash{$vm}{'label'} . "\n";
|
||
| 1068 | print "graph_title Memory allocated to " . $hash{$vm}{'name'} . "\n";
|
||
| 1069 | print "graph_args --base 1000\n"; |
||
| 1070 | print "graph_category Virtualization\n"; |
||
| 1071 | #print "graph_width 550\n"; |
||
| 1072 | |||
| 1073 | print "mem.label " . $hash{$vm}{'name'} . " (" . $hash{$vm}{'type'} . ")\n";
|
||
| 1074 | print "mem.type GAUGE\n"; |
||
| 1075 | print "mem.info Amount of memory allocated to " . $hash{$vm}{'name'} . ". The maximum amount of memory for this domain is " . $hash{$vm}{'maxmem'}/1024 . " MB.\n";
|
||
| 1076 | print "mem.min 0\n"; |
||
| 1077 | print "mem.draw AREA\n"; |
||
| 1078 | print "\n"; |
||
| 1079 | } |
||
| 1080 | |||
| 1081 | } elsif($type eq "fetch"){
|
||
| 1082 | for my $vm (sort keys %hash) {
|
||
| 1083 | print "multigraph libvirt_mem.vm_" . $hash{$vm}{'label'} . "\n";
|
||
| 1084 | print "mem.value " . $hash{$vm}{'info'}{'memory_bytes'} . "\n";
|
||
| 1085 | print "\n"; |
||
| 1086 | } |
||
| 1087 | } |
||
| 1088 | } |
||
| 1089 | } |
||
| 1090 | |||
| 1091 | sub clean_label() {
|
||
| 1092 | my $label=shift; |
||
| 1093 | $label =~ s/^[^A-Za-z_]/_/; |
||
| 1094 | $label =~ s/[^A-Za-z0-9_]/_/g; |
||
| 1095 | return $label; |
||
| 1096 | } |
||
| 1097 | |||
| 1098 | sub connect {
|
||
| 1099 | my $vmm = Sys::Virt->new(address => $address, |
||
| 1100 | auth => 1, |
||
| 1101 | credlist => [ |
||
| 1102 | Sys::Virt::CRED_AUTHNAME, |
||
| 1103 | Sys::Virt::CRED_PASSPHRASE, |
||
| 1104 | ], |
||
| 1105 | callback => |
||
| 1106 | sub {
|
||
| 1107 | my $creds = shift; |
||
| 1108 | |||
| 1109 | foreach my $cred (@{$creds}) {
|
||
| 1110 | if ($cred->{type} == Sys::Virt::CRED_AUTHNAME) {
|
||
| 1111 | $cred->{result} = $username;
|
||
| 1112 | } |
||
| 1113 | if ($cred->{type} == Sys::Virt::CRED_PASSPHRASE) {
|
||
| 1114 | $cred->{result} = $password;
|
||
| 1115 | } |
||
| 1116 | } |
||
| 1117 | return 0; |
||
| 1118 | }); |
||
| 1119 | return $vmm; |
||
| 1120 | } |
||
| 1121 | |||
| 1122 | sub autoconf {
|
||
| 1123 | my $vmm=&connect(); |
||
| 1124 | if($vmm){
|
||
| 1125 | my $node = $vmm->get_node_info(); |
||
| 1126 | if($node){
|
||
| 1127 | print "yes\n"; |
||
| 1128 | exit(0); |
||
| 1129 | } else {
|
||
| 1130 | print "no (Unable to fetch node info)\n"; |
||
| 1131 | exit(1); |
||
| 1132 | } |
||
| 1133 | } else {
|
||
| 1134 | print "no (Unable to connect to libvirt)\n"; |
||
| 1135 | exit(1); |
||
| 1136 | } |
||
| 1137 | |||
| 1138 | } |
||
| 1139 | |||
| 1140 | # |
||
| 1141 | # Function to extract information from xml and return a hash with the necessary information. |
||
| 1142 | # The logic is really ugly and should be improved. |
||
| 1143 | # |
||
| 1144 | sub parse_xml {
|
||
| 1145 | my $raw_xml=shift; |
||
| 1146 | my %res=(); |
||
| 1147 | |||
| 1148 | use XML::Simple qw(:strict); |
||
| 1149 | my $xs=XML::Simple->new; |
||
| 1150 | my @a=$xs->XMLin($raw_xml,ForceArray => 1, KeyAttr => 'target'); |
||
| 1151 | |||
| 1152 | for (my $i=0 ; $i < scalar(@a) ; $i++){
|
||
| 1153 | # Hack to extract disk information and put it into the hash |
||
| 1154 | # TODO: Improve |
||
| 1155 | if(defined($a[$i]{'devices'}[0]{'disk'})){
|
||
| 1156 | |||
| 1157 | my $teller = 0; |
||
| 1158 | my $fortsette = 1; |
||
| 1159 | |||
| 1160 | while($fortsette){
|
||
| 1161 | if( $a[$i]{'devices'}[0]{'disk'}[$teller] ){
|
||
| 1162 | my $type=$a[$i]{'devices'}[0]{'disk'}[$teller]{'type'};
|
||
| 1163 | my $source_dev=$a[$i]{'devices'}[0]{'disk'}[$teller]{'source'}[0]{'dev'};
|
||
| 1164 | my $target_bus=$a[$i]{'devices'}[0]{'disk'}[$teller]{'target'}[0]{'bus'};
|
||
| 1165 | my $target_dev=$a[$i]{'devices'}[0]{'disk'}[$teller]{'target'}[0]{'dev'};
|
||
| 1166 | |||
| 1167 | $res{'devices'}{'disk'}{$type}{$target_dev}{'source'}=$source_dev;
|
||
| 1168 | $res{'devices'}{'disk'}{$type}{$target_dev}{'bus'}=$target_bus;
|
||
| 1169 | $res{'devices'}{'disk'}{$type}{$target_dev}{'type'}=$type;
|
||
| 1170 | |||
| 1171 | $teller++; |
||
| 1172 | } |
||
| 1173 | else{
|
||
| 1174 | $fortsette = 0; |
||
| 1175 | } |
||
| 1176 | } |
||
| 1177 | } |
||
| 1178 | |||
| 1179 | # Hack to extract network information and put it into the hash |
||
| 1180 | # TODO: Improve |
||
| 1181 | if(defined($a[$i]{'devices'}[0]{'interface'})){
|
||
| 1182 | |||
| 1183 | my $teller = 0; |
||
| 1184 | my $fortsette = 1; |
||
| 1185 | |||
| 1186 | while($fortsette){
|
||
| 1187 | if( $a[$i]{'devices'}[0]{'interface'}[$teller] ){
|
||
| 1188 | my $type=$a[$i]{'devices'}[0]{'interface'}[$teller]{'type'};
|
||
| 1189 | my $target=$a[$i]{'devices'}[0]{'interface'}[$teller]{'target'}[0]{'dev'};
|
||
| 1190 | my $bridge=$a[$i]{'devices'}[0]{'interface'}[$teller]{'source'}[0]{'bridge'};;
|
||
| 1191 | my $mac=$a[$i]{'devices'}[0]{'interface'}[$teller]{'mac'}[0]{'address'};;
|
||
| 1192 | |||
| 1193 | $res{'devices'}{'interface'}{$type}{$target}{'target'}=$target;
|
||
| 1194 | $res{'devices'}{'interface'}{$type}{$target}{'mac'}=$mac;
|
||
| 1195 | $res{'devices'}{'interface'}{$type}{$target}{'bridge'}=$bridge;
|
||
| 1196 | $teller++; |
||
| 1197 | } |
||
| 1198 | else{
|
||
| 1199 | $fortsette = 0; |
||
| 1200 | } |
||
| 1201 | } |
||
| 1202 | } |
||
| 1203 | } |
||
| 1204 | |||
| 1205 | return \%res; |
||
| 1206 | } |
||
| 1207 | |||
| 1208 | sub read_diskstats{
|
||
| 1209 | my $dev=shift; |
||
| 1210 | |||
| 1211 | my %res=(); |
||
| 1212 | |||
| 1213 | # Verify that $dev is a block device. |
||
| 1214 | if(-b $dev){
|
||
| 1215 | # Read minor and major number |
||
| 1216 | my $rdev = stat($dev)->rdev; |
||
| 1217 | $res{'major'} = $rdev >> 8;
|
||
| 1218 | $res{'minor'} = $rdev & 0xff;
|
||
| 1219 | |||
| 1220 | # If major numer is 253, then proceed as dm-device |
||
| 1221 | if($res{'major'} == 253){
|
||
| 1222 | |||
| 1223 | # check that the directory /sys/block/dm-$minor/ exists with a /slaves/ sub directory |
||
| 1224 | if(-d "/sys/block/dm-" . $res{'minor'} . "/"){
|
||
| 1225 | if(-d "/sys/block/dm-" . $res{'minor'} . "/slaves/"){
|
||
| 1226 | |||
| 1227 | # see if /sys/block/dm-$minor/slaves/ has any slaves |
||
| 1228 | opendir(DIR, "/sys/block/dm-" . $res{'minor'} . "/slaves/");
|
||
| 1229 | while(my $slave = readdir(DIR)){
|
||
| 1230 | |||
| 1231 | # Exclude directories (. and ..) |
||
| 1232 | if($slave !~ m/^\.+$/){
|
||
| 1233 | |||
| 1234 | # Check if we have /sys/block/dm-$minor/slaves/$slave/stat |
||
| 1235 | if(-f "/sys/block/dm-" . $res{'minor'} . "/slaves/" . $slave . "/stat"){
|
||
| 1236 | # Read the stat-file |
||
| 1237 | open(FILE, "</sys/block/dm-" . $res{'minor'} . "/slaves/" . $slave . "/stat");
|
||
| 1238 | while (my $line = <FILE>) {
|
||
| 1239 | # 1 2 3 4 5 6 7 8 9 10 11 |
||
| 1240 | if($line =~ m/(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/){
|
||
| 1241 | |||
| 1242 | # Name units description |
||
| 1243 | # ---- ----- ----------- |
||
| 1244 | # read I/Os requests number of read I/Os processed |
||
| 1245 | # read merges requests number of read I/Os merged with in-queue I/O |
||
| 1246 | # read sectors sectors number of sectors read |
||
| 1247 | # read ticks milliseconds total wait time for read requests |
||
| 1248 | # write I/Os requests number of write I/Os processed |
||
| 1249 | # write merges requests number of write I/Os merged with in-queue I/O |
||
| 1250 | # write sectors sectors number of sectors written |
||
| 1251 | # write ticks milliseconds total wait time for write requests |
||
| 1252 | # in_flight requests number of I/Os currently in flight |
||
| 1253 | # io_ticks milliseconds total time this block device has been active |
||
| 1254 | # time_in_queue milliseconds total wait time for all requests |
||
| 1255 | # |
||
| 1256 | # Documentation fetched from http://www.mjmwired.net/kernel/Documentation/block/stat.txt |
||
| 1257 | |||
| 1258 | # store the output in the hash |
||
| 1259 | $res{'slaves'}{$slave}{'read_ios'}=$1;
|
||
| 1260 | $res{'slaves'}{$slave}{'read_merges'}=$2;
|
||
| 1261 | $res{'slaves'}{$slave}{'read_sectors'}=$3;
|
||
| 1262 | $res{'slaves'}{$slave}{'read_ticks'}=$4;
|
||
| 1263 | $res{'slaves'}{$slave}{'write_ios'}=$5;
|
||
| 1264 | $res{'slaves'}{$slave}{'write_merges'}=$6;
|
||
| 1265 | $res{'slaves'}{$slave}{'write_sectors'}=$7;
|
||
| 1266 | $res{'slaves'}{$slave}{'write_ticks'}=$8;
|
||
| 1267 | $res{'slaves'}{$slave}{'in_flight'}=$9;
|
||
| 1268 | $res{'slaves'}{$slave}{'io_ticks'}=$10;
|
||
| 1269 | $res{'slaves'}{$slave}{'time_in_queue'}=$11;
|
||
| 1270 | } |
||
| 1271 | } |
||
| 1272 | close(FILE); |
||
| 1273 | } |
||
| 1274 | } |
||
| 1275 | } |
||
| 1276 | close(DIR); |
||
| 1277 | } |
||
| 1278 | } |
||
| 1279 | } |
||
| 1280 | } |
||
| 1281 | |||
| 1282 | return \%res; |
||
| 1283 | } |
||
| 1284 | |||
| 1285 | # Return the timestamp of a file |
||
| 1286 | sub get_prev_time(){
|
||
| 1287 | my $tmpfile=shift; |
||
| 1288 | |||
| 1289 | my $time=-1; |
||
| 1290 | |||
| 1291 | if(-r $tmpfile){
|
||
| 1292 | $time = stat($tmpfile)->mtime; |
||
| 1293 | } |
||
| 1294 | |||
| 1295 | return $time; |
||
| 1296 | } |
||
| 1297 | |||
| 1298 | init(); |
||
| 1299 | |||
| 1300 | # vim:syntax=perl |
