added few local port names
[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 use server;
11
12 our $port = 514;
13 our $MAXLEN = 1524;
14
15 sub message {
16         my $sock = shift;
17
18         my $buf;
19         $sock->recv($buf, $MAXLEN);
20
21         next unless $buf;
22
23         my ($port, $ipaddr) = sockaddr_in($sock->peername);
24         my $log = {
25                 ip => join('.', unpack('C4',$ipaddr)),
26                 buf => $buf,
27         };
28
29         if ( $buf =~ s/<(\d+)>// ) {
30                 $log->{pri}    = $1 % 8;
31                 $log->{facility} = ( $1 - $log->{pri} ) / 8;
32         
33                 $log->{timestamp} = $1 if $buf =~ s/^(\w\w\w\s+\d+\s+\d\d:\d\d:\d\d)\s*//;      # strip timestamp which some syslog servers insert here
34
35                 if ( $buf =~ s/^([^:]+)\s*:\s*// ) {
36                         my $tag = $1;
37                         if ( $tag =~ m{^(\S+)\s(\S+)} ) {
38                                 $log->{tag} = $2;
39                                 $log->{hostname} = $1;
40                         } else {
41                                 $log->{tag} = $tag;
42                         }
43
44                         if ( $log->{tag} =~ s/\[(\d+)\]$// ) {
45                                 $log->{pid} = $1;
46                         } elsif ( $buf =~ s/^(\d+):\s*// ) {
47                                 $log->{pid} = $1;
48                         }
49                 }
50
51                 $log->{tag} =~ s{^/.+/([^/]+)$}{$1};
52
53                 if ( $log->{tag} =~ m{CRON}i && $buf =~ m{^\((\w+)\) (.+) \((.+)\)$} ) {
54                         $log->{cron} = {
55                                 user => $1,
56                                 command => $2,
57                                 argument => $3,
58                         };
59                 }
60
61                 if ( $buf =~ m{(init|error|mount|smart|usb|fs)}i ) {
62                         $log->{category} = $1;
63                 }
64
65                 $log->{message} = $buf;
66         }
67
68         warn "log ",dump( $log );
69         CouchDB::audit( $log->{tag}, $log );
70 }
71
72 sub start {
73
74         my $sock = IO::Socket::INET->new(
75                 LocalPort => $port,
76                 Proto => 'udp',
77                 ReuseAddr => 1,
78         ) || die "can't listen to $port: $!";
79
80         CouchDB::audit('start', { port => $port });
81
82         while(1) {
83                 message($sock);
84                 server->refresh;
85         }
86 }
87
88 1;