diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespalog/src/Log.pm |
Publish
Diffstat (limited to 'vespalog/src/Log.pm')
-rw-r--r-- | vespalog/src/Log.pm | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/vespalog/src/Log.pm b/vespalog/src/Log.pm new file mode 100644 index 00000000000..06eda129238 --- /dev/null +++ b/vespalog/src/Log.pm @@ -0,0 +1,93 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package Log; + +require 5.006_001; +use strict; +use warnings; +use Sys::Hostname; + + +#initialize +my $VESPA_LOG_TARGET = $ENV{VESPA_LOG_TARGET} || "fd:2"; +my $VESPA_LOG_LEVELS = $ENV{VESPA_LOG_LEVELS} || "all -debug -spam"; + +my $SERVICE = $ENV{VESPA_SERVICE_NAME} || "-"; +my $HOST = hostname; + +my %LEVEL = ( error => 0x01, + warning => 0x02, + info => 0x04, + config => 0x08, + debug => 0x10, + spam => 0x20, + all => 0x3f); + +my %instance = (); + +my $VESPA_LOG_FILTER; +foreach (split(/\s+/, $VESPA_LOG_LEVELS)) { + /(-?)(\S+)/ || die "Log level parse error: $_"; + my ($inv, $value) = ($1, $LEVEL{$2}); + die "Unknown level: $2" unless $value; + if ($inv) { + $VESPA_LOG_FILTER &= ~$value; + } else { + $VESPA_LOG_FILTER |= $value; + } +} + +if ($VESPA_LOG_TARGET =~ /fd:(\d+)/) { + open(TARGET, ">&=$1") || die $!; +} elsif ($VESPA_LOG_TARGET =~ /file:(.+)/) { + open(TARGET, ">>$1") || die $!; +} else { + die "Illegal target $VESPA_LOG_TARGET"; +} +select(TARGET); $| = 1; + +sub new { + my ($self, $name) = @_; + my $type = ref($self) || $self; + $instance{$name} = bless { component => $name } unless $instance{$name}; + return $instance{$name}; +} + +sub open_target { + return unless $VESPA_LOG_TARGET =~ /file:(.+)/; + close(TARGET); + open(TARGET, ">>$1") || die $!; + select(TARGET); $| = 1; +} + +sub escape_message { + $_ = shift; + s/\n/\\n/g; + s/\r/\\r/g; + s/\t/\\t/g; + s/([\x80-\xFF])/sprintf("\\x%x",ord($1))/eg; + return $_; +} + +sub log { + my ($this, $level, $msg) = @_; + my $component = ref($this) ? $this->{component} : "-"; + die "Unknown logging level: '$level'" unless $LEVEL{$level}; + return unless $VESPA_LOG_FILTER & $LEVEL{$level}; + + open_target; + $msg = escape_message($msg); + + # format: time host pid service component level message + print TARGET (time()."\t$HOST\t$$\t$SERVICE\t$component\t$level\t$msg\n"); +} + +sub error { &log(shift, "error", @_); } +sub warning { &log(shift, "warning", @_); } +sub info { &log(shift, "info", @_); } +sub config { &log(shift, "config", @_); } +sub debug { &log(shift, "debug", @_); } +sub spam { &log(shift, "spam", @_); } + + +$SIG{__DIE__} = sub { Log->log("error", @_); }; +$SIG{__WARN__} = sub { Log->log("warning", @_); }; |