--- /dev/null
+package syslogd;
+
+use warnings;
+use strict;
+
+use IO::Socket;
+use Data::Dump qw/dump/;
+use CouchDB;
+
+our $port = 514;
+our $MAXLEN = 1524;
+
+sub start {
+
+ my $sock = IO::Socket::INET->new(
+ LocalPort => $port,
+ Proto => 'udp',
+ ReuseAddr => 1,
+ ) || die "can't listen to $port: $!";
+
+ CouchDB::audit('start', { port => $port });
+
+ my $buf;
+ while(1) {
+ $sock->recv($buf, $MAXLEN);
+ my ($port, $ipaddr) = sockaddr_in($sock->peername);
+ my $log = {
+ ip => join('.', unpack('C4',$ipaddr)),
+ hostname => gethostbyaddr($ipaddr, AF_INET),
+ message => $buf,
+ };
+
+ if ( $buf =~ /<(\d+)>\s*(\S*)\s*:\s*(.*)/ ) {
+ my $level = $1 % 8;
+
+ my $overlay = {
+ message => $3,
+ level => $level,
+ facility => ( $1-$level ) / 8,
+ program => $2,
+ };
+
+ $log->{$_} = $overlay->{$_} foreach keys %$overlay;
+
+ $log->{pid} = $1 if $log->{program} =~ s/\[(\d+)\]$//;
+ }
+
+ warn "log ",dump( $log );
+ CouchDB::audit( 'syslog', $log );
+ }
+
+}
+
+1;