File Coverage

blib/lib/Metabrik/Server/Logstash.pm
Criterion Covered Total %
statement 9 115 7.8
branch 0 64 0.0
condition 0 13 0.0
subroutine 3 14 21.4
pod 2 10 20.0
total 14 216 6.4


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # server::logstash Brik
5             #
6             package Metabrik::Server::Logstash;
7 1     1   782 use strict;
  1         2  
  1         34  
8 1     1   5 use warnings;
  1         2  
  1         26  
9              
10 1     1   5 use base qw(Metabrik::System::Process);
  1         10  
  1         1460  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable elk) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             datadir => [ qw(datadir) ],
20             conf_file => [ qw(file) ],
21             log_file => [ qw(file) ],
22             version => [ qw(2.4.0|5.0.0|5.5.2) ],
23             no_output => [ qw(0|1) ],
24             binary => [ qw(binary_path) ],
25             },
26             attributes_default => {
27             version => '5.5.2',
28             no_output => 0,
29             log_file => 'logstash.log',
30             },
31             commands => {
32             install => [ ],
33             get_binary => [ ],
34             check_config => [ qw(conf_file) ],
35             start => [ qw(conf_file|OPTIONAL) ],
36             start_in_foreground => [ qw(conf_file|OPTIONAL) ],
37             stop => [ ],
38             generate_conf => [ qw(conf_file|OPTIONAL) ],
39             status => [ ],
40             },
41             require_modules => {
42             'Metabrik::File::Text' => [ ],
43             },
44             require_binaries => {
45             tar => [ ],
46             },
47             need_packages => {
48             ubuntu => [ qw(tar openjdk-8-jre-headless) ],
49             debian => [ qw(tar openjdk-8-jre-headless) ],
50             kali => [ qw(tar openjdk-8-jre-headless) ],
51             freebsd => [ qw(openjdk logstash) ],
52             },
53             };
54             }
55              
56             sub brik_use_properties {
57 0     0 1   my $self = shift;
58              
59 0           my $datadir = $self->datadir;
60 0           my $version = $self->version;
61 0           my $conf_file = $datadir."/logstash-$version.conf";
62 0           my $log_file = $datadir."/logstash-$version.log";
63              
64             return {
65 0           attributes_default => {
66             conf_file => $conf_file,
67             log_file => $log_file,
68             },
69             };
70             }
71              
72             sub get_binary {
73 0     0 0   my $self = shift;
74              
75 0           my $binary = $self->binary;
76 0 0         if (! defined($binary)) {
77 0           my $datadir = $self->datadir;
78 0           my $version = $self->version;
79 0           $binary = $datadir.'/logstash-'.$version.'/bin/logstash';
80             }
81              
82 0 0         $self->brik_help_run_file_not_found('get_binary', $binary) or return;
83              
84 0           $self->log->verbose("get_binary: found binary [$binary]");
85              
86 0           return $binary;
87             }
88              
89             sub generate_conf {
90 0     0 0   my $self = shift;
91 0           my ($conf_file) = @_;
92              
93 0   0       $conf_file ||= $self->conf_file;
94              
95 0           my $conf =<
96             input {
97             file {
98             type => "apache"
99             path => "/var/log/www/example.com-access.log*"
100             add_field => { "site" => "www.example.com" }
101             start_position => "beginning" # Start from beginning of every files
102             sincedb_path => "/dev/null" # Read files entirely every times
103             ignore_older => "0" # Process every file, even older than 24 hours
104             }
105             }
106              
107             filter {
108             if [message] =~ /: logfile turned over\$/ {
109             drop {}
110             }
111             if [type] == "apache" {
112             # Defining patterns:
113             # https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html
114             grok {
115             match => { "message" => "%{COMBINEDAPACHELOG}" }
116             overwrite => [ "message" ]
117             }
118             geoip {
119             source => "clientip"
120             target => "geoip"
121             add_tag => [ "apache-geoip" ]
122             }
123             date {
124             match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
125             remove_field => [ "timestamp" ]
126             }
127             }
128             }
129              
130             output {
131             if "_grokparsefailure" in [tags] {
132             null {}
133             }
134             if [type] == "apache" {
135             redis {
136             host => "127.0.0.1"
137             data_type => "list"
138             key => "logstash"
139             codec => json
140             congestion_interval => 1
141             congestion_threshold => 20000000
142             # Batch processing requires redis >= 2.4.0
143             batch => true
144             batch_events => 50
145             batch_timeout => 5
146             }
147             }
148             else {
149             stdout {
150             codec => json
151             }
152             }
153             }
154             EOF
155             ;
156              
157 0 0         my $ft = Metabrik::File::Text->new_from_brik_init($self) or return;
158 0           $ft->append(0);
159 0           $ft->overwrite(1);
160              
161 0 0         $ft->write($conf, $conf_file) or return;
162              
163 0           return $conf_file;
164             }
165              
166             sub install {
167 0     0 0   my $self = shift;
168              
169 0           my $datadir = $self->datadir;
170 0           my $version = $self->version;
171              
172 0           my $url = 'https://artifacts.elastic.co/downloads/logstash/logstash-5.5.2.tar.gz';
173 0 0         if ($version eq '2.4.0') {
    0          
174 0           $url = 'https://download.elastic.co/logstash/logstash/logstash-2.4.0.tar.gz';
175             }
176             elsif ($version eq '5.0.0') {
177 0           $url = 'https://artifacts.elastic.co/downloads/logstash/logstash-5.0.0.tar.gz';
178             }
179              
180 0 0         my $cw = Metabrik::Client::Www->new_from_brik_init($self) or return;
181 0 0         $cw->mirror($url, "$datadir/logstash.tar.gz") or return;
182              
183 0   0       my $cwd = defined($self->shell) && $self->shell->pwd || '/tmp';
184              
185 0 0         if (defined($self->shell)) {
186 0 0         $self->shell->run_cd($datadir) or return;
187             }
188             else {
189 0 0         chdir($datadir) or return $self->log->error("install: chdir: $!");
190             }
191              
192 0           my $cmd = "tar zxvf logstash.tar.gz";
193 0 0         my $r = $self->execute($cmd) or return;
194              
195 0 0         if (defined($self->shell)) {
196 0 0         $self->shell->run_cd($cwd) or return;
197             }
198             else {
199 0 0         chdir($cwd) or return $self->log->error("install: chdir: $!");
200             }
201              
202 0           return 1;
203             }
204              
205             sub check_config {
206 0     0 0   my $self = shift;
207 0           my ($conf_file) = @_;
208              
209 0 0         $self->brik_help_run_undef_arg('start', $conf_file) or return;
210 0 0         $self->brik_help_run_file_not_found('start', $conf_file) or return;
211              
212 0           my $datadir = $self->datadir;
213 0           my $version = $self->version;
214 0           my $log_file = $self->log_file;
215              
216 0 0         my $binary = $self->get_binary or return;
217              
218 0           my $cmd = "$binary -t -f $conf_file -l $log_file";
219              
220 0           $self->log->info("check_config: started...");
221              
222 0           return $self->system($cmd);
223             }
224              
225             #
226             # logstash -f -l --debug
227             #
228             sub start {
229 0     0 0   my $self = shift;
230 0           my ($conf_file) = @_;
231              
232 0 0         if ($self->status) {
233 0           return $self->info_process_is_running;
234             }
235              
236 0   0       $conf_file ||= $self->conf_file;
237 0 0         $self->brik_help_run_undef_arg('start', $conf_file) or return;
238 0 0         $self->brik_help_run_file_not_found('start', $conf_file) or return;
239              
240             # Make if a full path file
241 0 0         if ($conf_file !~ m{^/}) {
242 0   0       my $cwd = define($self->shell) && $self->shell->full_pwd || '/tmp';
243 0           $conf_file = $cwd.'/'.$conf_file;
244             }
245              
246 0           my $log_file = $self->log_file;
247 0           my $no_output = $self->no_output;
248              
249 0 0         my $binary = $self->get_binary or return;
250              
251 0           $self->close_output_on_start($no_output);
252              
253             $self->SUPER::start(sub {
254 0     0     $self->log->verbose("Within daemon");
255              
256 0           my $cmd = "$binary -f $conf_file -l $log_file";
257 0 0         if ($self->log->level > 2) {
258 0           $cmd .= ' --debug';
259             }
260              
261 0           $self->system($cmd);
262              
263 0           $self->log->error("start: son failed to start");
264 0           exit(1);
265 0           });
266              
267 0           return 1;
268             }
269              
270             sub start_in_foreground {
271 0     0 0   my $self = shift;
272 0           my ($conf_file) = @_;
273              
274 0   0       $conf_file ||= $self->conf_file;
275 0 0         $self->brik_help_run_undef_arg('start_in_foreground', $conf_file) or return;
276 0 0         $self->brik_help_run_file_not_found('start_in_foreground', $conf_file) or return;
277              
278 0 0         if ($self->status) {
279 0           return $self->error_process_is_running;
280             }
281              
282 0           my $log_file = $self->log_file;
283              
284 0 0         my $binary = $self->get_binary or return;
285              
286 0           my $cmd = "$binary -f $conf_file -l $log_file";
287 0 0         if ($self->log->level > 2) {
288 0           $cmd .= ' --debug';
289             }
290              
291 0           return $self->system($cmd);
292             }
293              
294             sub stop {
295 0     0 0   my $self = shift;
296              
297 0 0         if (! $self->status) {
298 0           return $self->info_process_is_not_running;
299             }
300              
301 0           my $conf_file = $self->conf_file;
302              
303 0           my $string = "-f $conf_file";
304 0 0         my $pid = $self->get_pid_from_string($string) or return;
305              
306 0           return $self->kill($pid);
307             }
308              
309             sub status {
310 0     0 0   my $self = shift;
311              
312 0           my $conf_file = $self->conf_file;
313              
314 0           my $string = "-f $conf_file";
315 0 0         if ($self->is_running_from_string($string)) {
316 0           $self->verbose_process_is_running;
317 0           return 1;
318             }
319              
320 0           $self->verbose_process_is_not_running;
321 0           return 0;
322             }
323              
324             1;
325              
326             __END__