simpliest possible syslog server
[pxelator] / lib / PXElator / syslogd.pm
1 package syslogd;
2
3 use warnings;
4 use strict;
5
6 use IO::Socket;
7 use Data::Dump qw/dump/;
8 use CouchDB;
9
10 our $port = 514;
11 our $MAXLEN = 1524;
12
13 sub start {
14
15         my $sock = IO::Socket::INET->new(
16                 LocalPort => $port,
17                 Proto => 'udp',
18                 ReuseAddr => 1,
19         ) || die "can't listen to $port: $!";
20
21         CouchDB::audit('start', { port => $port });
22
23         my $buf;
24         while(1) {
25                 $sock->recv($buf, $MAXLEN);
26                 my ($port, $ipaddr) = sockaddr_in($sock->peername);
27                 my $log = {
28                         ip => join('.', unpack('C4',$ipaddr)),
29                         hostname => gethostbyaddr($ipaddr, AF_INET),
30                         message => $buf,
31                 };
32
33                 if ( $buf =~ /<(\d+)>\s*(\S*)\s*:\s*(.*)/ ) {
34                         my $level = $1 % 8;
35
36                         my $overlay = {
37                                 message => $3,
38                                 level   => $level,
39                                 facility => ( $1-$level ) / 8,
40                                 program  => $2,
41                         };
42
43                         $log->{$_} = $overlay->{$_} foreach keys %$overlay;
44
45                         $log->{pid} = $1 if $log->{program} =~ s/\[(\d+)\]$//;
46                 }
47
48                 warn "log ",dump( $log );
49                 CouchDB::audit( 'syslog', $log );
50         }
51
52 }
53
54 1;