File Coverage

blib/lib/Mojo/Netdata.pm
Criterion Covered Total %
statement 79 93 84.9
branch 12 20 60.0
condition 3 7 42.8
subroutine 14 15 93.3
pod 1 1 100.0
total 109 136 80.1


line stmt bran cond sub pod time code
1             package Mojo::Netdata;
2 2     2   387425 use Mojo::Base -base, -signatures;
  2         282300  
  2         15  
3              
4 2     2   7243 use IO::Handle;
  2         3  
  2         79  
5 2     2   896 use Mojo::File qw(path);
  2         55551  
  2         107  
6 2     2   837 use Mojo::Netdata::Util qw(logf);
  2         5  
  2         2645  
7              
8             our $VERSION = '0.02';
9              
10             has collectors => sub ($self) { $self->_build_collectors };
11             has config => sub ($self) { $self->_build_config };
12             has user_config_dir => sub ($self) { $ENV{NETDATA_USER_CONFIG_DIR} || '/etc/netdata' };
13             has stock_config_dir => sub ($self) { $ENV{NETDATA_STOCK_CONFIG_DIR} || '/usr/lib/netdata/conf.d' };
14             has plugins_dir => sub ($self) { $ENV{NETDATA_PLUGINS_DIR} || '' };
15             has web_dir => sub ($self) { $ENV{NETDATA_WEB_DIR} || '' };
16             has cache_dir => sub ($self) { $ENV{NETDATA_CACHE_DIR} || '' };
17             has log_dir => sub ($self) { $ENV{NETDATA_LOG_DIR} || '' };
18             has host_prefix => sub ($self) { $ENV{NETDATA_HOST_PREFIX} || '' };
19             has debug_flags => sub ($self) { $ENV{NETDATA_DEBUG_FLAGS} || '' };
20             has update_every => sub ($self) { $ENV{NETDATA_UPDATE_EVERY} || 1 };
21              
22 0     0 1 0 sub start ($self) {
  0         0  
  0         0  
23 0         0 logf(info => 'Starting %s', __PACKAGE__);
24 0 0       0 return 0 unless @{$self->collectors};
  0         0  
25 0         0 $_->emit_charts->recurring_update_p for @{$self->collectors};
  0         0  
26 0         0 return int @{$self->collectors};
  0         0  
27             }
28              
29 2     2   3 sub _build_config ($self) {
  2         2  
  2         3  
30 2         4 my $config = {};
31              
32 2         4 my $file = path($self->user_config_dir, 'mojo.conf.pl')->to_abs;
33 2 100       75 if (-r $file) {
34 1         29 logf(debug => 'Loading config file %s into config().', $file);
35 1         3 $config = _eval_file($file);
36             }
37              
38 2         38 my $conf_d = path($self->user_config_dir, 'mojo.conf.d')->to_abs->list->sort;
39 2         357 for my $file ($conf_d->each) {
40 3 100       47 next unless $file->basename =~ m!\.conf\.pl$!;
41 2 50       68 next unless my $d = _eval_file($file);
42              
43 2 100       6 if ($d->{collector}) {
44 1         4 logf(debug => 'Adding config file %s to "collectors".', $file);
45 1         2 push @{$config->{collectors}}, $d;
  1         3  
46             }
47             else {
48 1         4 logf(debug => 'Merging config file %s into config().', $file);
49 1         5 @$config{keys(%$d)} = values %$d;
50             }
51             }
52              
53 2         21 return $config;
54             }
55              
56 2     2   6 sub _build_collectors ($self) {
  2         4  
  2         4  
57 2   100     27 my $fh = $self->{stdout} // \*STDOUT; # for testing
58 2         28 $fh->autoflush;
59              
60 2         115 local $@;
61 2         4 my @collectors;
62 2 50       4 for my $collector_config (@{$self->config->{collectors} || []}) {
  2         7  
63 3         20 my $collector_class = $collector_config->{collector};
64              
65 3 50 33     31 unless ($collector_class and $collector_class =~ m!^[\w:]+$!) {
66 0   0     0 logf(error => 'Invalid collector_class %s', $collector_class || 'missing');
67 0         0 next;
68             }
69 3 50       399 unless (eval "require $collector_class;1") {
70 0         0 logf(error => 'Load %s FAIL %s', $collector_class, $@);
71 0         0 next;
72             }
73              
74 3 50       38 next unless my $collector = $collector_class->new->register($collector_config, $self);
75 3     2   67 $collector->on(stdout => sub ($collector, $str) { $fh->print($str) });
  2         6  
  2         31  
  2         40  
  2         3  
  2         5  
76 3         47 logf(debug => 'Loaded and set up %s', $collector_class);
77 3         15 push @collectors, $collector;
78             }
79              
80 2         20 return \@collectors;
81             }
82              
83 3     3   5 sub _eval_file ($file) {
  3         3  
  3         4  
84 3         4 local $@;
85 3         5 my $prefix = 'package Mojo::Netdata::Config; no warnings; use Mojo::Base -strict;';
86 3     1   8 my $config = eval $prefix . $file->slurp;
  1     1   229  
  1     1   2  
  1     1   34  
  1     1   4  
  1     1   2  
  1         7  
  1         166  
  1         2  
  1         31  
  1         5  
  1         2  
  1         4  
  1         164  
  1         2  
  1         32  
  1         4  
  1         2  
  1         5  
87 3 50       20 logf(error => 'Config file "%s" is invalid: %s', $file, $@) if $@;
88 3         10 return $config;
89             }
90              
91             1;
92              
93             =encoding utf8
94              
95             =head1 NAME
96              
97             Mojo::Netdata - https://netdata.cloud plugin for Perl
98              
99             =head1 SYNOPSIS
100              
101             =head2 Installation
102              
103             sudo -i
104             apt install -y cpanminus
105             cpanm -n https://github.com/jhthorsen/mojo-netdata/archive/refs/heads/main.tar.gz
106             ln -s $(which mojo-netdata) /etc/netdata/custom-plugins.d/mojo-netdata.plugin
107              
108             # See "Config file" below for information on what to place inside mojo.conf.pl
109             $EDITOR /etc/netdata/mojo.conf.pl
110              
111             =head2 Config files
112              
113             The config files are located in C. The files are
114             plain Perl files, which means you can define variables and call functions. The
115             only important part is that the last statement in the file is a hash-ref.
116              
117             Any hash-refs that has the "collector" key will be placed into L,
118             while everything else will be merged into L. Example:
119              
120             # /etc/netdata/mojo.conf.d/foo.conf.pl
121             {foo => 42, bar => 100}
122              
123             # /etc/netdata/mojo.conf.d/bar.conf.pl
124             {collector => 'Mojo::Netdata::Collector::HTTP', jobs => []}
125              
126             The two config files above will result in this L:
127              
128             {
129             foo => 42,
130             bar => 100,
131             collectors => [
132             {collector => 'Mojo::Netdata::Collector::HTTP', jobs => []},
133             },
134             }
135              
136             See L for an example config file.
137              
138             =head2 Log file
139              
140             The output from this Netdata plugin can be found in
141             C.
142              
143             =head1 DESCRIPTION
144              
145             L is a plugin for L. It can load
146             custom L classes and write data back to Netdata on a
147             given interval.
148              
149             This module is currently EXPERIMENTAL, and the API might change without
150             warning.
151              
152             =head1 ATTRIBUTES
153              
154             =head2 cache_dir
155              
156             $path = $netdata->cache_dir;
157              
158             Holds the C environment variable. See
159             L
160             for more details.
161              
162             =head2 config
163              
164             $hash_ref = $netdata->config;
165              
166             Holds the config for L and all L.
167              
168             =head2 collectors
169              
170             $array_ref = $netdata->collectors;
171              
172             An array-ref of L objects.
173              
174             =head2 debug_flags
175              
176             $str = $netdata->debug_flags;
177              
178             Defaults to the C environment variable. See
179             L
180             for more details.
181              
182             =head2 host_prefix
183              
184             $str = $netdata->host_prefix;
185              
186             Defaults to the C environment variable. See
187             L
188             for more details.
189              
190             =head2 log_dir
191              
192             $path = $netdata->log_dir;
193              
194             Holds the C environment variable. See
195             L
196             for more details.
197              
198             =head2 plugins_dir
199              
200             $path = $netdata->plugins_dir;
201              
202             Holds the C environment variable. See
203             L
204             for more details.
205              
206             =head2 stock_config_dir
207              
208             $path = $netdata->stock_config_dir;
209              
210             Holds the C environment variable. See
211             L
212             for more details.
213              
214             =head2 update_every
215              
216             $num = $netdata->update_every;
217              
218             Defaults to the C environment variable. See
219             L
220             for more details.
221              
222             =head2 user_config_dir
223              
224             $path = $netdata->user_config_dir;
225              
226             Holds the C environment variable. See
227             L
228             for more details.
229              
230             =head2 web_dir
231              
232             $path = $netdata->web_dir;
233              
234             Holds the C environment variable. See
235             L
236             for more details.
237              
238             =head1 METHODS
239              
240             =head2 start
241              
242             $bool = $netdata->start;
243              
244             Reads the L and return 1 if any L got registered.
245              
246             =head1 AUTHOR
247              
248             Jan Henning Thorsen
249              
250             =head1 COPYRIGHT AND LICENSE
251              
252             Copyright (C) Jan Henning Thorsen
253              
254             This program is free software, you can redistribute it and/or modify it under
255             the terms of the Artistic License version 2.0.
256              
257             =head1 SEE ALSO
258              
259             L.
260              
261             =cut