File Coverage

blib/lib/Linux/Info/MemStats.pm
Criterion Covered Total %
statement 58 63 92.0
branch 12 22 54.5
condition n/a
subroutine 6 6 100.0
pod 3 3 100.0
total 79 94 84.0


line stmt bran cond sub pod time code
1             package Linux::Info::MemStats;
2 3     3   131872 use strict;
  3         23  
  3         91  
3 3     3   16 use warnings;
  3         5  
  3         103  
4 3     3   17 use Carp qw(croak);
  3         6  
  3         3170  
5              
6             our $VERSION = '1.5'; # VERSION
7              
8             =head1 NAME
9              
10             Linux::Info::MemStats - Collect linux memory information.
11              
12             =head1 SYNOPSIS
13              
14             use Linux::Info::MemStats;
15              
16             my $lxs = Linux::Info::MemStats->new;
17             my $stat = $lxs->get;
18              
19             =head1 DESCRIPTION
20              
21             Linux::Info::MemStats gathers memory statistics from the virtual F
22             filesystem (procfs).
23              
24             For more information read the documentation of the front-end module
25             L.
26              
27             =head1 MEMORY INFORMATIONS
28              
29             Generated by F.
30              
31             Check out the SEE ALSO section for details on what is extracted and what it
32             means. The list is extensive and Linux kernel is always being updated to keep
33             track of it here.
34              
35             =head1 METHODS
36              
37             =head2 new()
38              
39             Call C to create a new object.
40              
41             my $lxs = Linux::Info::MemStats->new;
42              
43             It's possible to set the path to the proc filesystem.
44              
45             Linux::Info::MemStats->new(
46             files => {
47             # This is the default
48             path => '/proc',
49             meminfo => 'meminfo',
50             }
51             );
52              
53             =cut
54              
55             sub new {
56 3     3 1 860 my $class = shift;
57 3 50       15 my $opts = ref( $_[0] ) ? shift : {@_};
58              
59 3         18 my %self = (
60             files => {
61             path => '/proc',
62             meminfo => 'meminfo',
63             }
64             );
65              
66 3         7 foreach my $file ( keys %{ $opts->{files} } ) {
  3         14  
67 0         0 $self{files}{$file} = $opts->{files}->{$file};
68             }
69              
70 3         19 $self{regex} = qr/([\w\(\)]+):\s+(\d+)/;
71 3         10 $self{inactive_regex} = qr/^inact_/;
72              
73 3         15 return bless \%self, $class;
74             }
75              
76             =head2 get()
77              
78             C returns the statistics as a hash reference.
79              
80             my $stats_ref = $lxs->get;
81              
82             This is the original method as defined in L
83             distribution and was kept here for backward compatibility since the amount of
84             information returned is somehow limited, for example, there is no Hugepages
85             information included. Of course, you might not need it anyway, but as time goes
86             by the Linux kernel might include more information (and remove some) and it's
87             hard to keep track of it.
88              
89             Short long story: if this method returns the information you need it, use it,
90             since the other method C will be slower.
91              
92             Here is the list of information returned explained:
93              
94             memused - Total size of used memory in kilobytes.
95             memfree - Total size of free memory in kilobytes.
96             memusedper - Total size of used memory in percent.
97             memtotal - Total size of memory in kilobytes.
98             buffers - Total size of buffers used from memory in kilobytes.
99             cached - Total size of cached memory in kilobytes.
100             realfree - Total size of memory is real free (memfree + buffers + cached).
101             realfreeper - Total size of memory is real free in percent of total memory.
102             swapused - Total size of swap space is used is kilobytes.
103             swapfree - Total size of swap space is free in kilobytes.
104             swapusedper - Total size of swap space is used in percent.
105             swaptotal - Total size of swap space in kilobytes.
106             swapcached - Memory that once was swapped out, is swapped back in but still also is in the swapfile.
107             active - Memory that has been used more recently and usually not reclaimed unless absolutely necessary.
108             inactive - Memory which has been less recently used and is more eligible to be reclaimed for other purposes.
109             On earlier kernels (2.4) Inact_dirty + Inact_laundry + Inact_clean.
110              
111             The following statistics are only available by kernels from 2.6.
112              
113             slab - Total size of memory in kilobytes that used by kernel for data structure allocations.
114             dirty - Total size of memory pages in kilobytes that waits to be written back to disk.
115             mapped - Total size of memory in kilbytes that is mapped by devices or libraries with mmap.
116             writeback - Total size of memory that was written back to disk.
117             committed_as - The amount of memory presently allocated on the system.
118              
119             The following statistic is only available by kernels from 2.6.9.
120              
121             commitlimit - Total amount of memory currently available to be allocated on the system.
122              
123             =cut
124              
125             sub get {
126 2     2 1 1503 my $self = shift;
127 2         8 my $class = ref($self);
128 2         11 my $file = $self->{files};
129 2         6 my %meminfo = ();
130              
131             my $filename =
132 2 50       13 $file->{path} ? "$file->{path}/$file->{meminfo}" : $file->{meminfo};
133 2 50       87 open my $fh, '<', $filename
134             or croak "$class: unable to open $filename ($!)";
135              
136 2         90 while ( my $line = <$fh> ) {
137 90 100       336 if (
    50          
138             $line =~
139             /^((?:Mem|Swap)(?:Total|Free)|Buffers|Cached|SwapCached|Active|Inactive|
140             Dirty|Writeback|Mapped|Slab|Commit(?:Limit|ted_AS)):\s*(\d+)/x
141             )
142             {
143 30         87 my ( $n, $v ) = ( $1, $2 );
144 30         49 $n =~ tr/A-Z/a-z/;
145 30         102 $meminfo{$n} = $v;
146             }
147             elsif ( $line =~ /^Inact_(?:dirty|laundry|clean):\s*(\d+)/ ) {
148 0         0 $meminfo{inactive} += $1;
149             }
150             }
151              
152 2         28 close($fh);
153              
154 2         22 $meminfo{memused} = sprintf( '%u', $meminfo{memtotal} - $meminfo{memfree} );
155             $meminfo{memusedper} =
156 2         27 sprintf( '%.2f', 100 * $meminfo{memused} / $meminfo{memtotal} );
157             $meminfo{swapused} =
158 2         10 sprintf( '%u', $meminfo{swaptotal} - $meminfo{swapfree} );
159             $meminfo{realfree} =
160 2         10 sprintf( '%u', $meminfo{memfree} + $meminfo{buffers} + $meminfo{cached} );
161             $meminfo{realfreeper} =
162 2         14 sprintf( '%.2f', 100 * $meminfo{realfree} / $meminfo{memtotal} );
163              
164             # maybe there is no swap space on the machine
165 2 50       8 if ( !$meminfo{swaptotal} ) {
166 0         0 $meminfo{swapusedper} = '0.00';
167             }
168             else {
169             $meminfo{swapusedper} =
170 2         26 sprintf( '%.2f', 100 * $meminfo{swapused} / $meminfo{swaptotal} );
171             }
172              
173 2         15 return \%meminfo;
174             }
175              
176             =head2 get_more
177              
178             It does the same thing as C, but returns all data read from
179             F.
180              
181             It also includes C for the same purposes, but due the amount of data
182             read, is a bit slower than C.
183              
184             =cut
185              
186             sub get_more {
187 1     1 1 4 my $self = shift;
188 1         3 my $class = ref($self);
189 1         4 my $file = $self->{files};
190 1         2 my %meminfo = ();
191              
192             my $filename =
193 1 50       5 $file->{path} ? "$file->{path}/$file->{meminfo}" : $file->{meminfo};
194 1 50       43 open my $fh, '<', $filename
195             or croak "$class: unable to open $filename ($!)";
196              
197 1         46 while ( my $line = <$fh> ) {
198 45 50       215 if ( $line =~ $self->{regex} ) {
199 45         112 my ( $n, $v ) = ( $1, $2 );
200 45         63 $n =~ tr/A-Z/a-z/;
201 45         113 $meminfo{$n} = $v;
202             }
203              
204 45 50       202 if ( $line =~ $self->{inactive_regex} ) {
205 0         0 $meminfo{inactive} += $1;
206             }
207             }
208              
209 1         14 close($fh);
210              
211 1         8 $meminfo{memused} = sprintf( '%u', $meminfo{memtotal} - $meminfo{memfree} );
212             $meminfo{memusedper} =
213 1         11 sprintf( '%.2f', 100 * $meminfo{memused} / $meminfo{memtotal} );
214             $meminfo{swapused} =
215 1         5 sprintf( '%u', $meminfo{swaptotal} - $meminfo{swapfree} );
216             $meminfo{realfree} =
217 1         5 sprintf( '%u', $meminfo{memfree} + $meminfo{buffers} + $meminfo{cached} );
218             $meminfo{realfreeper} =
219 1         6 sprintf( '%.2f', 100 * $meminfo{realfree} / $meminfo{memtotal} );
220              
221             # maybe there is no swap space on the machine
222 1 50       16 if ( !$meminfo{swaptotal} ) {
223 0         0 $meminfo{swapusedper} = '0.00';
224             }
225             else {
226             $meminfo{swapusedper} =
227 1         8 sprintf( '%.2f', 100 * $meminfo{swapused} / $meminfo{swaptotal} );
228             }
229              
230 1         6 return \%meminfo;
231             }
232              
233             =head1 EXPORTS
234              
235             Nothing.
236              
237             =head1 SEE ALSO
238              
239             =over
240              
241             =item *
242              
243             B
244              
245             =item *
246              
247             L, C
248             section.
249              
250             =item *
251              
252             L.
253              
254             =item *
255              
256             L
257              
258             =back
259              
260             =head1 AUTHOR
261              
262             Alceu Rodrigues de Freitas Junior, Earfreitas@cpan.orgE
263              
264             =head1 COPYRIGHT AND LICENSE
265              
266             This software is copyright (c) 2015 of Alceu Rodrigues de Freitas Junior,
267             Earfreitas@cpan.orgE.
268              
269             This file is part of Linux Info project.
270              
271             Linux-Info is free software: you can redistribute it and/or modify
272             it under the terms of the GNU General Public License as published by
273             the Free Software Foundation, either version 3 of the License, or
274             (at your option) any later version.
275              
276             Linux-Info is distributed in the hope that it will be useful,
277             but WITHOUT ANY WARRANTY; without even the implied warranty of
278             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
279             GNU General Public License for more details.
280              
281             You should have received a copy of the GNU General Public License
282             along with Linux Info. If not, see .
283              
284             =cut
285              
286             1;