Last active
August 29, 2015 14:19
-
-
Save inakianduaga/ef2220f975d8fe6aa88d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# | |
# Json Wrapper: Wraps Stdin input into json template for logging purposes. | |
# | |
# The idea is to use this script to wrap logs from cli commands so they can be used | |
# for rsyslog @cee log processing. | |
# | |
# Author: Inaki Anduaga <inaki@inakianduaga.com> | |
# | |
# Usage: <COMMAND> | ./jsonWrap.pl <MODE> <CHANNEL> <KEY1:VAL1> <KEY2:VAL2> ... | |
# | |
# Where <MODE>: line|block. | |
# Line block will json wrap each line into an individual json entry, | |
# block will json wrap the entire output | |
# <CHANNEL>: String used to identifiy to what group this log belongs to | |
# <COMMAND>: Anything script that generates stdin output | |
# <KEY:VAL>: These optional key/value pairs will be added to the log entry | |
# | |
# Requires perls json package (in ubuntu, `apt-get install libconfig-json-perl`) | |
use strict; | |
use warnings; | |
package main; | |
use JSON; | |
# Set mode from command line arguments | |
# Defaults to line when undefined / non-matching | |
my $mode = defined($ARGV[0]) && $ARGV[0] eq 'block' ? 'block' : 'line'; | |
my $channel = $ARGV[1]; | |
# Parse extra CLI parameters into hash | |
my %extraLogParameters = parseExtraCliParameters(@ARGV); | |
# | |
# Line mode: Pipe each line through the log formatter | |
# | |
if($mode eq 'line') { | |
# Read stdin and wrap each line in a json block | |
# http://alumnus.caltech.edu/~svhwan/prodScript/perlGettingInput.html | |
while (<STDIN>) { | |
# Remove trailing linebreaks on input | |
# http://perldoc.perl.org/functions/chomp.html | |
chomp; | |
# Format line | |
my $formatted = LogFormatter($_); | |
# Print output prepended by rsyslog @cee log tag | |
print '@cee: '. $formatted . "\n"; | |
} | |
} | |
# | |
# Block mode: Buffer input and format | |
# | |
else { | |
my $stdin = ''; | |
while(<STDIN>) { | |
$stdin .= $_; | |
} | |
# Format line | |
my $formatted = LogFormatter($stdin); | |
# Print output prepended by rsyslog @cee log tag | |
print '@cee: '. $formatted . "\n"; | |
} | |
# | |
# Log formatter | |
# | |
# Formats the input string around a json string w/ additional metadata | |
# | |
# http://stackoverflow.com/questions/8463919/how-to-convert-a-simple-hash-to-json-in-perl | |
# | |
# @param string the message we want to format | |
# @param channel The log channel | |
# @params string additional `key:value` pairs to add to each log entry | |
# | |
sub LogFormatter { | |
my $JSON = JSON->new->utf8; | |
$JSON->convert_blessed(1); | |
my $message = $_[0]; | |
my %log = ("timestamp" => scalar(localtime()), "log_level" => "INFO", "channel" => $channel, "msg" => $message); | |
# Merge additional log parameters | |
@log{keys %extraLogParameters} = values %extraLogParameters; | |
# Json Encode | |
return $JSON->encode(\%log); | |
} | |
# | |
# Maps arguments of the form key:value into a hash | |
# | |
sub parseExtraCliParameters { | |
my %hash = (); | |
if(@_ + 1 > 2) { | |
for (my $i=2; $i < @_; $i++) { | |
my ($key, $value) = split /:/, $_[$i]; | |
$hash{$key} = $value; | |
} | |
} | |
return %hash; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment