#!/usr/bin/perl
# Name: synolog.pl
# Version: 0.1
# Installation:
# 1. copy synolog.pl to a directory in your $PATH (e.g. /opt/bin)
# 2. chmod 755 /opt/bin/synolog.pl
# 3. mv /usr/syno/bin/synologset1 /usr/syno/bin/synologset1.old
# 4 ln -s /opt/bin/synolog.pl /usr/syno/bin/synologset1
use warnings;
use strict;
# customize your notification settings here. Events are defined in '/usr/syno/synosdk/texts/enu/events'
my @NOTIFY_EVENTS = qw( 11800101 11800102 11B00005 11E00000 );
my $NOTIFY_RECIPIENT = "your\@email.com";
my $NOTIFY_SUBJECT = "[NAS] ###SUBJECT###";
my $NOTIFY_CMD = "echo \"###MESSAGE###\" | /opt/bin/nail -s \"###SUBJECT###\" $NOTIFY_RECIPIENT";
my $LOGFILE;
my $EVENTFILE = "/usr/syno/synosdk/texts/enu/events";
my %events;
sub send_notification {
my %typelist = (
info => 'Information',
warn => 'Warning',
err => 'Error',
);
my $event_type = $ARGV[1] && $typelist{$ARGV[1]} ? $typelist{$ARGV[1]} : "Unknown";
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime;
my $timestamp = sprintf("%02d.%02d.%4d %02d:%02d:%02d", $mday, $mon + 1, $year + 1900, $hour, $min, $sec);
my $event = $ARGV[2] ? uc($ARGV[2]) : "0x00000000";
$event =~ s/^0x//i;
my $message = "$event_type $timestamp ";
$message .= $events{$event} ? $events{$event} : "N/A";
my $arg1 = $ARGV[3] ? $ARGV[3] : " ";
my $arg2 = $ARGV[4] ? $ARGV[4] : " ";
my $arg3 = $ARGV[5] ? $ARGV[5] : " ";
my $arg4 = $ARGV[6] ? $ARGV[6] : " ";
$message =~ s/\@1/$arg1/g;;
$message =~ s/\@2/$arg2/g;;
$message =~ s/\@3/$arg3/g;;
$message =~ s/\@4/$arg4/g;;
$NOTIFY_CMD =~ s/###MESSAGE###/$message/;
$NOTIFY_SUBJECT =~ s/###SUBJECT##/$message/;
system("$NOTIFY_CMD"), if $event =~ /\b (?: ${\join('|', @NOTIFY_EVENTS) }) \b/x;
}
sub load_events {
open(EVENTS, $EVENTFILE) || die "\nCannot open '$EVENTFILE' for reading $!\n";
while(my $line = <EVENTS>) {
chomp $line;
next, if $line =~ /^$|^#|^\[/;
my ($event, $text) = split(/=/, $line, 2);
$event =~ s/^\s+|\s+$//g;
$text =~ s/^\s+|\s+$//g;
$text =~ s/^\"|\"$//g;
$events{$event} = $text;
}
close EVENTS;
}
sub process_log {
my $buffer;
open(LOG, $LOGFILE) || die "\nCannot open '$LOGFILE' for reading $!\n";
binmode LOG;
read(LOG, $buffer, 16);
my ($magic, $version, $file_len) = unpack "a8 L L", $buffer;
if ($magic ne "SYNO" && $version != 16) {
close LOG;
die "\nFormat of '$LOGFILE' not supported.\n";
}
print "-" x 170;
print "\n";
printf("%-11s | %-19s | %-10s | %-15s | %s\n", "Event Type", "Timestamp", "Event ID", "User", "Message");
print "-" x 170;
print "\n";
while(read(LOG, $buffer, 2)) {
my $record_len = unpack "S", $buffer;
read(LOG, $buffer, $record_len - 2);
my ($event_type, $timestamp, $source_len, $user_len, $event, $arg1_len, $arg2_len, $arg3_len, $arg4_len, $text) = unpack "S L S S H8 S S S S a*", $buffer;
my @typelist = qw( Unknown Information Warning Error );
$event_type = $typelist[$event_type] ? $typelist[$event_type] : "Unknown";
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($timestamp);
$timestamp = sprintf("%02d.%02d.%4d %02d:%02d:%02d", $mday, $mon + 1, $year + 1900, $hour, $min, $sec);
$event = uc(join '', reverse split(/(..)/, $event));
my ($source, $user, $arg1, $arg2, $arg3, $arg4) = unpack "a$source_len a$user_len a$arg1_len a$arg2_len a$arg3_len a$arg4_len", $text;
my $message = $events{$event} ? $events{$event} : "N/A";
$message =~ s/\@1/$arg1/g;
$message =~ s/\@2/$arg2/g;
$message =~ s/\@3/$arg3/g;
$message =~ s/\@4/$arg4/g;
printf("%-11s | %-19s | 0x%-8s | %-15s | %s\n", $event_type, $timestamp, $event, $user, $message);
}
close LOG;
}
sub usage {
print "\nUsage: synolog.pl [FILE]\n";
print "Prints FILE in Synology log format to standard output.\n";
print "Example: synolog.pl /var/log/synosys.log\n\n";
}
if ($0 =~ /synologset1$/) {
load_events;
send_notification;
my $args = join(' ', @ARGV);
system("/usr/syno/bin/synologset1.old $args");
} elsif ($#ARGV != 0 && $0 !~ /synologset1$/) {
usage;
exit;
} else {
$LOGFILE = $ARGV[0];
load_events();
process_log();
}