File Coverage

blib/lib/OSLV/Monitor.pm
Criterion Covered Total %
statement 14 103 13.5
branch 0 64 0.0
condition n/a
subroutine 5 9 55.5
pod 2 4 50.0
total 21 180 11.6


line stmt bran cond sub pod time code
1             package OSLV::Monitor;
2              
3 1     1   107149 use 5.006;
  1         3  
4 1     1   7 use strict;
  1         1  
  1         26  
5 1     1   4 use warnings;
  1         2  
  1         40  
6 1     1   4 use Scalar::Util qw(looks_like_number);
  1         2  
  1         46  
7 1     1   4 use Time::HiRes qw(gettimeofday);
  1         1  
  1         6  
8              
9             =head1 NAME
10              
11             OSLV::Monitor - OS level virtualization monitoring extend for LibreNMS.
12              
13             =head1 VERSION
14              
15             Version 1.0.4
16              
17             =cut
18              
19             our $VERSION = '1.0.4';
20              
21             =head1 SYNOPSIS
22              
23             Quick summary of what the module does.
24              
25             Perhaps a little code snippet.
26              
27             use OSLV::Monitor;
28              
29             my $monitor = OSLV::Monitor->new();
30              
31             eval { $monitor->load; };
32             if ($@) {
33             print encode_json( { version => 1, data => {}, error => 1, errorString => 'load failed... ' . $@ } ) . "\n";
34             exit 1;
35             }
36              
37             my $data = encode_json( $monitor->run );
38              
39             print $data."\n";
40              
41              
42             =head2 METHODS
43              
44             Inits the object.
45              
46             One option is taken and that is a hash ref.
47              
48             # init with the cbsd backend
49             my $monitor->new(backend=>'FreeBSD');
50              
51             The keys are list as below.
52              
53             - backend :: The name of the backend to use. If undef, it is choosen based on $^O
54             freebsd :: FreeBSD
55             linux :: cgroups
56              
57             - base_dir :: The dir to use for any caches as well as output.
58             Default :: /var/cache/oslv_monitor
59              
60             - include :: An array of regexps to match names against for seeing if they should
61             be included or not. By default everything is return.
62             - Default :: ['^.*$']
63              
64             - exclude :: An array of regexps to exclude. By default this array is empty. It is
65             processed after the include array.
66             - Default :: []
67              
68             - time_divider :: What to pass to the backend for the time_divider for that if needed.
69             Default :: 1000000
70              
71             =cut
72              
73             sub new {
74 0     0 0   my ( $blank, %opts ) = @_;
75              
76 0 0         if ( !defined( $opts{time_divider} ) ) {
77 0           $opts{time_divider} = 1000000;
78             } else {
79 0 0         if ( !looks_like_number( $opts{time_divider} ) ) {
80 0           die('time_divider is not a number');
81             }
82             }
83              
84 0 0         if ( !defined( $opts{backend} ) ) {
85 0           $opts{backend} = 'FreeBSD';
86 0 0         if ( $^O eq 'freebsd' ) {
    0          
87 0           $opts{backend} = 'FreeBSD';
88             } elsif ( $^O eq 'linux' ) {
89 0           $opts{backend} = 'cgroups';
90             }
91             }
92              
93 0 0         if ( !defined( $opts{include} ) ) {
94 0           my @include = ('^.+$');
95 0           $opts{include} = \@include;
96             } else {
97 0 0         if ( !defined( $opts{include}[0] ) ) {
98 0           $opts{include}[0] = '^.+$';
99             }
100              
101 0           my $int = 0;
102 0           while ( defined( $opts{include}[$int] ) ) {
103 0 0         if ( ref( $opts{include}[$int] ) ne '' ) {
104 0           die( 'ref for $opts{include}[' . $int . '] is ' . ref( $opts{include}[$int] ) . ' and not ""' );
105             }
106 0           $int++;
107             }
108             } ## end else [ if ( !defined( $opts{include} ) ) ]
109              
110 0 0         if ( !defined( $opts{exclude} ) ) {
111 0           my @exclude;
112 0           $opts{exclude} = \@exclude;
113             } else {
114 0           my $int = 0;
115 0           while ( defined( $opts{exclude}[$int] ) ) {
116 0 0         if ( ref( $opts{exclude}[$int] ) ne '' ) {
117 0           die( 'ref for $opts{exclude}[' . $int . '] is ' . ref( $opts{exclude}[$int] ) . ' and not ""' );
118             }
119 0           $int++;
120             }
121             }
122              
123 0 0         if ( !defined( $opts{base_dir} ) ) {
124 0           $opts{base_dir} = '/var/cache/oslv_monitor';
125             }
126              
127 0 0         if ( !-d $opts{base_dir} ) {
128 0 0         mkdir( $opts{base_dir} ) || die( $opts{base_dir} . ' was not a directory and could not be created' );
129             }
130              
131             my $self = {
132             time_divider => $opts{time_divider},
133             version => 1,
134             backend => $opts{backend},
135             base_dir => $opts{base_dir},
136             include => $opts{include},
137             exclude => $opts{exclude},
138 0           };
139 0           bless $self;
140              
141 0           return $self;
142             } ## end sub new
143              
144             =head2 load
145              
146             This loads the specified backend.
147              
148             eval{ $monitor->load; };
149             if ( $@ ){
150             print "Failed to load the backend... ".$@;
151             }
152              
153             =cut
154              
155             sub load {
156 0     0 1   my $self = $_[0];
157              
158 0           my $loaded = 0;
159              
160 0           my $backend_test;
161             my $usable;
162             my $test_string = '
163             use OSLV::Monitor::Backends::' . $self->{backend} . ';
164             $backend_test=OSLV::Monitor::Backends::'
165 0           . $self->{backend} . '->new(base_dir=>$self->{base_dir}, obj=>$self, time_divider=>$self->{time_divider});
166             $usable=$backend_test->usable;
167             ';
168 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
169 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': test string "' . $test_string . '"' );
170             }
171 0           eval($test_string);
172              
173 0 0         if ($usable) {
174 0           $self->{backend_mod} = $backend_test;
175 0           $loaded = 1;
176             } else {
177 0           die( 'Failed to load backend... ' . $@ );
178             }
179              
180 0           return $loaded;
181             } ## end sub load
182              
183             =head2 run
184              
185             Runs the poller backend and report the results.
186              
187             If nothing is nothing is loaded, load will be called.
188              
189             my $status=$monitor->run;
190              
191             =cut
192              
193             sub run {
194 0     0 1   my $self = $_[0];
195              
196 0 0         if ( !defined( $self->{backend_mod} ) ) {
197             return {
198             version => $self->{version},
199 0           data => {},
200             error => 1,
201             errorString => 'No module loaded',
202             };
203             }
204              
205 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
206 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': calling backend run' );
207             }
208              
209 0           my $to_return_data;
210             # eval { $to_return_data = $self->{backend_mod}->run };
211 0           $to_return_data = $self->{backend_mod}->run;
212 0 0         if ($@) {
213             return {
214             version => $self->{version},
215 0           data => {},
216             error => 1,
217             errorString => 'Failed to run backend... ' . $@,
218             };
219             }
220              
221 0           $to_return_data->{backend} = $self->{backend};
222              
223             return {
224             version => $self->{version},
225 0           data => $to_return_data,
226             error => 0,
227             errorString => ''
228             };
229             } ## end sub run
230              
231             sub include {
232 0     0 0   my $self = $_[0];
233 0           my $name = $_[1];
234              
235             # any of these means it is not meaningfully usable or an error
236 0 0         if ( !defined($name) ) {
    0          
    0          
237 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
238 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': include name is undef returning 0' );
239             }
240 0           return 0;
241             } elsif ( ref($name) ne '' ) {
242 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
243 0           warn( 'DEBUG, '
244             . join( '.', gettimeofday )
245             . ': include name ref is not "" but "'
246             . ref($name)
247             . '" returning 0' );
248             }
249 0           return 0;
250             } elsif ( $name eq '' ) {
251 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
252 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': include name is "" returning 0' );
253             }
254 0           return 0;
255             }
256              
257 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
258 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': include name being tested is "' . $name . '"' );
259             }
260              
261             # look for mathcing includes
262 0           foreach my $item ( @{ $self->{include} } ) {
  0            
263             # check if it matches
264 0 0         if ( $name =~ /$item/ ) {
    0          
265 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
266 0           warn( 'DEBUG, '
267             . join( '.', gettimeofday )
268             . ': include name matched include /'
269             . $item
270             . '/ testing for exlcudes now' );
271             }
272             # if we got a match check for excludes
273 0           foreach my $item ( @{ $self->{exclude} } ) {
  0            
274 0 0         if ( $name =~ /$item/ ) {
    0          
275 0           return 0;
276             } elsif ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
277 0           warn( 'DEBUG, '
278             . join( '.', gettimeofday )
279             . ': include name did not match exclude /'
280             . $item
281             . '/' );
282             }
283             } ## end foreach my $item ( @{ $self->{exclude} } )
284             # if we get here it should means a include matched and no excludes matched
285 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
286 0           warn( 'DEBUG, '
287             . join( '.', gettimeofday )
288             . ': include name matched a include and no exlcudes returning 1' );
289             }
290 0           return 1;
291             } elsif ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
292 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': include name did not match include /' . $item . '/' );
293             }
294              
295             } ## end foreach my $item ( @{ $self->{include} } )
296              
297 0 0         if ( $ENV{'OSLV_MONITOR_DEBUG'} ) {
298 0           warn( 'DEBUG, ' . join( '.', gettimeofday ) . ': include name did not match any includes' );
299             }
300              
301             # if we get here it should mean no includes matched
302 0           return 0;
303             } ## end sub include
304              
305             =head1 AUTHOR
306              
307             Zane C. Bowers-Hadley, C<< >>
308              
309             =head1 BUGS
310              
311             Please report any bugs or feature requests to C, or through
312             the web interface at L. I will be notified, and then you'll
313             automatically be notified of progress on your bug as I make changes.
314              
315              
316              
317              
318             =head1 SUPPORT
319              
320             You can find documentation for this module with the perldoc command.
321              
322             perldoc OSLV::Monitor
323              
324              
325             You can also look for information at:
326              
327             =over 4
328              
329             =item * RT: CPAN's request tracker (report bugs here)
330              
331             L
332              
333             =item * CPAN Ratings
334              
335             L
336              
337             =item * Search CPAN
338              
339             L
340              
341             =back
342              
343              
344             =head1 ACKNOWLEDGEMENTS
345              
346              
347             =head1 LICENSE AND COPYRIGHT
348              
349             This software is Copyright (c) 2024 by Zane C. Bowers-Hadley.
350              
351             This is free software, licensed under:
352              
353             The Artistic License 2.0 (GPL Compatible)
354              
355              
356             =cut
357              
358             1; # End of OSLV::Monitor