root / plugins / system / cpu @ f14628ad
Historique | Voir | Annoter | Télécharger (31,1 ko)
| 1 |
#!/usr/bin/perl -w |
|---|---|
| 2 |
# -*- perl -*- |
| 3 |
|
| 4 |
=head1 NAME |
| 5 |
|
| 6 |
cpu - Plugin to monitor CPU usage and frequencies. |
| 7 |
|
| 8 |
=head1 APPLICABLE SYSTEMS |
| 9 |
|
| 10 |
All Linux systems, but read below section |
| 11 |
|
| 12 |
=head1 CONFIGURATION |
| 13 |
|
| 14 |
The plugin automatically selects which graphics drawing. |
| 15 |
Charts related to the frequencies of processors depends on the settings of the kernel: |
| 16 |
Power management and ACPI options -> CPU Frequency scaling -> CPU frequency translation statistics -> Advanced statistics |
| 17 |
|
| 18 |
=head2 WARNING AND CRITICAL SETTINGS |
| 19 |
|
| 20 |
You can set warning and critical levels for each of the data |
| 21 |
series the plugin reports. The following environment variables are |
| 22 |
used as default for all fields: |
| 23 |
|
| 24 |
env.warning |
| 25 |
env.critical |
| 26 |
|
| 27 |
But each field (system user nice etc...) can be controlled separately: |
| 28 |
For example: |
| 29 |
|
| 30 |
env.system_warning 70 |
| 31 |
env.user_warning 70 |
| 32 |
env.idle_critical 1 |
| 33 |
|
| 34 |
Also each field of each cpu can be controlled separately |
| 35 |
For example: |
| 36 |
|
| 37 |
env.cpu1_system_warning 70 |
| 38 |
env.cpu0_user_warning 70 |
| 39 |
env.cpu0_idle_critical 1 |
| 40 |
|
| 41 |
Algoritm is easy: for example current graph limit is env.cpu0_idle_critical if defined env.cpu0_idle_critical or env.idle_critical if defined env.idle_critical |
| 42 |
or env.critical if defined env.critical. Or no limit |
| 43 |
|
| 44 |
=head1 INTERPRETATION |
| 45 |
|
| 46 |
The plugin shows each cpu usage in percent, shows the CPU frequency, |
| 47 |
frequency shift frequencies, the percentage of use of frequencies |
| 48 |
|
| 49 |
=head1 MAGIC MARKERS |
| 50 |
|
| 51 |
#%# family=auto |
| 52 |
#%# capabilities=autoconf |
| 53 |
|
| 54 |
|
| 55 |
=head1 VERSION |
| 56 |
|
| 57 |
2.0 |
| 58 |
|
| 59 |
=head1 BUGS |
| 60 |
|
| 61 |
none known |
| 62 |
|
| 63 |
=head1 AUTHOR |
| 64 |
|
| 65 |
Gorlow Maxim aka Sheridan <sheridan@sheridan-home.ru> (email and jabber) |
| 66 |
|
| 67 |
=head1 LICENSE |
| 68 |
|
| 69 |
GPLv2 |
| 70 |
|
| 71 |
=cut |
| 72 |
|
| 73 |
use strict; |
| 74 |
use warnings; |
| 75 |
use Munin::Plugin; |
| 76 |
use Data::Dumper; |
| 77 |
my @cnames = qw(user nice system idle iowait irq softirq steal guest); |
| 78 |
my $stat_file = "/proc/stat"; |
| 79 |
my $freq_path = "/sys/devices/system/cpu"; |
| 80 |
my $limits = {};
|
| 81 |
my $cpuinfo = {}; $cpuinfo->{'cpu_count'} = 0;
|
| 82 |
my @stat_file_content = (); |
| 83 |
my $freq_mul = 1000; # CPU frequency multiplier from kHz to Hz |
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
my $graphs = |
| 88 |
{
|
| 89 |
'cpu_utilisation' => # multigraph |
| 90 |
{
|
| 91 |
'title' => 'CPU:t: utilisation', |
| 92 |
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100', |
| 93 |
'vlabel' => '%', |
| 94 |
'scale' => 'no', |
| 95 |
'info' => 'This graph shows how CPU:t: time is spent :i:' |
| 96 |
}, |
| 97 |
'cpu_all' => # single |
| 98 |
{
|
| 99 |
'title' => 'All CPU utilisation', |
| 100 |
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100', |
| 101 |
'vlabel' => '%', |
| 102 |
'scale' => 'no', |
| 103 |
'info' => 'This graph shows how CPU time is spent on each processor', |
| 104 |
'category' => 'cpu' |
| 105 |
}, |
| 106 |
'cpu_freq_trans' => # multi |
| 107 |
{
|
| 108 |
'title' => 'CPU frequency transitions', |
| 109 |
'args' => '--base 1000', |
| 110 |
'vlabel' => 'count', |
| 111 |
'scale' => 'no', |
| 112 |
'info' => 'This graph shows CPU transitions of each processor', |
| 113 |
}, |
| 114 |
'cpu_freq' => # child of cpu_freq_trans |
| 115 |
{
|
| 116 |
'title' => 'CPU:t: frequency (total)', |
| 117 |
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100', |
| 118 |
'vlabel' => '% of total', |
| 119 |
'info' => 'This graph shows CPU:t: frequency :i:', |
| 120 |
'category' => 'cpu' |
| 121 |
}, |
| 122 |
'cpu_freq_ps' => # child of cpu_freq_trans |
| 123 |
{
|
| 124 |
'title' => 'CPU:t: frequency (per secund)', |
| 125 |
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100', |
| 126 |
'vlabel' => '% per secund', |
| 127 |
'info' => 'This graph shows CPU:t: frequency per secund from last update :i:', |
| 128 |
'category' => 'cpu' |
| 129 |
}, |
| 130 |
'cpu_freq_trans_table' => # child of cpu_freq_trans |
| 131 |
{
|
| 132 |
'title' => 'CPU:t: frequency switches (total)', |
| 133 |
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100', |
| 134 |
'vlabel' => '% of total', |
| 135 |
'scale' => 'no', |
| 136 |
'info' => 'This graph shows CPU:t: frequency switches :i:', |
| 137 |
}, |
| 138 |
'cpu_freq_trans_table_ps' => # child of cpu_freq_trans |
| 139 |
{
|
| 140 |
'title' => 'CPU:t: frequency switches (per secund)', |
| 141 |
'args' => '--base 1000 -r --lower-limit 0 --upper-limit 100', |
| 142 |
'vlabel' => '% per secund', |
| 143 |
'scale' => 'no', |
| 144 |
'info' => 'This graph shows CPU:t: frequency switches per secund from last update :i:', |
| 145 |
} |
| 146 |
}; |
| 147 |
|
| 148 |
my $transparent = 'CC'; |
| 149 |
my $fields = |
| 150 |
{
|
| 151 |
'user' => |
| 152 |
{
|
| 153 |
'label' => 'User', |
| 154 |
'info' => 'Normal processes executing in user mode', |
| 155 |
'type' => 'GAUGE', |
| 156 |
'draw' => 'AREASTACK', |
| 157 |
'min' => 0, |
| 158 |
'max' => 100 |
| 159 |
}, |
| 160 |
'nice' => |
| 161 |
{
|
| 162 |
'label' => 'Nice', |
| 163 |
'info' => 'Niced processes executing in user mode', |
| 164 |
'type' => 'GAUGE', |
| 165 |
'draw' => 'AREASTACK', |
| 166 |
'min' => 0, |
| 167 |
'max' => 100 |
| 168 |
}, |
| 169 |
'system' => |
| 170 |
{
|
| 171 |
'label' => 'System', |
| 172 |
'info' => 'Processes executing in kernel mode', |
| 173 |
'type' => 'GAUGE', |
| 174 |
'draw' => 'AREASTACK', |
| 175 |
'min' => 0, |
| 176 |
'max' => 100 |
| 177 |
}, |
| 178 |
'idle' => |
| 179 |
{
|
| 180 |
'label' => 'Idle', |
| 181 |
'info' => 'Twiddling thumbs', |
| 182 |
'type' => 'GAUGE', |
| 183 |
'draw' => 'AREASTACK', |
| 184 |
'colour'=> 'FFFFDD'.$transparent, |
| 185 |
'min' => 0, |
| 186 |
'max' => 100 |
| 187 |
}, |
| 188 |
'iowait' => |
| 189 |
{
|
| 190 |
'label' => 'I/O wait', |
| 191 |
'info' => 'Waiting for I/O to complete', |
| 192 |
'type' => 'GAUGE', |
| 193 |
'draw' => 'AREASTACK', |
| 194 |
'min' => 0, |
| 195 |
'max' => 100 |
| 196 |
}, |
| 197 |
'irq' => |
| 198 |
{
|
| 199 |
'label' => 'IRQ', |
| 200 |
'info' => 'Servicing interrupts', |
| 201 |
'type' => 'GAUGE', |
| 202 |
'draw' => 'AREASTACK', |
| 203 |
'min' => 0, |
| 204 |
'max' => 100 |
| 205 |
}, |
| 206 |
'softirq' => |
| 207 |
{
|
| 208 |
'label' => 'Software IRQ', |
| 209 |
'info' => 'Servicing software interrupts', |
| 210 |
'type' => 'GAUGE', |
| 211 |
'draw' => 'AREASTACK', |
| 212 |
'min' => 0, |
| 213 |
'max' => 100 |
| 214 |
}, |
| 215 |
'steal' => |
| 216 |
{
|
| 217 |
'label' => 'Steal', |
| 218 |
'info' => 'Involuntary wait', |
| 219 |
'type' => 'GAUGE', |
| 220 |
'draw' => 'AREASTACK', |
| 221 |
'min' => 0, |
| 222 |
'max' => 100 |
| 223 |
}, |
| 224 |
'guest' => |
| 225 |
{
|
| 226 |
'label' => 'Guest', |
| 227 |
'info' => 'Running a guest', |
| 228 |
'type' => 'GAUGE', |
| 229 |
'draw' => 'AREASTACK', |
| 230 |
'min' => 0, |
| 231 |
'max' => 100 |
| 232 |
}, |
| 233 |
'cpu_util' => |
| 234 |
{
|
| 235 |
'label' => ':t:', |
| 236 |
'info' => ':t: utilisation', |
| 237 |
'type' => 'GAUGE', |
| 238 |
'draw' => 'LINE0.5', |
| 239 |
'min' => 0, |
| 240 |
'max' => 100 |
| 241 |
}, |
| 242 |
'freq_percent' => |
| 243 |
{
|
| 244 |
'label' => 'CPU:t: frequency', |
| 245 |
'info' => 'CPU:t: frequency percent', |
| 246 |
'type' => 'GAUGE', |
| 247 |
'draw' => 'LINE0.5', |
| 248 |
'min' => 0, |
| 249 |
'max' => 100 |
| 250 |
}, |
| 251 |
'freq_hz' => |
| 252 |
{
|
| 253 |
'label' => ':t:', |
| 254 |
'info' => 'CPU :t: frequency', |
| 255 |
'type' => 'GAUGE', |
| 256 |
'draw' => 'AREASTACK', |
| 257 |
'min' => 0, |
| 258 |
'max' => 100 |
| 259 |
}, |
| 260 |
'freq_trans' => |
| 261 |
{
|
| 262 |
'label' => ':t:', |
| 263 |
'info' => ':t: frequency transitions', |
| 264 |
'type' => 'GAUGE', |
| 265 |
'draw' => 'LINE0.5', |
| 266 |
'min' => 0 |
| 267 |
}, |
| 268 |
'freq_trans_table' => |
| 269 |
{
|
| 270 |
'label' => ':t:', |
| 271 |
'info' => ':t: frequency switch', |
| 272 |
'type' => 'GAUGE', |
| 273 |
'draw' => 'AREASTACK', |
| 274 |
'min' => 0, |
| 275 |
'max' => 100 |
| 276 |
} |
| 277 |
|
| 278 |
}; |
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
# ----------------- main ---------------- |
| 283 |
load_cpuinfo(); |
| 284 |
need_multigraph(); |
| 285 |
remove_unavialabled_counters(); |
| 286 |
|
| 287 |
if (defined($ARGV[0]) and ($ARGV[0] eq 'autoconf')) |
| 288 |
{
|
| 289 |
printf("%s\n", -e $stat_file ? "yes" : "no (stats not exists)");
|
| 290 |
exit (0); |
| 291 |
} |
| 292 |
|
| 293 |
if (defined($ARGV[0]) and ($ARGV[0] eq 'config')) |
| 294 |
{
|
| 295 |
print_config(); |
| 296 |
exit (0); |
| 297 |
} |
| 298 |
|
| 299 |
print_values(); |
| 300 |
#print Dumper prepare_graphs_fields(); |
| 301 |
exit(0); |
| 302 |
|
| 303 |
# ----------------- sub's ---------------- |
| 304 |
|
| 305 |
# ----------------------- trim whitespace at begin and end of string ------------ |
| 306 |
sub trim |
| 307 |
{
|
| 308 |
my($string)=@_; |
| 309 |
for ($string) { s/^\s+//; s/\s+$//; }
|
| 310 |
return $string; |
| 311 |
} |
| 312 |
|
| 313 |
|
| 314 |
my $items_exists = {};
|
| 315 |
sub check_exists |
| 316 |
{
|
| 317 |
my ($t, $cpu_num) = @_[0..1]; |
| 318 |
if (defined($cpu_num)) |
| 319 |
{
|
| 320 |
unless (exists($items_exists->{$t}{$cpu_num}))
|
| 321 |
{
|
| 322 |
if ($t eq 'freq_hz') { $items_exists->{$t}{$cpu_num} = ( -e sprintf("%s/cpu%s/cpufreq/scaling_min_freq" , $freq_path, $cpu_num) and
|
| 323 |
-e sprintf("%s/cpu%s/cpufreq/scaling_cur_freq" , $freq_path, $cpu_num) and
|
| 324 |
-e sprintf("%s/cpu%s/cpufreq/scaling_max_freq" , $freq_path, $cpu_num)); }
|
| 325 |
elsif ($t eq 'freq_trans') { $items_exists->{$t}{$cpu_num} = -e sprintf("%s/cpu%s/cpufreq/stats/time_in_state", $freq_path, $cpu_num); }
|
| 326 |
elsif ($t eq 'freq_times') { $items_exists->{$t}{$cpu_num} = -e sprintf("%s/cpu%s/cpufreq/stats/total_trans" , $freq_path, $cpu_num); }
|
| 327 |
elsif ($t eq 'freq_ttable') { $items_exists->{$t}{$cpu_num} = -e sprintf("%s/cpu%s/cpufreq/stats/trans_table" , $freq_path, $cpu_num); }
|
| 328 |
} |
| 329 |
return $items_exists->{$t}{$cpu_num};
|
| 330 |
} |
| 331 |
else |
| 332 |
{
|
| 333 |
unless(exists($items_exists->{$t}{'total'}))
|
| 334 |
{
|
| 335 |
my $c = 0; |
| 336 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++) { $c++ if (check_exists($t, $i)); }
|
| 337 |
$items_exists->{$t}{'total'} = $c > 0;
|
| 338 |
} |
| 339 |
return $items_exists->{$t}{'total'};
|
| 340 |
} |
| 341 |
} |
| 342 |
|
| 343 |
# ------------------------- remove unavialable fields from graph -------------------------- |
| 344 |
sub remove_unavialabled_counters |
| 345 |
{
|
| 346 |
my @cpu = split(/\s+/, (grep(/cpu\s/, get_stat_file_content()))[0]); |
| 347 |
my $counters_count = scalar(@cpu) - 3; |
| 348 |
@cnames = @cnames[0..$counters_count]; |
| 349 |
} |
| 350 |
|
| 351 |
# ----------------------- get sysfs file content ---------------- |
| 352 |
my $fcontents = {};
|
| 353 |
sub get_sys_file_content |
| 354 |
{
|
| 355 |
my $file = $_[0]; |
| 356 |
return 'nan' if (-z $file); |
| 357 |
unless (exists($fcontents->{$file}))
|
| 358 |
{
|
| 359 |
open (FH, '<', $file) or die "$! $file \n"; |
| 360 |
$fcontents->{$file} = <FH>;
|
| 361 |
close (FH); |
| 362 |
chomp $fcontents->{$file};
|
| 363 |
} |
| 364 |
return $fcontents->{$file};
|
| 365 |
} |
| 366 |
|
| 367 |
# -------------------------- loading cpu info --------------------------------- |
| 368 |
sub load_cpuinfo |
| 369 |
{
|
| 370 |
my $file = "/proc/cpuinfo"; |
| 371 |
open (FH, '<', $file) or die "$! $file \n"; |
| 372 |
my $cpu_num = -1; |
| 373 |
for my $line (<FH>) |
| 374 |
{
|
| 375 |
chomp $line; |
| 376 |
$cpu_num++ if $line =~ m/^processor\s+:/; |
| 377 |
$cpuinfo->{$cpu_num}{'name'} = trim((split(/:/,$line))[1]) if $line =~ m/^model name\s+:/;
|
| 378 |
$cpuinfo->{$cpu_num}{'bogomips'} = trim((split(/:/,$line))[1]) if $line =~ m/^bogomips\s+:/;
|
| 379 |
if (not exists($cpuinfo->{$cpu_num}{'info'}) and exists($cpuinfo->{$cpu_num}{'name'}) and exists($cpuinfo->{$cpu_num}{'bogomips'}))
|
| 380 |
{
|
| 381 |
$cpuinfo->{$cpu_num}{'info'} = sprintf("[%s (%s bogomips)]", $cpuinfo->{$cpu_num}{'name'}, $cpuinfo->{$cpu_num}{'bogomips'}) ;
|
| 382 |
} |
| 383 |
} |
| 384 |
close (FH); |
| 385 |
$cpuinfo->{'cpu_count'} = $cpu_num+1;
|
| 386 |
} |
| 387 |
|
| 388 |
|
| 389 |
# -------------------------- loading stat file lines --------------------------------- |
| 390 |
sub get_stat_file_content |
| 391 |
{
|
| 392 |
if(scalar(@stat_file_content) == 0) |
| 393 |
{
|
| 394 |
open (FH, '<', $stat_file) or die "$! $stat_file \n"; |
| 395 |
for (<FH>) |
| 396 |
{
|
| 397 |
next unless $_ =~ m/cpu/; |
| 398 |
chomp $_; |
| 399 |
push(@stat_file_content, $_); |
| 400 |
} |
| 401 |
close (FH); |
| 402 |
} |
| 403 |
return @stat_file_content; |
| 404 |
} |
| 405 |
|
| 406 |
# -------------------------------- replacing strings ------------------------ |
| 407 |
sub replace_template |
| 408 |
{
|
| 409 |
my ($string, $needle, $replacement) = @_[0..2]; |
| 410 |
$string =~ s/$needle/$replacement/g; |
| 411 |
return $string; |
| 412 |
} |
| 413 |
|
| 414 |
sub replace_templates |
| 415 |
{
|
| 416 |
my ($src, $replacement_t, $replacement_i) = @_[0..2]; |
| 417 |
my $dst = {};
|
| 418 |
for my $key ( keys %{$src} )
|
| 419 |
{
|
| 420 |
$dst->{$key} = $src->{$key};
|
| 421 |
if($key =~ m/label|info|title/) { $dst->{$key} = replace_template($dst->{$key}, ':t:', $replacement_t); }
|
| 422 |
if($key =~ m/info|title/) { $dst->{$key} = replace_template($dst->{$key}, ':i:', $replacement_i); }
|
| 423 |
} |
| 424 |
return $dst; |
| 425 |
} |
| 426 |
|
| 427 |
sub append_order |
| 428 |
{
|
| 429 |
my ($pg, $graph_name, $field_name) = @_[0..2]; |
| 430 |
$pg->{$graph_name}{'graph'}{'order'} = exists($pg->{$graph_name}{'graph'}{'order'}) ? sprintf("%s %s", $pg->{$graph_name}{'graph'}{'order'}, $field_name) : $field_name;
|
| 431 |
} |
| 432 |
|
| 433 |
sub append_field |
| 434 |
{
|
| 435 |
my ($pg, $graph_name, $field_name, $field_src, $replacement_t, $replacement_i) = @_[0..5]; |
| 436 |
$pg->{$graph_name}{'fields'}{$field_name} = replace_templates($fields->{$field_src}, $replacement_t, $replacement_i);
|
| 437 |
append_order($pg, $graph_name, $field_name); |
| 438 |
} |
| 439 |
|
| 440 |
sub append_graph |
| 441 |
{
|
| 442 |
my ($pg, $graph_name, $category, $graph_src, $replacement_t, $replacement_i) = @_[0..5]; |
| 443 |
$pg->{$graph_name}{'graph'} = replace_templates($graphs->{$graph_src}, $replacement_t, $replacement_i);
|
| 444 |
$pg->{$graph_name}{'graph'}{'category'} = $category;
|
| 445 |
} |
| 446 |
|
| 447 |
# ---------------------------------------- preparing data for graphs ------------------------------------ |
| 448 |
sub prepare_graphs_fields |
| 449 |
{
|
| 450 |
my $pg = {};
|
| 451 |
# ------------------ cpu_utilisation ----------------------------------- |
| 452 |
# ---------- general ---------------------- |
| 453 |
append_graph($pg, 'cpu_utilisation', 'cpu', 'cpu_utilisation', '', ''); |
| 454 |
for my $cname (@cnames) { append_field($pg, 'cpu_utilisation', $cname, $cname, '', ''); append_utilisation_limits($pg, 'cpu_utilisation', $cname, undef); }
|
| 455 |
if(check_exists('freq_hz')) { for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { append_field($pg, 'cpu_utilisation', sprintf("fp_%s", $i), 'freq_percent', $i, ''); } }
|
| 456 |
# ---------------- childs ------------------- |
| 457 |
if ($cpuinfo->{'cpu_count'} > 1)
|
| 458 |
{
|
| 459 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 460 |
{
|
| 461 |
my $graph_name = sprintf("cpu_utilisation.cpu%s", $i);
|
| 462 |
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_utilisation', $i, $cpuinfo->{$i}{'info'});
|
| 463 |
for my $cname (@cnames) { append_field($pg, $graph_name, $cname, $cname, '', ''); append_utilisation_limits($pg, $graph_name, $cname, $i); }
|
| 464 |
if(check_exists('freq_hz', $i)) { append_field($pg, $graph_name, 'fp', 'freq_percent', '', ''); }
|
| 465 |
} |
| 466 |
} |
| 467 |
|
| 468 |
|
| 469 |
# --------------- cpu_frequency -------------------------------------------- |
| 470 |
if(check_exists('freq_trans'))
|
| 471 |
{
|
| 472 |
# ------------ general -------------------- |
| 473 |
# - cpu frequency transitions - |
| 474 |
append_graph($pg, 'cpu_frequency', 'cpu', 'cpu_freq_trans', '', ''); |
| 475 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { if (check_exists('freq_trans', $i)) { append_field($pg, 'cpu_frequency', sprintf("cpu_%s", $i), 'freq_trans', sprintf("CPU%s", $i), ''); } }
|
| 476 |
append_field($pg, 'cpu_frequency', 'total', 'freq_trans', 'Total', ''); |
| 477 |
# ---------------- childs ------------------- |
| 478 |
if(check_exists('freq_times'))
|
| 479 |
{
|
| 480 |
my $frequences = get_frequency_times(); |
| 481 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 482 |
{
|
| 483 |
if(check_exists('freq_times', $i))
|
| 484 |
{
|
| 485 |
# - cpu frequencyes - |
| 486 |
my $graph_name = sprintf("cpu_frequency.percent_cpu%s", $i);
|
| 487 |
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq', $i, $cpuinfo->{$i}{'info'});
|
| 488 |
for my $freq (@{$frequences->{'names'}{$i}}) { append_field($pg, $graph_name, sprintf("hz_%s", $freq), 'freq_hz', scaleNumber($freq, 'Hz'), ''); }
|
| 489 |
# - cpu frequencyes per secund - |
| 490 |
$graph_name = sprintf("cpu_frequency.percent_ps_cpu%s", $i);
|
| 491 |
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq_ps', $i, $cpuinfo->{$i}{'info'});
|
| 492 |
for my $freq (@{$frequences->{'names'}{$i}}) { append_field($pg, $graph_name, sprintf("hz_%s", $freq), 'freq_hz', scaleNumber($freq, 'Hz'), ''); }
|
| 493 |
} |
| 494 |
} |
| 495 |
} |
| 496 |
if(check_exists('freq_ttable'))
|
| 497 |
{
|
| 498 |
my $f_table = get_frequency_trans_table(); |
| 499 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 500 |
{
|
| 501 |
if(check_exists('freq_ttable', $i))
|
| 502 |
{
|
| 503 |
# - cpu frequencyes table - |
| 504 |
my $graph_name = sprintf("cpu_frequency.trans_table_cpu%s", $i);
|
| 505 |
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq_trans_table', $i, $cpuinfo->{$i}{'info'});
|
| 506 |
for my $from (sort keys %{$f_table->{'values'}{$i}})
|
| 507 |
{
|
| 508 |
for my $to (sort keys %{$f_table->{'values'}{$i}{$from}})
|
| 509 |
{
|
| 510 |
next if ($from eq $to); |
| 511 |
append_field($pg, $graph_name, sprintf("f_%s_t_%s", $from, $to), 'freq_trans_table', sprintf(". %9s -> %s", scaleNumber($from, 'Hz'), scaleNumber($to, 'Hz')), '');
|
| 512 |
} |
| 513 |
} |
| 514 |
# - cpu frequencyes table per secund - |
| 515 |
$graph_name = sprintf("cpu_frequency.trans_table_ps_cpu%s", $i);
|
| 516 |
append_graph($pg, $graph_name, sprintf("CPU %s", $i), 'cpu_freq_trans_table_ps', $i, $cpuinfo->{$i}{'info'});
|
| 517 |
for my $from (sort keys %{$f_table->{'values'}{$i}})
|
| 518 |
{
|
| 519 |
for my $to (sort keys %{$f_table->{'values'}{$i}{$from}})
|
| 520 |
{
|
| 521 |
next if ($from eq $to); |
| 522 |
append_field($pg, $graph_name, sprintf("f_%s_t_%s", $from, $to), 'freq_trans_table', sprintf(". %9s -> %s", scaleNumber($from, 'Hz'), scaleNumber($to, 'Hz')), '');
|
| 523 |
} |
| 524 |
} |
| 525 |
} |
| 526 |
} |
| 527 |
} |
| 528 |
} |
| 529 |
|
| 530 |
|
| 531 |
# --------------- cpu_all ----------------------------------------- |
| 532 |
if ($cpuinfo->{'cpu_count'} > 1)
|
| 533 |
{
|
| 534 |
append_graph($pg, 'cpu_all', 'cpu', 'cpu_all', '', ''); |
| 535 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { append_field($pg, 'cpu_all', sprintf("cpu_%s", $i), 'cpu_util', sprintf("CPU%s", $i)); }
|
| 536 |
append_field($pg, 'cpu_all', 'total', 'cpu_util', 'Combined'); |
| 537 |
} |
| 538 |
return $pg; |
| 539 |
} |
| 540 |
|
| 541 |
|
| 542 |
# ------------------------------------ printing limits (for utilisation graphs) ---------------- |
| 543 |
sub append_utilisation_limits |
| 544 |
{
|
| 545 |
my ($pg, $graph_name, $cname, $i) = @_[0..3]; |
| 546 |
for my $type (qw(warning critical)) |
| 547 |
{
|
| 548 |
my $field = sprintf("%s_%s", $cname, $type);
|
| 549 |
my $cpu_field = defined($i) ? sprintf("cpu%s_%s_%s", $i, $cname, $type) : undef;
|
| 550 |
my $limit = (defined($i) and defined($limits->{'utilisation'}{$cpu_field})) ?
|
| 551 |
$limits->{'utilisation'}{$cpu_field} :
|
| 552 |
( |
| 553 |
defined($limits->{'utilisation'}{$field}) ?
|
| 554 |
$limits->{'utilisation'}{$field} :
|
| 555 |
( |
| 556 |
defined($limits->{'utilisation'}{$type}) ?
|
| 557 |
$limits->{'utilisation'}{$type} :
|
| 558 |
undef |
| 559 |
) |
| 560 |
); |
| 561 |
if(defined($limit)) { $pg->{$graph_name}{'fields'}{$cname}{$type} = $limit; }
|
| 562 |
} |
| 563 |
} |
| 564 |
|
| 565 |
# ---------------- loading limits ------------- |
| 566 |
sub load_limits |
| 567 |
{
|
| 568 |
$limits->{'utilisation'}{'warning'} = $ENV{warning} || undef;
|
| 569 |
$limits->{'utilisation'}{'critical'} = $ENV{critical} || undef;
|
| 570 |
for my $cname (@cnames) |
| 571 |
{
|
| 572 |
for my $t (qw(warning critical)) |
| 573 |
{
|
| 574 |
my $name = sprintf("%s_%s", $cname, $t);
|
| 575 |
$limits->{'utilisation'}{$name} = $ENV{$name} || undef;
|
| 576 |
for (my $i = 0; $i <= $cpuinfo->{'cpu_count'}; $i++)
|
| 577 |
{
|
| 578 |
$name = sprintf("cpu%s_%s_%s",$i, $cname, $t);
|
| 579 |
$limits->{'utilisation'}{$name} = $ENV{$name} || undef;
|
| 580 |
} |
| 581 |
} |
| 582 |
} |
| 583 |
} |
| 584 |
|
| 585 |
# --------------------------------- graph configs ---------------------------- |
| 586 |
sub print_config |
| 587 |
{
|
| 588 |
load_limits(); |
| 589 |
my $config = prepare_graphs_fields(); |
| 590 |
for my $g (sort keys %{$config})
|
| 591 |
{
|
| 592 |
printf("multigraph %s\n", $g);
|
| 593 |
for my $go (sort keys %{$config->{$g}{'graph'}}) { printf("graph_%s %s\n", $go, $config->{$g}{'graph'}{$go}); }
|
| 594 |
for my $f (sort keys %{$config->{$g}{'fields'}}) { for my $fo (sort keys %{$config->{$g}{'fields'}{$f}}) { printf("%s.%s %s\n", $f, $fo, $config->{$g}{'fields'}{$f}{$fo}); } }
|
| 595 |
print "\n"; |
| 596 |
} |
| 597 |
} |
| 598 |
|
| 599 |
# ----------------------------------- saving state data using munin -------------------- |
| 600 |
sub save_state_data |
| 601 |
{
|
| 602 |
my $data = $_[0]; |
| 603 |
my $d = Data::Dumper->new([$data]); |
| 604 |
$d->Indent(0); |
| 605 |
save_state($d->Dump); |
| 606 |
} |
| 607 |
|
| 608 |
# -------------------------------- loading previous state data using munin ------------------- |
| 609 |
sub restore_state_data |
| 610 |
{
|
| 611 |
my $VAR1; |
| 612 |
my $states = (restore_state())[0]; |
| 613 |
eval $states if defined $states; |
| 614 |
return $VAR1; |
| 615 |
} |
| 616 |
|
| 617 |
sub load_stats |
| 618 |
{
|
| 619 |
my $stats = {};
|
| 620 |
# need to store -------------------- |
| 621 |
$stats->{'timestamp'} = time();
|
| 622 |
$stats->{'cpu_util'} = get_cpu_utilisation_stats() ;
|
| 623 |
$stats->{'f_trans'} = get_frequency_transitions() if check_exists('freq_trans') ;
|
| 624 |
$stats->{'f_times'} = get_frequency_times() if check_exists('freq_times') ;
|
| 625 |
$stats->{'f_ttable'} = get_frequency_trans_table() if check_exists('freq_ttable');
|
| 626 |
|
| 627 |
save_state_data($stats); |
| 628 |
|
| 629 |
# no need to store -------------------- |
| 630 |
$stats->{'f_minmax'} = get_cpu_curr_max_freqences() if check_exists('freq_hz') ;
|
| 631 |
|
| 632 |
|
| 633 |
#print Dumper $stats; |
| 634 |
return $stats; |
| 635 |
} |
| 636 |
|
| 637 |
# ---------------------------------- loading cpu stats from loaded lines ------------------------ |
| 638 |
sub get_cpu_utilisation_stats |
| 639 |
{
|
| 640 |
my $stats = {};
|
| 641 |
for (my $i = 0; $i <= $cpuinfo->{'cpu_count'}; $i++)
|
| 642 |
{
|
| 643 |
my $rx = $i == $cpuinfo->{'cpu_count'} ? 'cpu' : sprintf ("cpu%s", $i);
|
| 644 |
my $cn = $i == $cpuinfo->{'cpu_count'} ? 'total' : $i;
|
| 645 |
my @tmp = split(/\s+/, (grep(/$rx\s/, get_stat_file_content()))[0]); |
| 646 |
my $j = 1; |
| 647 |
for my $cname (@cnames) |
| 648 |
{
|
| 649 |
$stats->{$cn}{$cname} = $tmp[$j];
|
| 650 |
$j++; |
| 651 |
} |
| 652 |
} |
| 653 |
return $stats; |
| 654 |
} |
| 655 |
# ------------------ loading frequency transitions for each cpu ---------------------------- |
| 656 |
sub get_frequency_transitions |
| 657 |
{
|
| 658 |
my $stats = {};
|
| 659 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 660 |
{
|
| 661 |
next unless (check_exists('freq_trans', $i));
|
| 662 |
$stats->{$i} = get_sys_file_content(sprintf("%s/cpu%s/cpufreq/stats/total_trans", $freq_path, $i));
|
| 663 |
} |
| 664 |
return $stats; |
| 665 |
} |
| 666 |
|
| 667 |
# ------------------ loading frequency times for each cpu ---------------------------- |
| 668 |
sub get_frequency_times |
| 669 |
{
|
| 670 |
my $stat = {};
|
| 671 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 672 |
{
|
| 673 |
next unless (check_exists('freq_times', $i));
|
| 674 |
my $total = 0; |
| 675 |
my $file = sprintf("%s/cpu%s/cpufreq/stats/time_in_state", $freq_path, $i);
|
| 676 |
open (FH, '<', $file) or die "$! $file \n"; |
| 677 |
for my $line (<FH>) |
| 678 |
{
|
| 679 |
chomp $line; |
| 680 |
my ($hz, $count) = split(/\s+/, $line); |
| 681 |
$hz = $hz*$freq_mul; |
| 682 |
$stat->{'values'}{$i}{$hz} = $count;
|
| 683 |
push(@{$stat->{'names'}{$i}}, $hz);
|
| 684 |
$total += $count; |
| 685 |
} |
| 686 |
close (FH); |
| 687 |
$stat->{'total'}{$i} = $total;
|
| 688 |
} |
| 689 |
return $stat; |
| 690 |
} |
| 691 |
|
| 692 |
# ------------------ loading current and max frequency for each cpu ---------------------------- |
| 693 |
sub get_cpu_curr_max_freqences |
| 694 |
{
|
| 695 |
my $freq = {};
|
| 696 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 697 |
{
|
| 698 |
next unless (check_exists('freq_hz', $i));
|
| 699 |
my $cpu_path = sprintf("%s/cpu%s/cpufreq", $freq_path, $i);
|
| 700 |
$freq->{'cur'}{$i} = get_sys_file_content(sprintf("%s/scaling_cur_freq", $cpu_path))*$freq_mul;
|
| 701 |
$freq->{'max'}{$i} = get_sys_file_content(sprintf("%s/scaling_max_freq", $cpu_path))*$freq_mul;
|
| 702 |
$freq->{'min'}{$i} = get_sys_file_content(sprintf("%s/scaling_min_freq", $cpu_path))*$freq_mul;
|
| 703 |
} |
| 704 |
return $freq; |
| 705 |
} |
| 706 |
|
| 707 |
sub get_frequency_trans_table |
| 708 |
{
|
| 709 |
my $tbl = {};
|
| 710 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 711 |
{
|
| 712 |
next unless (check_exists('freq_ttable', $i));
|
| 713 |
my @frequences; |
| 714 |
my $fcount = 0; |
| 715 |
my $total = 0; |
| 716 |
my $file = sprintf("%s/cpu%s/cpufreq/stats/trans_table", $freq_path, $i);
|
| 717 |
open (FH, '<', $file) or die "$! $file \n"; |
| 718 |
for my $line (<FH>) |
| 719 |
{
|
| 720 |
chomp $line; |
| 721 |
my ($left, $right) = split(/:/, $line); |
| 722 |
next if($left =~ m/From/); |
| 723 |
if($left =~ m/\d+/) |
| 724 |
{
|
| 725 |
my $frequence = trim($left)*$freq_mul; |
| 726 |
my @counters = split(/\s+/, trim($right)); |
| 727 |
for (my $j = 0; $j<$fcount; $j++) |
| 728 |
{
|
| 729 |
$tbl->{'values'}{$i}{$frequence}{$frequences[$j]*$freq_mul} = $counters[$j];
|
| 730 |
$total += $counters[$j]; |
| 731 |
} |
| 732 |
} |
| 733 |
else |
| 734 |
{
|
| 735 |
@frequences = split(/\s+/, trim($right)); |
| 736 |
$fcount = scalar(@frequences); |
| 737 |
} |
| 738 |
} |
| 739 |
$tbl->{'total'}{$i} = $total;
|
| 740 |
close (FH); |
| 741 |
} |
| 742 |
return $tbl; |
| 743 |
} |
| 744 |
|
| 745 |
sub one_second_part |
| 746 |
{
|
| 747 |
my ($curr, $prev, $timediff) = @_[0..2]; |
| 748 |
#print "$prev, $curr, $timediff\n"; |
| 749 |
return 'NaN' if ($curr < $prev or $timediff < 0); |
| 750 |
return $curr - $prev if $timediff == 0; |
| 751 |
return ($curr - $prev)/$timediff; |
| 752 |
} |
| 753 |
|
| 754 |
sub divide |
| 755 |
{
|
| 756 |
my ($divider, $divident) = @_[0..1]; |
| 757 |
return 'NaN' if $divident == 0; |
| 758 |
return $divider/$divident; |
| 759 |
} |
| 760 |
|
| 761 |
# -------------------------------- calculating fields values ------------------------------ |
| 762 |
sub calculate |
| 763 |
{
|
| 764 |
my ($pstats, $cstats) = @_[0..1]; |
| 765 |
my $result = {};
|
| 766 |
my $timediff = $cstats->{'timestamp'} - $pstats->{'timestamp'};
|
| 767 |
# --- cpu utilisation ---- |
| 768 |
for my $cpu (keys %{$cstats->{'cpu_util'}})
|
| 769 |
{
|
| 770 |
# ------ calculating 1% |
| 771 |
$result->{'cpu_util'}{'1%'}{$cpu} = 0;
|
| 772 |
for my $cname (@cnames) |
| 773 |
{
|
| 774 |
$result->{'cpu_util'}{'diff'}{$cpu}{$cname} = one_second_part($cstats->{'cpu_util'}{$cpu}{$cname}, $pstats->{'cpu_util'}{$cpu}{$cname}, $timediff);
|
| 775 |
$result->{'cpu_util'}{'1%'}{$cpu} += $result->{'cpu_util'}{'diff'}{$cpu}{$cname} if $result->{'cpu_util'}{'diff'}{$cpu}{$cname} ne 'NaN';
|
| 776 |
} |
| 777 |
$result->{'cpu_util'}{'1%'}{$cpu} = $result->{'cpu_util'}{'1%'}{$cpu}/100;
|
| 778 |
# ------ calculating used percents |
| 779 |
$result->{'cpu_util'}{'used'}{$cpu} = 0;
|
| 780 |
for my $cname (@cnames) |
| 781 |
{
|
| 782 |
$result->{'cpu_util'}{'%'}{$cpu}{$cname} = divide($result->{'cpu_util'}{'diff'}{$cpu}{$cname}, $result->{'cpu_util'}{'1%'}{$cpu});
|
| 783 |
next if $cname eq 'idle'; |
| 784 |
$result->{'cpu_util'}{'used'}{$cpu} += $result->{'cpu_util'}{'%'}{$cpu}{$cname} if $result->{'cpu_util'}{'%'}{$cpu}{$cname} ne 'NaN';
|
| 785 |
} |
| 786 |
} |
| 787 |
# ------ freq min max ---- |
| 788 |
if (check_exists('freq_hz'))
|
| 789 |
{
|
| 790 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 791 |
{
|
| 792 |
$result->{'f_minmax'}{'%'}{$i} = divide($cstats->{'f_minmax'}{'cur'}{$i} - $cstats->{'f_minmax'}{'min'}{$i},
|
| 793 |
(($cstats->{'f_minmax'}{'max'}{$i} - $cstats->{'f_minmax'}{'min'}{$i}) / 100 )) if (check_exists('freq_hz', $i));
|
| 794 |
} |
| 795 |
} |
| 796 |
# ---- freq trans ---- |
| 797 |
if (check_exists('freq_trans'))
|
| 798 |
{
|
| 799 |
$result->{'f_trans'}{'total'} = 0;
|
| 800 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 801 |
{
|
| 802 |
if(check_exists('freq_trans', $i))
|
| 803 |
{
|
| 804 |
$result->{'f_trans'}{$i} = one_second_part($cstats->{'f_trans'}{$i}, $pstats->{'f_trans'}{$i}, $timediff);
|
| 805 |
$result->{'f_trans'}{'total'} += $result->{'f_trans'}{$i} if $result->{'f_trans'}{$i} ne 'NaN';
|
| 806 |
} |
| 807 |
} |
| 808 |
} |
| 809 |
# -- freq times --- |
| 810 |
if (check_exists('freq_times'))
|
| 811 |
{
|
| 812 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 813 |
{
|
| 814 |
if (check_exists('freq_times', $i))
|
| 815 |
{
|
| 816 |
my $oneprc = $cstats->{'f_times'}{'total'}{$i}/100;
|
| 817 |
my $ps_total = 0; |
| 818 |
for my $hz (@{$cstats->{'f_times'}{'names'}{$i}})
|
| 819 |
{
|
| 820 |
$result->{'f_times'}{$i}{$hz} = divide($cstats->{'f_times'}{'values'}{$i}{$hz}, $oneprc);
|
| 821 |
$cstats->{'f_times'}{'%_ps'}{$i}{$hz} = one_second_part($cstats->{'f_times'}{'values'}{$i}{$hz}, $pstats->{'f_times'}{'values'}{$i}{$hz}, $timediff);
|
| 822 |
$ps_total += $cstats->{'f_times'}{'%_ps'}{$i}{$hz};
|
| 823 |
} |
| 824 |
$ps_total = $ps_total/100; |
| 825 |
for my $hz (@{$cstats->{'f_times'}{'names'}{$i}})
|
| 826 |
{
|
| 827 |
$result->{'f_times_ps'}{$i}{$hz} = divide($cstats->{'f_times'}{'%_ps'}{$i}{$hz}, $ps_total);
|
| 828 |
} |
| 829 |
} |
| 830 |
} |
| 831 |
} |
| 832 |
# ------- freq trans table --- |
| 833 |
if (check_exists('freq_ttable'))
|
| 834 |
{
|
| 835 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 836 |
{
|
| 837 |
if (check_exists('freq_ttable', $i))
|
| 838 |
{
|
| 839 |
my $oneprc = $cstats->{'f_ttable'}{'total'}{$i}/100;
|
| 840 |
my $ps_total = 0; |
| 841 |
for my $from (keys %{$cstats->{'f_ttable'}{'values'}{$i}})
|
| 842 |
{
|
| 843 |
for my $to (keys %{$cstats->{'f_ttable'}{'values'}{$i}{$from}})
|
| 844 |
{
|
| 845 |
next if ($from eq $to); |
| 846 |
$result->{'f_ttable'}{$i}{$from}{$to} = divide($cstats->{'f_ttable'}{'values'}{$i}{$from}{$to}, $oneprc);
|
| 847 |
$cstats->{'f_ttable'}{'%_ps'}{$i}{$from}{$to} = one_second_part($cstats->{'f_ttable'}{'values'}{$i}{$from}{$to}, $pstats->{'f_ttable'}{'values'}{$i}{$from}{$to}, $timediff);
|
| 848 |
$ps_total += $cstats->{'f_ttable'}{'%_ps'}{$i}{$from}{$to};
|
| 849 |
} |
| 850 |
} |
| 851 |
$ps_total = $ps_total/100; |
| 852 |
for my $from (keys %{$cstats->{'f_ttable'}{'values'}{$i}})
|
| 853 |
{
|
| 854 |
for my $to (keys %{$cstats->{'f_ttable'}{'values'}{$i}{$from}})
|
| 855 |
{
|
| 856 |
next if ($from eq $to); |
| 857 |
$result->{'f_ttable_ps'}{$i}{$from}{$to} = divide($cstats->{'f_ttable'}{'%_ps'}{$i}{$from}{$to}, $ps_total);
|
| 858 |
} |
| 859 |
} |
| 860 |
} |
| 861 |
} |
| 862 |
} |
| 863 |
#print Dumper $result; |
| 864 |
return $result; |
| 865 |
} |
| 866 |
|
| 867 |
# ---------------------------------------- preparing values ------------------------------------ |
| 868 |
sub prepare_graphs_values |
| 869 |
{
|
| 870 |
my ($data) = $_[0]; |
| 871 |
my $pg = {};
|
| 872 |
# ------------------ cpu_utilisation ----------------------------------- |
| 873 |
# ---------- general ---------------------- |
| 874 |
for my $cname (@cnames) { $pg->{'cpu_utilisation'}{$cname} = $data->{'cpu_util'}{'%'}{'total'}{$cname}; }
|
| 875 |
if(check_exists('freq_hz')) { for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { $pg->{'cpu_utilisation'}{sprintf("fp_%s", $i)} = $data->{'f_minmax'}{'%'}{$i}; } }
|
| 876 |
# ---------------- childs ------------------- |
| 877 |
if ($cpuinfo->{'cpu_count'} > 1)
|
| 878 |
{
|
| 879 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 880 |
{
|
| 881 |
my $graph_name = sprintf("cpu_utilisation.cpu%s", $i);
|
| 882 |
for my $cname (@cnames) { $pg->{$graph_name}{$cname} = $data->{'cpu_util'}{'%'}{$i}{$cname}; }
|
| 883 |
if(check_exists('freq_hz', $i)) { $pg->{$graph_name}{'fp'} = $data->{'f_minmax'}{'%'}{$i}; }
|
| 884 |
} |
| 885 |
} |
| 886 |
|
| 887 |
|
| 888 |
# --------------- cpu_frequency -------------------------------------------- |
| 889 |
if(check_exists('freq_trans'))
|
| 890 |
{
|
| 891 |
# ------------ general -------------------- |
| 892 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { $pg->{'cpu_frequency'}{sprintf("cpu_%s", $i)} = $data->{'f_trans'}{$i} if (check_exists('freq_trans', $i)); }
|
| 893 |
$pg->{'cpu_frequency'}{'total'} = $data->{'f_trans'}{'total'};
|
| 894 |
# ---------------- childs ------------------- |
| 895 |
if(check_exists('freq_times'))
|
| 896 |
{
|
| 897 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 898 |
{
|
| 899 |
if(check_exists('freq_times', $i))
|
| 900 |
{
|
| 901 |
my $graph_name = sprintf("cpu_frequency.percent_cpu%s", $i);
|
| 902 |
for my $freq (keys %{$data->{'f_times'}{$i}}) { $pg->{$graph_name}{sprintf("hz_%s", $freq)} = $data->{'f_times'}{$i}{$freq}; }
|
| 903 |
$graph_name = sprintf("cpu_frequency.percent_ps_cpu%s", $i);
|
| 904 |
for my $freq (keys %{$data->{'f_times_ps'}{$i}}) { $pg->{$graph_name}{sprintf("hz_%s", $freq)} = $data->{'f_times_ps'}{$i}{$freq}; }
|
| 905 |
} |
| 906 |
} |
| 907 |
} |
| 908 |
if(check_exists('freq_ttable'))
|
| 909 |
{
|
| 910 |
for (my $i=0; $i < $cpuinfo->{'cpu_count'}; $i++)
|
| 911 |
{
|
| 912 |
if(check_exists('freq_ttable', $i))
|
| 913 |
{
|
| 914 |
my $graph_name = sprintf("cpu_frequency.trans_table_cpu%s", $i);
|
| 915 |
for my $from (keys %{$data->{'f_ttable'}{$i}})
|
| 916 |
{
|
| 917 |
for my $to (keys %{$data->{'f_ttable'}{$i}{$from}})
|
| 918 |
{
|
| 919 |
$pg->{$graph_name}{sprintf("f_%s_t_%s", $from, $to)} = $data->{'f_ttable'}{$i}{$from}{$to};
|
| 920 |
} |
| 921 |
} |
| 922 |
$graph_name = sprintf("cpu_frequency.trans_table_ps_cpu%s", $i);
|
| 923 |
for my $from (keys %{$data->{'f_ttable_ps'}{$i}})
|
| 924 |
{
|
| 925 |
for my $to (keys %{$data->{'f_ttable_ps'}{$i}{$from}})
|
| 926 |
{
|
| 927 |
$pg->{$graph_name}{sprintf("f_%s_t_%s", $from, $to)} = $data->{'f_ttable_ps'}{$i}{$from}{$to};
|
| 928 |
} |
| 929 |
} |
| 930 |
} |
| 931 |
} |
| 932 |
} |
| 933 |
} |
| 934 |
|
| 935 |
# --------------- cpu_all -------------------------------------------- |
| 936 |
if ($cpuinfo->{'cpu_count'} > 1)
|
| 937 |
{
|
| 938 |
for (my $i = 0; $i < $cpuinfo->{'cpu_count'}; $i++) { $pg->{'cpu_all'}{sprintf("cpu_%s", $i)} = $data->{'cpu_util'}{'used'}{$i}; }
|
| 939 |
$pg->{'cpu_all'}{'total'} = $data->{'cpu_util'}{'used'}{'total'};
|
| 940 |
} |
| 941 |
return $pg; |
| 942 |
} |
| 943 |
|
| 944 |
|
| 945 |
|
| 946 |
# -------------------------------- printing values ----------------------------------- |
| 947 |
sub print_values |
| 948 |
{
|
| 949 |
my $pstats = restore_state_data(); |
| 950 |
my $cstats = load_stats(); |
| 951 |
if (exists ($pstats->{'timestamp'}))
|
| 952 |
{
|
| 953 |
my $values = prepare_graphs_values(calculate($pstats, $cstats)); |
| 954 |
#print Dumper $values; |
| 955 |
for my $g (sort keys %{$values})
|
| 956 |
{
|
| 957 |
printf("multigraph %s\n", $g);
|
| 958 |
for my $f (sort keys %{$values->{$g}}) { printf("%s.value %s\n", $f, $values->{$g}{$f}); }
|
| 959 |
print "\n"; |
| 960 |
} |
| 961 |
} |
| 962 |
} |
| 963 |
|
| 964 |
__END__ |
| 965 |
|
| 966 |
- user: normal processes executing in user mode |
| 967 |
- nice: niced processes executing in user mode |
| 968 |
- system: processes executing in kernel mode |
| 969 |
- idle: twiddling thumbs |
| 970 |
- iowait: waiting for I/O to complete |
| 971 |
- irq: servicing interrupts |
| 972 |
- softirq: servicing softirqs |
| 973 |
- steal: involuntary wait |
| 974 |
- guest: running a guest |
