aboutsummaryrefslogtreecommitdiffstats
path: root/vespalog/src/Log.pm
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespalog/src/Log.pm
Publish
Diffstat (limited to 'vespalog/src/Log.pm')
-rw-r--r--vespalog/src/Log.pm93
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", @_); };