line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Sys::Statgrab; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
$VERSION = 0.01; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
29263
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
51
|
|
6
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
221
|
|
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
|
|
257
|
use constant STATGRAB_CONSTANTS => qw( |
9
|
|
|
|
|
|
|
SG_ERROR_ASPRINTF |
10
|
|
|
|
|
|
|
SG_ERROR_DEVSTAT_GETDEVS |
11
|
|
|
|
|
|
|
SG_ERROR_DEVSTAT_SELECTDEVS |
12
|
|
|
|
|
|
|
SG_ERROR_ENOENT |
13
|
|
|
|
|
|
|
SG_ERROR_GETIFADDRS |
14
|
|
|
|
|
|
|
SG_ERROR_GETMNTINFO |
15
|
|
|
|
|
|
|
SG_ERROR_GETPAGESIZE |
16
|
|
|
|
|
|
|
SG_ERROR_KSTAT_DATA_LOOKUP |
17
|
|
|
|
|
|
|
SG_ERROR_KSTAT_LOOKUP |
18
|
|
|
|
|
|
|
SG_ERROR_KSTAT_OPEN |
19
|
|
|
|
|
|
|
SG_ERROR_KSTAT_READ |
20
|
|
|
|
|
|
|
SG_ERROR_KVM_GETSWAPINFO |
21
|
|
|
|
|
|
|
SG_ERROR_KVM_OPENFILES |
22
|
|
|
|
|
|
|
SG_ERROR_MALLOC |
23
|
|
|
|
|
|
|
SG_ERROR_NONE |
24
|
|
|
|
|
|
|
SG_ERROR_OPEN |
25
|
|
|
|
|
|
|
SG_ERROR_OPENDIR |
26
|
|
|
|
|
|
|
SG_ERROR_PARSE |
27
|
|
|
|
|
|
|
SG_ERROR_SETEGID |
28
|
|
|
|
|
|
|
SG_ERROR_SETEUID |
29
|
|
|
|
|
|
|
SG_ERROR_SETMNTENT |
30
|
|
|
|
|
|
|
SG_ERROR_SOCKET |
31
|
|
|
|
|
|
|
SG_ERROR_SWAPCTL |
32
|
|
|
|
|
|
|
SG_ERROR_SYSCONF |
33
|
|
|
|
|
|
|
SG_ERROR_SYSCTL |
34
|
|
|
|
|
|
|
SG_ERROR_SYSCTLBYNAME |
35
|
|
|
|
|
|
|
SG_ERROR_SYSCTLNAMETOMIB |
36
|
|
|
|
|
|
|
SG_ERROR_UNAME |
37
|
|
|
|
|
|
|
SG_ERROR_UNSUPPORTED |
38
|
|
|
|
|
|
|
SG_ERROR_XSW_VER_MISMATCH |
39
|
|
|
|
|
|
|
SG_IFACE_DUPLEX_FULL |
40
|
|
|
|
|
|
|
SG_IFACE_DUPLEX_HALF |
41
|
|
|
|
|
|
|
SG_IFACE_DUPLEX_UNKNOWN |
42
|
|
|
|
|
|
|
SG_PROCESS_STATE_RUNNING |
43
|
|
|
|
|
|
|
SG_PROCESS_STATE_SLEEPING |
44
|
|
|
|
|
|
|
SG_PROCESS_STATE_STOPPED |
45
|
|
|
|
|
|
|
SG_PROCESS_STATE_UNKNOWN |
46
|
|
|
|
|
|
|
SG_PROCESS_STATE_ZOMBIE |
47
|
1
|
|
|
1
|
|
7
|
); |
|
1
|
|
|
|
|
12
|
|
48
|
1
|
|
|
|
|
86
|
use constant STATGRAB_BASE_FUNCTIONS => qw( |
49
|
|
|
|
|
|
|
get_error drop_privileges |
50
|
|
|
|
|
|
|
get_host_info |
51
|
|
|
|
|
|
|
get_cpu_stats get_cpu_stats_diff get_cpu_percents |
52
|
|
|
|
|
|
|
get_disk_io_stats get_disk_io_stats_diff |
53
|
|
|
|
|
|
|
get_fs_stats |
54
|
|
|
|
|
|
|
get_load_stats |
55
|
|
|
|
|
|
|
get_mem_stats |
56
|
|
|
|
|
|
|
get_swap_stats |
57
|
|
|
|
|
|
|
get_network_io_stats get_network_io_stats_diff |
58
|
|
|
|
|
|
|
get_network_iface_stats |
59
|
|
|
|
|
|
|
get_page_stats get_page_stats_diff |
60
|
|
|
|
|
|
|
get_user_stats |
61
|
|
|
|
|
|
|
get_process_stats |
62
|
1
|
|
|
1
|
|
6
|
); |
|
1
|
|
|
|
|
2
|
|
63
|
1
|
|
|
|
|
64
|
use constant STATGRAB_SORT_FUNCTIONS => qw( |
64
|
|
|
|
|
|
|
sort_procs_by_name |
65
|
|
|
|
|
|
|
sort_procs_by_pid |
66
|
|
|
|
|
|
|
sort_procs_by_uid |
67
|
|
|
|
|
|
|
sort_procs_by_gid |
68
|
|
|
|
|
|
|
sort_procs_by_size |
69
|
|
|
|
|
|
|
sort_procs_by_res |
70
|
|
|
|
|
|
|
sort_procs_by_cpu |
71
|
|
|
|
|
|
|
sort_procs_by_time |
72
|
1
|
|
|
1
|
|
7
|
); |
|
1
|
|
|
|
|
1
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
BEGIN { |
75
|
1
|
|
|
1
|
|
5
|
use Exporter (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
76
|
1
|
|
|
1
|
|
6
|
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
1928
|
|
77
|
1
|
|
|
1
|
|
22
|
@ISA = qw(Exporter); |
78
|
1
|
|
|
|
|
21
|
@EXPORT = (STATGRAB_CONSTANTS, STATGRAB_BASE_FUNCTIONS, STATGRAB_SORT_FUNCTIONS); |
79
|
1
|
|
|
|
|
9
|
@EXPORT_OK = (STATGRAB_CONSTANTS, STATGRAB_BASE_FUNCTIONS, STATGRAB_SORT_FUNCTIONS); |
80
|
1
|
|
|
|
|
11
|
%EXPORT_TAGS = ( 'all' => [ STATGRAB_CONSTANTS, STATGRAB_BASE_FUNCTIONS, STATGRAB_SORT_FUNCTIONS ] ); |
81
|
|
|
|
|
|
|
|
82
|
1
|
50
|
|
|
|
16
|
if ($^O eq 'cygwin') { |
|
|
50
|
|
|
|
|
|
83
|
0
|
|
|
|
|
0
|
require Unix::Statgrab; |
84
|
0
|
|
|
|
|
0
|
import Unix::Statgrab (STATGRAB_CONSTANTS); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# Natively supported by Statgrab (>= 0.8) on cygwin |
87
|
0
|
|
|
|
|
0
|
*drop_privileges = *drop_privileges = \&Unix::Statgrab::drop_privileges; |
88
|
0
|
|
|
|
|
0
|
*get_host_info = *get_host_info = \&Unix::Statgrab::get_host_info; |
89
|
0
|
|
|
|
|
0
|
*get_cpu_stats = *get_cpu_stats = \&Unix::Statgrab::get_cpu_stats; |
90
|
0
|
|
|
|
|
0
|
*get_cpu_stats_diff = *get_cpu_stats_diff = \&Unix::Statgrab::get_cpu_stats_diff; |
91
|
0
|
|
|
|
|
0
|
*get_cpu_percents = *get_cpu_percents = \&Unix::Statgrab::get_cpu_percents; |
92
|
0
|
|
|
|
|
0
|
*get_mem_stats = *get_mem_stats = \&Unix::Statgrab::get_mem_stats; |
93
|
0
|
|
|
|
|
0
|
*get_swap_stats = *get_swap_stats = \&Unix::Statgrab::get_swap_stats; |
94
|
0
|
|
|
|
|
0
|
*get_page_stats = *get_page_stats = \&Unix::Statgrab::get_page_stats; |
95
|
0
|
|
|
|
|
0
|
*get_page_stats_diff = *get_page_stats_diff = \&Unix::Statgrab::get_page_stats_diff; |
96
|
0
|
|
|
|
|
0
|
*get_user_stats = *get_user_stats = \&Unix::Statgrab::get_user_stats; |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Known as not supported by Statgrab (<= 0.13, at least) on cygwin |
99
|
0
|
|
0
|
|
|
0
|
*get_disk_io_stats = *get_disk_io_stats = sub { return Unix::Statgrab::get_disk_io_stats(@_) || Sys::Statgrab::Cygwin::sg_disk_io_stats->new(); }; |
|
0
|
|
|
|
|
0
|
|
100
|
0
|
|
0
|
|
|
0
|
*get_disk_io_stats_diff = *get_disk_io_stats_diff = sub { return Unix::Statgrab::get_disk_io_stats_diff(@_) || Sys::Statgrab::Cygwin::sg_disk_io_stats->new('diff'); }; |
|
0
|
|
|
|
|
0
|
|
101
|
0
|
|
0
|
|
|
0
|
*get_fs_stats = *get_fs_stats = sub { return Unix::Statgrab::get_fs_stats(@_) || Sys::Statgrab::Cygwin::sg_fs_stats->new(); }; |
|
0
|
|
|
|
|
0
|
|
102
|
0
|
|
0
|
|
|
0
|
*get_load_stats = *get_load_stats = sub { return Unix::Statgrab::get_load_stats(@_) || Sys::Statgrab::Cygwin::sg_load_stats->new(); }; |
|
0
|
|
|
|
|
0
|
|
103
|
0
|
|
0
|
|
|
0
|
*get_network_io_stats = *get_network_io_stats = sub { return Unix::Statgrab::get_network_io_stats(@_) || Sys::Statgrab::Cygwin::sg_network_io_stats->new(); }; |
|
0
|
|
|
|
|
0
|
|
104
|
0
|
|
0
|
|
|
0
|
*get_network_io_stats_diff = *get_network_io_stats_diff = sub { return Unix::Statgrab::get_network_io_stats_diff(@_) || Sys::Statgrab::Cygwin::sg_network_io_stats->new('diff'); }; |
|
0
|
|
|
|
|
0
|
|
105
|
0
|
|
0
|
|
|
0
|
*get_network_iface_stats = *get_network_iface_stats = sub { return Unix::Statgrab::get_network_iface_stats(@_) || Sys::Statgrab::Cygwin::sg_network_iface_stats->new(); }; |
|
0
|
|
|
|
|
0
|
|
106
|
0
|
|
0
|
|
|
0
|
*get_process_stats = *get_process_stats = sub { return Unix::Statgrab::get_process_stats(@_) || Sys::Statgrab::Cygwin::sg_process_stats->new(); }; |
|
0
|
|
|
|
|
0
|
|
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
0
|
*sort_procs_by_name = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_name; |
109
|
0
|
|
|
|
|
0
|
*sort_procs_by_pid = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_pid; |
110
|
0
|
|
|
|
|
0
|
*sort_procs_by_uid = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_uid; |
111
|
0
|
|
|
|
|
0
|
*sort_procs_by_gid = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_gid; |
112
|
0
|
|
|
|
|
0
|
*sort_procs_by_size = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_size; |
113
|
0
|
|
|
|
|
0
|
*sort_procs_by_res = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_res; |
114
|
0
|
|
|
|
|
0
|
*sort_procs_by_cpu = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_cpu; |
115
|
0
|
|
|
|
|
0
|
*sort_procs_by_time = \&Sys::Statgrab::Cygwin::sg_process_stats::_sort_procs_by_time; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
elsif ($^O eq 'MSWin32') |
118
|
|
|
|
|
|
|
{ |
119
|
0
|
|
|
|
|
0
|
die "$^O not yet supported by ".__PACKAGE__; |
120
|
0
|
|
|
|
|
0
|
require Unix::Statgrab; |
121
|
0
|
|
|
|
|
0
|
import Unix::Statgrab (STATGRAB_CONSTANTS); |
122
|
0
|
|
|
|
|
0
|
require Win32::Process::Info; |
123
|
0
|
|
|
|
|
0
|
import Unix::Statgrab (STATGRAB_CONSTANTS); |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
else { |
127
|
1
|
|
|
|
|
2761
|
require Unix::Statgrab; |
128
|
0
|
|
|
|
|
|
import Unix::Statgrab (STATGRAB_CONSTANTS, STATGRAB_BASE_FUNCTIONS, STATGRAB_SORT_FUNCTIONS); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_disk_io_stats; |
134
|
|
|
|
|
|
|
use strict; |
135
|
|
|
|
|
|
|
use warnings; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub new { |
138
|
|
|
|
|
|
|
my $type = shift; |
139
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
140
|
|
|
|
|
|
|
my $diff = 1 if shift; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
warn "get_disk_io_stats not yet implemented"; |
143
|
|
|
|
|
|
|
return undef; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_fs_stats; |
147
|
|
|
|
|
|
|
use strict; |
148
|
|
|
|
|
|
|
use warnings; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub new { |
151
|
|
|
|
|
|
|
my $type = shift; |
152
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
warn "get_fs_stats not yet implemented"; |
155
|
|
|
|
|
|
|
return undef; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_load_stats; |
159
|
|
|
|
|
|
|
use strict; |
160
|
|
|
|
|
|
|
use warnings; |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub new { |
163
|
|
|
|
|
|
|
my $type = shift; |
164
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
warn "get_load_stats not yet implemented"; |
167
|
|
|
|
|
|
|
return undef; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_network_io_stats; |
171
|
|
|
|
|
|
|
use strict; |
172
|
|
|
|
|
|
|
use warnings; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub new { |
175
|
|
|
|
|
|
|
my $type = shift; |
176
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
177
|
|
|
|
|
|
|
my $diff = 1 if shift; |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
warn "get_network_io_stats not yet implemented"; |
180
|
|
|
|
|
|
|
return undef; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_network_iface_stats; |
184
|
|
|
|
|
|
|
use strict; |
185
|
|
|
|
|
|
|
use warnings; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub new { |
188
|
|
|
|
|
|
|
my $type = shift; |
189
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
warn "get_network_iface_stats not yet implemented"; |
192
|
|
|
|
|
|
|
return undef; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_process_stats; |
196
|
|
|
|
|
|
|
use strict; |
197
|
|
|
|
|
|
|
use warnings; |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
use constant SORT_METHOD_PREFIX => '_sort_procs_by_'; |
200
|
|
|
|
|
|
|
use constant SORT_METHODS => qw( |
201
|
|
|
|
|
|
|
name |
202
|
|
|
|
|
|
|
pid |
203
|
|
|
|
|
|
|
uid |
204
|
|
|
|
|
|
|
gid |
205
|
|
|
|
|
|
|
size |
206
|
|
|
|
|
|
|
res |
207
|
|
|
|
|
|
|
cpu |
208
|
|
|
|
|
|
|
time |
209
|
|
|
|
|
|
|
); |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub new { |
212
|
|
|
|
|
|
|
my $type = shift; |
213
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
### generate process stat objects ### |
216
|
|
|
|
|
|
|
my @procs; |
217
|
|
|
|
|
|
|
opendir(PROCDIR, '/proc') || die "Can't read dir /proc: $!"; |
218
|
|
|
|
|
|
|
push @procs, Sys::Statgrab::Cygwin::sg_process_stats::all_procs->new($_) foreach grep(/^\d+$/o, (readdir(PROCDIR))); |
219
|
|
|
|
|
|
|
closedir PROCDIR; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
### optimization for pcpu stat ### |
222
|
|
|
|
|
|
|
my %cpu_map; |
223
|
|
|
|
|
|
|
my @line; |
224
|
|
|
|
|
|
|
if (open(IPCCMD, "procps -e -opid -opcpu |")) { |
225
|
|
|
|
|
|
|
foreach my $l () { |
226
|
|
|
|
|
|
|
$l =~ s/^\s+//o; |
227
|
|
|
|
|
|
|
@line = split(/\s+/o, $l); |
228
|
|
|
|
|
|
|
chomp @line; |
229
|
|
|
|
|
|
|
$cpu_map{$line[0]} = $line[1]; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
close IPCCMD; |
232
|
|
|
|
|
|
|
foreach my $proc (@procs) { |
233
|
|
|
|
|
|
|
$proc->{cpu_percent} = $cpu_map{$proc->{pid}}; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
else { |
237
|
|
|
|
|
|
|
warn "Can't obtain cpu_percent stats: Can't execute procps: $!"; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
return bless(\@procs, $class); |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub all_procs { |
244
|
|
|
|
|
|
|
my $self = shift; |
245
|
|
|
|
|
|
|
return @{$self}; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub sort_by { |
249
|
|
|
|
|
|
|
my $self = shift; |
250
|
|
|
|
|
|
|
my $meth = shift; |
251
|
|
|
|
|
|
|
die "Usage: ".__PACKAGE__."::sort_by(obj, meth)" unless defined $meth; |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
my $regex = quotemeta $meth; |
254
|
|
|
|
|
|
|
my $sort_method = SORT_METHOD_PREFIX.$meth; |
255
|
|
|
|
|
|
|
@{$self} = sort $sort_method @{$self} if grep(/^$regex$/, SORT_METHODS); |
256
|
|
|
|
|
|
|
return $self; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub _sort_procs_by_name ($$) { shift->proc_name cmp shift->proc_name } |
260
|
|
|
|
|
|
|
sub _sort_procs_by_pid ($$) { shift->pid <=> shift->pid } |
261
|
|
|
|
|
|
|
sub _sort_procs_by_uid ($$) { shift->uid <=> shift->uid } |
262
|
|
|
|
|
|
|
sub _sort_procs_by_gid ($$) { shift->gid <=> shift->gid } |
263
|
|
|
|
|
|
|
sub _sort_procs_by_size ($$) { shift->proc_size <=> shift->proc_size } |
264
|
|
|
|
|
|
|
sub _sort_procs_by_res ($$) { shift->proc_resident <=> shift->proc_resident } |
265
|
|
|
|
|
|
|
sub _sort_procs_by_cpu ($$) { shift->cpu_percent <=> shift->cpu_percent } |
266
|
|
|
|
|
|
|
sub _sort_procs_by_time ($$) { shift->time_spent <=> shift->time_spent } |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
package Sys::Statgrab::Cygwin::sg_process_stats::all_procs; |
269
|
|
|
|
|
|
|
use strict; |
270
|
|
|
|
|
|
|
use warnings; |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
our $AUTOLOAD; |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
sub new { |
275
|
|
|
|
|
|
|
my $type = shift; |
276
|
|
|
|
|
|
|
my $class = ref($type) || $type; |
277
|
|
|
|
|
|
|
my $pid = shift; |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
my $o = bless(\$pid, $class); |
280
|
|
|
|
|
|
|
my $self = { |
281
|
|
|
|
|
|
|
proc_name => $o->_proc_name, |
282
|
|
|
|
|
|
|
proc_title => $o->_proc_title, |
283
|
|
|
|
|
|
|
pid => $o->_pid, |
284
|
|
|
|
|
|
|
parent_pid => $o->_parent_pid, |
285
|
|
|
|
|
|
|
pgid => $o->_pgid, |
286
|
|
|
|
|
|
|
uid => $o->_uid, |
287
|
|
|
|
|
|
|
euid => $o->_euid, |
288
|
|
|
|
|
|
|
gid => $o->_gid, |
289
|
|
|
|
|
|
|
egid => $o->_egid, |
290
|
|
|
|
|
|
|
proc_size => $o->_proc_size, |
291
|
|
|
|
|
|
|
proc_resident => $o->_proc_resident, |
292
|
|
|
|
|
|
|
time_spent => $o->_time_spent, |
293
|
|
|
|
|
|
|
cpu_percent => undef, #efficiently calculated later by caller class |
294
|
|
|
|
|
|
|
nice => $o->_nice, |
295
|
|
|
|
|
|
|
state => $o->_state, |
296
|
|
|
|
|
|
|
}; |
297
|
|
|
|
|
|
|
return bless($self, $class); |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
sub AUTOLOAD { #read-only |
301
|
|
|
|
|
|
|
my $self = shift; |
302
|
|
|
|
|
|
|
my $class = ref($self) || $self; |
303
|
|
|
|
|
|
|
my $name = $AUTOLOAD; |
304
|
|
|
|
|
|
|
$name =~ s/.*://o; # strip fully-qualified portion |
305
|
|
|
|
|
|
|
no strict 'refs'; |
306
|
|
|
|
|
|
|
Carp::confess "Can't access '$name' field in class $class" unless (exists $self->{$name}); |
307
|
|
|
|
|
|
|
return $self->{$name}; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
sub DESTROY {} |
310
|
|
|
|
|
|
|
sub CLONE {} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub _proc_name { |
313
|
|
|
|
|
|
|
my $self = shift; |
314
|
|
|
|
|
|
|
return Sys::Statgrab::Util::get_hash_value("/proc/${$self}/status", ':', 'Name', 1); |
315
|
|
|
|
|
|
|
} |
316
|
|
|
|
|
|
|
sub _proc_title { |
317
|
|
|
|
|
|
|
my $self = shift; |
318
|
|
|
|
|
|
|
my $cmdline = Sys::Statgrab::Util::get_value("/proc/${$self}/cmdline"); |
319
|
|
|
|
|
|
|
$cmdline =~ s/\x0/ /go; |
320
|
|
|
|
|
|
|
return $cmdline; |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
sub _pid { |
323
|
|
|
|
|
|
|
my $self = shift; |
324
|
|
|
|
|
|
|
return ${$self}; |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
sub _parent_pid { |
327
|
|
|
|
|
|
|
my $self = shift; |
328
|
|
|
|
|
|
|
return Sys::Statgrab::Util::get_value("/proc/${$self}/ppid"); |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
sub _pgid { |
331
|
|
|
|
|
|
|
my $self = shift; |
332
|
|
|
|
|
|
|
return Sys::Statgrab::Util::get_value("/proc/${$self}/pgid"); |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
sub _uid { |
335
|
|
|
|
|
|
|
my $self = shift; |
336
|
|
|
|
|
|
|
return Sys::Statgrab::Util::get_value("/proc/${$self}/uid"); |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
sub _euid { return _uid(@_); } #bug: is euid accessable on cygwin? |
339
|
|
|
|
|
|
|
sub _gid { |
340
|
|
|
|
|
|
|
my $self = shift; |
341
|
|
|
|
|
|
|
return Sys::Statgrab::Util::get_value("/proc/${$self}/gid"); |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
sub _egid { return _gid(@_); } #bug: is egid accessable on cygwin? |
344
|
|
|
|
|
|
|
sub _proc_size { #note: approximated to nearest unit (default is kB) |
345
|
|
|
|
|
|
|
my $self = shift; |
346
|
|
|
|
|
|
|
my @size = split(/ /, Sys::Statgrab::Util::get_hash_value("/proc/${$self}/status", ':', 'VmSize', 1)); |
347
|
|
|
|
|
|
|
return $size[0] * (lc $size[1] eq 'kb' ? 1000 : lc $size[1] eq 'mb' ? 1000000 : lc $size[1] eq 'gb' ? 1000000000 : 1); |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
sub _proc_resident { #note: approximated to nearest unit (default is kB) |
350
|
|
|
|
|
|
|
my $self = shift; |
351
|
|
|
|
|
|
|
my @rss = split(/ /, Sys::Statgrab::Util::get_hash_value("/proc/${$self}/status", ':', 'VmRSS', 1)); |
352
|
|
|
|
|
|
|
return $rss[0] * (lc $rss[1] eq 'kb' ? 1000 : lc $rss[1] eq 'mb' ? 1000000 : lc $rss[1] eq 'gb' ? 1000000000 : 1); |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
sub _time_spent { |
355
|
|
|
|
|
|
|
my $self = shift; |
356
|
|
|
|
|
|
|
my ($utime, $stime) = (split(/ /, Sys::Statgrab::Util::get_value("/proc/${$self}/stat")))[13..14]; |
357
|
|
|
|
|
|
|
return $utime + $stime; |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
sub _cpu_percent { #note: using more efficient method |
360
|
|
|
|
|
|
|
my $self = shift; |
361
|
|
|
|
|
|
|
return Sys::Statgrab::Util::get_procps_value(${$self}, 'pcpu'); |
362
|
|
|
|
|
|
|
return undef; |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
sub _nice { |
365
|
|
|
|
|
|
|
my $self = shift; |
366
|
|
|
|
|
|
|
# return Sys::Statgrab::Util::get_procps_value(${$self}, 'ni'); |
367
|
|
|
|
|
|
|
return (split(/ /, Sys::Statgrab::Util::get_value("/proc/${$self}/stat")))[18]; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
sub _state { |
370
|
|
|
|
|
|
|
my $self = shift; |
371
|
|
|
|
|
|
|
my $state = (split(/ /, Sys::Statgrab::Util::get_value("/proc/${$self}/stat")))[2]; |
372
|
|
|
|
|
|
|
# return $state eq 'R' ? Sys::Statgrab::SG_PROCESS_STATE_RUNNING |
373
|
|
|
|
|
|
|
# : $state eq 'S' ? Sys::Statgrab::SG_PROCESS_STATE_SLEEPING |
374
|
|
|
|
|
|
|
# : $state eq 'T' ? Sys::Statgrab::SG_PROCESS_STATE_STOPPED |
375
|
|
|
|
|
|
|
# : $state eq 'Z' ? Sys::Statgrab::SG_PROCESS_STATE_ZOMBIE #kludge: not sure if this is the correct letter |
376
|
|
|
|
|
|
|
# : Sys::Statgrab::SG_PROCESS_STATE_UNKNOWN |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
package Sys::Statgrab::Util; |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
use strict; |
382
|
|
|
|
|
|
|
use warnings; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
sub get_value ($) { |
385
|
|
|
|
|
|
|
my $file = shift; |
386
|
|
|
|
|
|
|
open(PROCFILE, "<$file") || die "Can't open file $file"; |
387
|
|
|
|
|
|
|
my @line = ; |
388
|
|
|
|
|
|
|
close PROCFILE; |
389
|
|
|
|
|
|
|
chomp @line; |
390
|
|
|
|
|
|
|
return $line[0]; |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
sub get_array_index ($$$) { |
394
|
|
|
|
|
|
|
my $file = shift; |
395
|
|
|
|
|
|
|
my $delimiter = shift; |
396
|
|
|
|
|
|
|
my $idx = shift; |
397
|
|
|
|
|
|
|
open(PROCFILE, "<$file") || die "Can't open file $file"; |
398
|
|
|
|
|
|
|
my @line = split(/\s*$delimiter\s*/, ); |
399
|
|
|
|
|
|
|
close PROCFILE; |
400
|
|
|
|
|
|
|
chomp @line; |
401
|
|
|
|
|
|
|
return $line[$idx]; |
402
|
|
|
|
|
|
|
} |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
sub get_hash_value ($$$;$) { |
405
|
|
|
|
|
|
|
my $file = shift; |
406
|
|
|
|
|
|
|
my $delimiter = shift; |
407
|
|
|
|
|
|
|
my $key = shift; |
408
|
|
|
|
|
|
|
my $idx = shift; |
409
|
|
|
|
|
|
|
open(PROCFILE, "<$file") || die "Can't open file $file"; |
410
|
|
|
|
|
|
|
my @line; |
411
|
|
|
|
|
|
|
while (@line = split(/\s*$delimiter\s*/, )) { |
412
|
|
|
|
|
|
|
last if $line[0] eq $key; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
chomp @line; |
415
|
|
|
|
|
|
|
close PROCFILE; |
416
|
|
|
|
|
|
|
return defined $idx ? $line[$idx] : wantarray ? @line : $line[1]; |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
sub get_procps_value ($$) { |
420
|
|
|
|
|
|
|
my $pid = shift; |
421
|
|
|
|
|
|
|
my $format = shift; |
422
|
|
|
|
|
|
|
if (open(IPCCMD, "procps -e -opid -o$format |")) { |
423
|
|
|
|
|
|
|
my @line; |
424
|
|
|
|
|
|
|
foreach my $l () { |
425
|
|
|
|
|
|
|
$l =~ s/^\s+//o; |
426
|
|
|
|
|
|
|
@line = split(/\s+/o, $l); |
427
|
|
|
|
|
|
|
last if $line[0] eq $pid; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
close IPCCMD; |
430
|
|
|
|
|
|
|
chomp @line; |
431
|
|
|
|
|
|
|
return $line[1]; |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
else { |
434
|
|
|
|
|
|
|
warn "Can't obtain cpu_percent stats: Can't execute procps: $!"; |
435
|
|
|
|
|
|
|
return undef; |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
1; |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
__END__ |