File Coverage

blib/lib/File/Syslogger.pm
Criterion Covered Total %
statement 17 69 24.6
branch 0 30 0.0
condition n/a
subroutine 6 9 66.6
pod 1 1 100.0
total 24 109 22.0


line stmt bran cond sub pod time code
1             package File::Syslogger;
2              
3 1     1   72640 use 5.006;
  1         3  
4 1     1   5 use strict;
  1         2  
  1         41  
5 1     1   6 use warnings;
  1         11  
  1         32  
6 1     1   663 use POE qw(Wheel::FollowTail);
  1         43157  
  1         6  
7 1     1   75229 use Log::Syslog::Fast ':all';
  1         4634  
  1         206  
8 1     1   13 use Sys::Hostname;
  1         2  
  1         839  
9              
10             =head1 NAME
11              
12             File::Syslogger - Use POE to tail a file and read new lines into syslog.
13              
14             =head1 VERSION
15              
16             Version 0.0.2
17              
18             =cut
19              
20             our $VERSION = '0.0.2';
21              
22             =head1 SYNOPSIS
23              
24             use File::Syslogger;
25              
26             File::Syslogger->run(
27             pri=>'alert',
28             facility=>'daemon',
29             files=>{
30             {'sagan_eve'}=>{file=>'/var/log/sagan/eve', program=>'saganEve'},
31             {'suricata_eve'}=>{file=>'/var/log/suricata/eve', program=>'suricataEve'},
32             },
33             );
34              
35             =head1 METHODS
36              
37             =head2 run
38              
39             Initiates POE sessions and run them.
40              
41             This will die if there are any config issues.
42              
43             The following options are optionaal.
44              
45             priority - The priority of the logged item.
46             Default is 'notice'.
47            
48             facility - The facility for logging.
49             Default is 'daemon'.
50            
51             program - Name of the program logging.
52             Default is 'fileSyslogger'.
53            
54             socket - The syslogd socket.
55             Default is "/var/run/log"
56              
57             The option files is a hash of hashes. It has one mandatory
58             key, 'file', which is the file to follow. All the above
59             options may be used in the sub hashes.
60              
61             For priority, below are the various valid values.
62              
63             emerg
64             emergency
65             alert
66             crit
67             critical
68             err
69             error
70             warning
71             notice
72             info
73              
74             For facility, below are the various valid values.
75              
76             kern
77             user
78             mail
79             daemon
80             auth
81             syslog
82             lpr
83             news
84             uucp
85             cron
86             authpriv
87             ftp
88             local0
89             local1
90             local2
91             local3
92             local4
93             local5
94             local6
95             local7
96              
97             File rotation should be picked up POE::Wheel::FollowTail.
98              
99             =cut
100              
101             sub run {
102 0     0 1   my ( $blank, %opts ) = @_;
103              
104 0 0         if ( !defined( $opts{files} ) ) {
105 0           die('"files" is not defined');
106             }
107              
108 0 0         if ( ref( $opts{files} ) ne 'HASH' ) {
109 0           die("$opts{files} is not a hash");
110             }
111              
112 0 0         if ( !defined( $opts{program} ) ) {
113 0           $opts{program} = 'fileSyslogger';
114             }
115              
116 0 0         if (!defined( $opts{socket} )) {
117 0           $opts{socket}="/var/run/log";
118             }
119              
120             #mapping for severity for constant handling
121 0           my %sev_mapping = (
122             'emerg' => LOG_EMERG,
123             'emergency' => LOG_EMERG,
124             'alert' => LOG_ALERT,
125             'crit' => LOG_CRIT,
126             'critical' => LOG_CRIT,
127             'err' => LOG_ERR,
128             'error' => LOG_ERR,
129             'warning' => LOG_WARNING,
130             'notice' => LOG_NOTICE,
131             'info' => LOG_INFO,
132             );
133              
134             # default to info if none is specified
135 0 0         if ( !defined( $opts{priority} ) ) {
136 0           $opts{priority} = "notice";
137             }
138             else {
139             # one was specified, convert to lower case and make sure it valid
140 0           $opts{priority} = lc( $opts{priority} );
141 0 0         if ( !defined( $sev_mapping{ $opts{priority} } ) ) {
142 0           die( '"' . $opts{priority} . '" is not a known priority' );
143             }
144             }
145              
146             #mapping for facility for constant handling
147 0           my %fac_mapping = (
148             'kern' => LOG_KERN,
149             'user' => LOG_USER,
150             'mail' => LOG_MAIL,
151             'daemon' => LOG_DAEMON,
152             'auth' => LOG_AUTH,
153             'syslog' => LOG_SYSLOG,
154             'lpr' => LOG_LPR,
155             'news' => LOG_NEWS,
156             'uucp' => LOG_UUCP,
157             'cron' => LOG_CRON,
158             'authpriv' => LOG_AUTHPRIV,
159             'ftp' => LOG_FTP,
160             'local0' => LOG_LOCAL0,
161             'local1' => LOG_LOCAL1,
162             'local2' => LOG_LOCAL2,
163             'local3' => LOG_LOCAL3,
164             'local4' => LOG_LOCAL4,
165             'local5' => LOG_LOCAL5,
166             'local6' => LOG_LOCAL6,
167             'local7' => LOG_LOCAL7,
168             );
169              
170             # default to system if none is specified
171 0 0         if ( !defined( $opts{facility} ) ) {
172 0           $opts{facility} = 'daemon';
173             }
174             else {
175             # one was specified, convert to lower case and make sure it valid
176 0           $opts{facility} = lc( $opts{facility} );
177 0 0         if ( !defined( $fac_mapping{ $opts{facility} } ) ) {
178 0           die( '"' . $opts{facility} . '" is not a known facility' );
179             }
180             }
181              
182             # process each file and setup the syslogger
183 0           my $file_count = 0;
184 0           foreach my $item ( keys( %{ $opts{files} } ) ) {
  0            
185              
186             # make sure we have a file specified
187 0 0         if ( !defined( $opts{files}{$item}{file} ) ) {
188 0           die( 'No file specified for "' . $item . '"' );
189             }
190              
191             # figure out what facility to use for this item
192 0           my $item_fac;
193 0 0         if ( defined( $opts{files}{$item}{facility} ) ) {
194              
195             # make sure it is valid
196 0           $item_fac = lc( $opts{files}{$item}{facility} );
197 0 0         if ( !defined( $fac_mapping{ $opts{facility} } ) ) {
198 0           die( '"' . $item_fac . '" in "' . $item . '" is not a known facility' );
199             }
200             }
201             else {
202             # none specified, so using default
203 0           $item_fac = $opts{facility};
204             }
205 0           $item_fac=$fac_mapping{$item_fac};
206              
207             # figure out what facility to use for this item
208 0           my $item_pri;
209 0 0         if ( defined( $opts{files}{$item}{priority} ) ) {
210              
211             # make sure it is valid
212 0           $item_pri = lc( $opts{files}{$item}{priority} );
213 0 0         if ( !defined( $fac_mapping{$item_pri} ) ) {
214 0           die( '"' . $item_pri . '" in "' . $item . '" is not a known facility' );
215             }
216             }
217             else {
218             # none specified, so using default
219 0           $item_pri = $opts{priority};
220             }
221 0           $item_pri=$sev_mapping{$item_pri};
222              
223             # figure out what program name to use
224 0           my $item_program;
225 0 0         if ( defined( $opts{files}{$item}{program} ) ) {
226 0           $item_program = $opts{files}{$item}{program};
227             }
228             else {
229             # none specified, so using default
230 0           $item_program = $opts{program};
231             }
232              
233             # create the logger that will be used by the POE session
234 0           my $logger = Log::Syslog::Fast->new( LOG_UNIX, $opts{socket}, 1, $item_fac, $item_pri, hostname, $item_program );
235              
236             # create the POE session
237             POE::Session->create(
238             inline_states => {
239             _start => sub {
240             $_[HEAP]{tailor} = POE::Wheel::FollowTail->new(
241             Filename => $_[HEAP]{file},
242 0     0     InputEvent => "got_log_line",
243             );
244             },
245             got_log_line => sub {
246 0     0     $_[HEAP]{logger}->send( $_[ARG0] );
247             },
248             },
249 0           heap => { file => $opts{files}{$item}{file}, logger => $logger },
250             );
251              
252 0           $file_count++;
253             }
254              
255 0 0         if ( $file_count == 0 ) {
256 0           die("No files specified");
257             }
258              
259 0           POE::Kernel->run;
260             }
261              
262             =head1 AUTHOR
263              
264             Zane C. Bowers-Hadley, C<< >>
265              
266             =head1 BUGS
267              
268             Please report any bugs or feature requests to C, or through
269             the web interface at L. I will be notified, and then you'll
270             automatically be notified of progress on your bug as I make changes.
271              
272              
273              
274              
275             =head1 SUPPORT
276              
277             You can find documentation for this module with the perldoc command.
278              
279             perldoc File::Syslogger
280              
281              
282             You can also look for information at:
283              
284             =over 4
285              
286             =item * RT: CPAN's request tracker (report bugs here)
287              
288             L
289              
290             =item * CPAN Ratings
291              
292             L
293              
294             =item * Search CPAN
295              
296             L
297              
298             =back
299              
300              
301             =head1 ACKNOWLEDGEMENTS
302              
303              
304             =head1 LICENSE AND COPYRIGHT
305              
306             This software is Copyright (c) 2021 by Zane C. Bowers-Hadley.
307              
308             This is free software, licensed under:
309              
310             The Artistic License 2.0 (GPL Compatible)
311              
312              
313             =cut
314              
315             1; # End of File::Syslogger