-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathprocstat-post-process
executable file
·102 lines (98 loc) · 4.73 KB
/
procstat-post-process
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/perl
## -*- mode: perl; indent-tabs-mode: nil; perl-indent-level: 4 -*-
## vim: autoindent tabstop=4 shiftwidth=4 expandtab softtabstop=4 filetype=perl
use strict;
use warnings;
use JSON::XS;
use JSON::Validator;
use Data::Dumper;
use File::pushd;
BEGIN {
if (!(exists $ENV{'TOOLBOX_HOME'} && -d "$ENV{'TOOLBOX_HOME'}/perl")) {
print "This script requires libraries that are provided by the toolbox project.\n";
print "Toolbox can be acquired from https://github.com/perftool-incubator/toolbox and\n";
print "then use 'export TOOLBOX_HOME=/path/to/toolbox' so that it can be located.\n";
exit 1;
}
}
use lib "$ENV{'TOOLBOX_HOME'}/perl";
use toolbox::json;
use toolbox::cpu;
use toolbox::metrics;
my $num_forks = 16;
my $count = 1;
my $cpu_topo_ref = build_cpu_topology("sys/devices/system/cpu");
my %metric_types;
my $data_dir = "proc";
my $dh;
opendir($dh, $data_dir);
for my $log_file (sort readdir($dh)) {
if (($log_file =~ /^interrupts$/) || ($log_file =~ /^interrupts.xz$/)) {
my @pids;
for (my $i = 0; $i < $num_forks; $i++) {
if (my $pid = fork) {
push(@pids, $pid);
} else { # child
my $metric_type = "interrupts-sec";
my %metric_desc = ('class' => 'throughput', 'source' => 'procstat', 'type' => $metric_type);
my $curr_timestamp_ms; # Epochtime in milliseconds
my $prev_timestamp_ms; # Epochtime in milliseconds
my $log_fh = new IO::Uncompress::UnXz $data_dir . "/" . $log_file, Transparent => 1 || die "[ERROR]could not open file " . $log_file;
my @cpu_ids;
my %curr_irq_counts; # {'irq-num'}{'cpu-id'}
my %prev_irq_counts; # {'irq-num'}{'cpu-id'}
my $num_cpus;
my $first_cpu_idx;
my $last_cpu_idx;
while (<$log_fh>) {
chomp;
if ( /^\s*([A-Z]{3}|[0-9]+):([^a-z,A-Z]+)(.*)/ ) {
my $irq = $1;
my $counts = $2;
my $extra = $3;
# example output
# 41: 0 0 0 0 0 0 0 IR-PCI-MSI 91275264-edge PCIe PME, pciehp
my @counts = split(/\s+/, $counts);
shift(@counts);
(my $type, my $other, my $desc) = split(/\s+/, $extra);
for (my $cpu_idx = $first_cpu_idx; $cpu_idx < $last_cpu_idx; $cpu_idx++) {
my $cpu = $cpu_ids[$cpu_idx];
$curr_irq_counts{$irq}{$cpu} = $counts[$cpu_idx];
if (exists $prev_irq_counts{$irq}{$cpu} and defined $prev_irq_counts{$irq}{$cpu}) {
my $irq_count_diff = $curr_irq_counts{$irq}{$cpu} - $prev_irq_counts{$irq}{$cpu};
my $time_diff_sec = ($curr_timestamp_ms - $prev_timestamp_ms) / 1000;
my $ints_sec = $irq_count_diff / $time_diff_sec;
(my $package, my $die, my $core, my $thread) = get_cpu_topology($cpu, $cpu_topo_ref);
my %metric_names = ('package' => $package, 'die' => $die, 'core' => $core, 'thread' => $thread, 'cpu' => $cpu, 'irq' => $irq, 'type' => $type, 'desc' => $desc);
my %sample = ( 'value' => $ints_sec, 'end' => $curr_timestamp_ms );
log_sample($i, \%metric_desc, \%metric_names, \%sample);
}
$prev_irq_counts{$irq}{$cpu} = $curr_irq_counts{$irq}{$cpu};
}
} elsif ( /^\s+(CPU\d+\s+)+/) {
@cpu_ids = split(/\s*CPU/, $_);
shift(@cpu_ids);
s/(\d+)\s*/$1/ for @cpu_ids;
$num_cpus = scalar @cpu_ids;
$first_cpu_idx = int $i * ($num_cpus / $num_forks);
$last_cpu_idx = int (($i + 1) * ($num_cpus / $num_forks));
if ($num_cpus < $last_cpu_idx) {
$last_cpu_idx = $num_cpus;
}
} elsif (/^DATE:(\d+\.\d+)$/) {
if (defined($curr_timestamp_ms)) {
$prev_timestamp_ms = $curr_timestamp_ms;
}
$curr_timestamp_ms = int ($1 * 1000);
$count++;
}
}
finish_samples();
close($log_fh);
exit;
} # finish child
}
}
}
while (wait() > -1) {}
closedir $dh;