File Coverage

blib/lib/Linux/GetPidstat/Collector/Parser.pm
Criterion Covered Total %
statement 46 46 100.0
branch 11 12 91.6
condition 4 6 66.6
subroutine 11 11 100.0
pod 0 1 0.0
total 72 76 94.7


line stmt bran cond sub pod time code
1             package Linux::GetPidstat::Collector::Parser;
2 23     23   35196 use 5.008001;
  23         72  
3 23     23   95 use strict;
  23         46  
  23         420  
4 23     23   93 use warnings;
  23         46  
  23         548  
5              
6 23     23   123 use Exporter qw(import);
  23         108  
  23         886  
7 23     23   132 use List::Util qw(sum reduce);
  23         26  
  23         10773  
8              
9             our @EXPORT = qw(parse_pidstat_output);
10              
11             sub parse ($) {
12 20     20 0 4017 my $lines = shift;
13              
14 20         77 my $ret;
15              
16 20         117 my $mapping = _get_metric_rule_mapping();
17 20         73 my $pid_rule = delete $mapping->{pid};
18 20         209 while (my ($name, $metric_rule) = each %$mapping) {
19 140         350 my $metric = _get_metric_mean($metric_rule, $pid_rule, $lines);
20 140 100       582 unless (defined $metric) {
21 5         237 warn (sprintf "Empty metric: name=%s, lines=%s\n",
22             $name, join ',', @$lines);
23 5         75 return;
24             }
25              
26             # ex. cpu => 21.0
27 135         636 $ret->{$name} = $metric;
28             }
29              
30 15         184 return $ret;
31             }
32              
33             sub _get_metric_rule_mapping() {
34 745     745   1215 my $convert_from_kilobytes = sub { my $raw = shift; return $raw * 1000 };
  745     20   1842  
  20         208  
35              
36             return {
37 20         523 pid => {
38             column_num => 2,
39             },
40             cpu => {
41             column_num => 6,
42             },
43             memory_percent => {
44             column_num => 12,
45             },
46             memory_rss => {
47             column_num => 11,
48             convert_func => $convert_from_kilobytes,
49             },
50             stk_size => {
51             column_num => 13,
52             convert_func => $convert_from_kilobytes,
53             },
54             stk_ref => {
55             column_num => 14,
56             convert_func => $convert_from_kilobytes,
57             },
58             disk_read_per_sec => {
59             column_num => 15,
60             convert_func => $convert_from_kilobytes,
61             },
62             disk_write_per_sec => {
63             column_num => 16,
64             convert_func => $convert_from_kilobytes,
65             },
66             cswch_per_sec => {
67             column_num => 18,
68             },
69             nvcswch_per_sec => {
70             column_num => 19,
71             },
72             };
73             }
74              
75             sub _get_metric_mean($$) {
76 140     140   314 my ($metric_rule, $pid_rule, $lines) = @_;
77              
78 140         303 my %metrics;
79 140         320 for (@$lines) {
80 2517         9234 my @fields = split " ";
81              
82 2517         4766 my $pid = $fields[$pid_rule->{column_num}];
83 2517 100 100     11708 next unless defined $pid && $pid =~ /^\d+$/;
84              
85 1341         2702 my $metric = $fields[$metric_rule->{column_num}];
86 1341 50 33     5895 next unless defined $metric && $metric =~ /^[-+]?[0-9.]+$/;
87 1341 100       3293 if (my $cf = $metric_rule->{convert_func}) {
88 745         1575 $metric = $cf->($metric);
89             }
90              
91 1341 100       3370 $metrics{$pid} = [] unless exists $metrics{$pid};
92 1341         2096 push @{ $metrics{$pid} }, $metric;
  1341         4407  
93             }
94              
95 140 100       466 return unless %metrics;
96 135     342   1264 return reduce { $a + _mean(@$b) } (0, values %metrics);
  342         903  
97             }
98              
99             sub _mean(@) {
100 342     342   3005 return sprintf '%.2f', sum(@_)/@_;
101             }
102              
103             *parse_pidstat_output = \&parse;
104              
105             1;
106             __END__