at 18.03-beta 1.6 kB view raw
1package Logger; 2 3use strict; 4use Thread::Queue; 5use XML::Writer; 6use Encode qw(decode encode); 7 8sub new { 9 my ($class) = @_; 10 11 my $logFile = defined $ENV{LOGFILE} ? "$ENV{LOGFILE}" : "/dev/null"; 12 my $log = new XML::Writer(OUTPUT => new IO::File(">$logFile")); 13 14 my $self = { 15 log => $log, 16 logQueue => Thread::Queue->new() 17 }; 18 19 $self->{log}->startTag("logfile"); 20 21 bless $self, $class; 22 return $self; 23} 24 25sub close { 26 my ($self) = @_; 27 $self->{log}->endTag("logfile"); 28 $self->{log}->end; 29} 30 31sub drainLogQueue { 32 my ($self) = @_; 33 while (defined (my $item = $self->{logQueue}->dequeue_nb())) { 34 $self->{log}->dataElement("line", sanitise($item->{msg}), 'machine' => $item->{machine}, 'type' => 'serial'); 35 } 36} 37 38sub maybePrefix { 39 my ($msg, $attrs) = @_; 40 $msg = $attrs->{machine} . ": " . $msg if defined $attrs->{machine}; 41 return $msg; 42} 43 44sub nest { 45 my ($self, $msg, $coderef, $attrs) = @_; 46 print STDERR maybePrefix("$msg\n", $attrs); 47 $self->{log}->startTag("nest"); 48 $self->{log}->dataElement("head", $msg, %{$attrs}); 49 $self->drainLogQueue(); 50 eval { &$coderef }; 51 my $res = $@; 52 $self->drainLogQueue(); 53 $self->{log}->endTag("nest"); 54 die $@ if $@; 55} 56 57sub sanitise { 58 my ($s) = @_; 59 $s =~ s/[[:cntrl:]\xff]//g; 60 $s = decode('UTF-8', $s, Encode::FB_DEFAULT); 61 return encode('UTF-8', $s, Encode::FB_CROAK); 62} 63 64sub log { 65 my ($self, $msg, $attrs) = @_; 66 chomp $msg; 67 print STDERR maybePrefix("$msg\n", $attrs); 68 $self->drainLogQueue(); 69 $self->{log}->dataElement("line", $msg, %{$attrs}); 70} 71 721;