From 4c7cf8ceca3e4b471e01f8169f51bde2a2702334 Mon Sep 17 00:00:00 2001 From: eleksir Date: Sun, 13 Dec 2020 13:17:44 +0300 Subject: [PATCH] Implement logging via Log::Any, cleanup, remove logger() --- bin/aleesa-jabber-bot | 48 ++++++++++++----- cpanfile | 4 +- data/sample_config.json | 2 +- lib/botlib.pm | 21 +------- lib/conf.pm | 4 +- lib/fortune.pm | 12 ++--- lib/friday.pm | 12 ++--- lib/jabberbot.pm | 114 ++++++++++++++++++++-------------------- lib/karma.pm | 6 +-- lib/lat.pm | 13 ++--- 10 files changed, 113 insertions(+), 123 deletions(-) diff --git a/bin/aleesa-jabber-bot b/bin/aleesa-jabber-bot index b975914..675b203 100755 --- a/bin/aleesa-jabber-bot +++ b/bin/aleesa-jabber-bot @@ -6,7 +6,6 @@ use warnings; use utf8; use open qw(:std :utf8); use English qw( -no_match_vars ); - use version; our $VERSION = qw(1.0); my $workdir; @@ -26,18 +25,23 @@ use Cwd::utf8 qw(chdir abs_path); use POSIX qw(setgid setuid setsid); use File::Path qw(make_path); use File::Basename qw(basename dirname); +use Log::Any::Adapter; +use Log::Any::For::Std; use conf qw(loadConf); -use botlib qw(logger); use jabberbot qw(run_jabberbot); sub daemonize (); sub __fork (); +sub __signal_handler; local $OUTPUT_AUTOFLUSH = 1; my $runAsUid = $UID; my $piddir = '/var/run/' . basename (abs_path ($PROGRAM_NAME)); my $C = loadConf (); +my $logfile; +if (defined $C->{'log'}) { $logfile = $C->{'log'}; } +elsif (defined $C->{'debug_log'}) {$logfile = $C->{'debug_log'}; } # if we run under root, create pid dir and set correct owner for it, same for debug log if it is defined if ($UID == 0) { @@ -54,15 +58,21 @@ if ($UID == 0) { ); } - if ($C->{'debug_log'}) { - unless (-d dirname($C->{'debug_log'})) { + die "Unable to create $piddir" unless (-d $piddir); ## no critic (ErrorHandling::RequireCarping) + + if (defined $logfile) { + my $logdir = dirname ($logfile); + + unless (-d $logdir) { make_path ( - dirname($C->{'debug_log'}), { + $logdir, { uid => $uid, group => $gid } ); } + + die "Unable to create $logdir" unless (-d $logdir); ## no critic (ErrorHandling::RequireCarping) } # drop privs @@ -72,27 +82,31 @@ if ($UID == 0) { $piddir = $workdir; } +if (defined $logfile) { + Log::Any::Adapter->set ('File', $logfile); +} else { + Log::Any::Adapter->set ('File', '/dev/null'); +} + # double fork attach to /dev/null all stdio and go background daemonize (); # write pidfile my $apath = abs_path ($PROGRAM_NAME); - -unless (defined($apath)) { - logger ("Unable to get abs_path: $OS_ERROR"); - die "Unable to get abs_path: $OS_ERROR\n"; -}; +die "Unable to get abs_path: $OS_ERROR\n" if (! defined $apath); my $pidfile = sprintf ('%s/%s.pid', $piddir, basename ($apath)); -logger ("Creating pidfile at $pidfile"); +warn "Creating pidfile at $pidfile\n"; open (my $pid, '>', $pidfile) or die "Error opening $pidfile: $OS_ERROR\n"; print $pid $PID or die "Error writing to $pidfile: $OS_ERROR\n"; close $pid; ## no critic (InputOutput::RequireCheckedSyscalls +local $SIG{INT} = \&__signal_handler; +local $SIG{TERM} = \&__signal_handler; + # set correct proctitle $PROGRAM_NAME = abs_path ($PROGRAM_NAME); ## no critic (Variables::RequireLocalizedPunctuationVars) -# run bot, at last run_jabberbot (); unlink ($pidfile) if (-f $pidfile); exit 0; @@ -101,8 +115,9 @@ sub daemonize () { __fork (); POSIX::setsid (); open (STDIN, '<', '/dev/null'); ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) - open (STDOUT, '>', '/dev/null'); ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) - open (STDERR, '>', '/dev/null'); ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) + # we handle STDOUT && STDERR via Log::Any::For::Std, so do not close them explicitly + #open (STDOUT, '>', '/dev/null'); ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) + #open (STDERR, '>', '/dev/null'); ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) __fork (); umask 0; return; @@ -115,5 +130,10 @@ sub __fork () { return; } +sub __signal_handler ($) { + warn "Caught a signal $OS_ERROR\n"; + unlink $pidfile if (-f $pidfile); + exit 0; +} __END__ # vim: set ft=perl noet ai ts=4 sw=4 sts=4: diff --git a/cpanfile b/cpanfile index 3695604..e76c97b 100644 --- a/cpanfile +++ b/cpanfile @@ -13,7 +13,9 @@ requires 'JSON::PP'; requires 'POSIX'; requires 'URI::URL'; requires 'local::lib'; - +requires 'Log::Any'; +requires 'Log::Any::Adapter'; +requires 'Log::Any::For::Std'; # Bundled Net::Jabber::Bot deps # requires 'Net::Jabber::Bot'; diff --git a/data/sample_config.json b/data/sample_config.json index ecfcee7..bb5155b 100644 --- a/data/sample_config.json +++ b/data/sample_config.json @@ -20,7 +20,7 @@ "cachedata": "data/cache/openweathermap.Id-Data.db", "appid": "get_it_on_openweathermap.org" }, - "debug_log" : "/var/log/aleesa-telegram-bot/debug.log", + "log" : "/var/log/aleesa-jabber-bot/aleesa-jabber-bot.log", "lat" : { "brain" : "data/lat/brain.sqlite", "src" : "lat.txt" diff --git a/lib/botlib.pm b/lib/botlib.pm index 851e995..5ac9d01 100644 --- a/lib/botlib.pm +++ b/lib/botlib.pm @@ -12,14 +12,11 @@ use URI::URL; use JSON::XS qw(decode_json encode_json); use Digest::MD5 qw(md5_base64); use DB_File; - use conf qw(loadConf); use vars qw/$VERSION/; - use Exporter qw(import); -our @EXPORT_OK = qw(weather logger trim randomCommonPhrase); - +our @EXPORT_OK = qw(weather trim randomCommonPhrase); $VERSION = '1.0'; my $c = loadConf (); @@ -189,22 +186,6 @@ sub __urlencode($) { return $str; } -sub logger { - my $msg = shift; - - if ($c->{debug_log}) { - my $mode = '>'; - $mode = '>>' if (-f $c->{debug_log}); - - if (open (my $LOG, $mode, $c->{debug_log})) { - print $LOG $msg . "\n"; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) - close $LOG; ## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::RequireCheckedOpen) - } - } - - return; -} - sub trim ($) { my $str = shift; diff --git a/lib/conf.pm b/lib/conf.pm index 0460fdf..6ee8188 100644 --- a/lib/conf.pm +++ b/lib/conf.pm @@ -7,13 +7,11 @@ use warnings; use utf8; use open qw(:std :utf8); use English qw( -no_match_vars ); - -use vars qw/$VERSION/; use JSON::XS; +use vars qw/$VERSION/; use Exporter qw(import); our @EXPORT_OK = qw(loadConf); - $VERSION = '1.0'; sub loadConf { diff --git a/lib/fortune.pm b/lib/fortune.pm index 0603ee3..3c7917b 100644 --- a/lib/fortune.pm +++ b/lib/fortune.pm @@ -8,18 +8,16 @@ use utf8; use open qw(:std :utf8); use English qw( -no_match_vars ); use Carp qw(cluck croak); - -use vars qw/$VERSION/; -use Exporter qw(import); -our @EXPORT_OK = qw(seed fortune); - -$VERSION = '1.0'; - use SQLite_File; use MIME::Base64; use File::Path qw(mkpath); use conf qw(loadConf); +use vars qw/$VERSION/; +use Exporter qw(import); +our @EXPORT_OK = qw(seed fortune); +$VERSION = '1.0'; + my $c = loadConf(); my $dir = $c->{fortune}->{dir}; my $srcdir = $c->{fortune}->{srcdir}; diff --git a/lib/friday.pm b/lib/friday.pm index c1d8009..d07e1e2 100644 --- a/lib/friday.pm +++ b/lib/friday.pm @@ -8,18 +8,16 @@ use utf8; use open qw(:std :utf8); use English qw( -no_match_vars ); use Carp qw(cluck croak); - -use vars qw/$VERSION/; -use Exporter qw(import); -our @EXPORT_OK = qw(seed friday); - -$VERSION = '1.0'; - use SQLite_File; use MIME::Base64; use File::Path qw(mkpath); use conf qw(loadConf); +use vars qw/$VERSION/; +use Exporter qw(import); +our @EXPORT_OK = qw(seed friday); +$VERSION = '1.0'; + my $c = loadConf(); my $dir = $c->{friday}->{dir}; my $srcfile = $c->{friday}->{src}; diff --git a/lib/jabberbot.pm b/lib/jabberbot.pm index fa10f27..445eef7 100644 --- a/lib/jabberbot.pm +++ b/lib/jabberbot.pm @@ -8,12 +8,10 @@ use strict; use warnings; use utf8; use open qw(:std :utf8); - use Net::Jabber::Bot; use Hailo; - use conf qw(loadConf); -use botlib qw(weather logger trim randomCommonPhrase); +use botlib qw(weather trim randomCommonPhrase); use lat qw(latAnswer); use karma qw(karmaSet karmaGet); use friday qw(friday); @@ -32,7 +30,7 @@ sub __background_checks { my $bot = shift; unless ($imonline) { - $bot->ChangeStatus('Available', 'I\'m here'); + $bot->ChangeStatus ('Available', 'I\'m here'); $imonline = 1; } @@ -48,71 +46,71 @@ sub __new_bot_message { # ignore self messages return if ($hash{'from_full'} eq $bot->{'from_full'}); # parse messages - my $qname = quotemeta($c->{jabberbot}->{aleesa}->{mucname}); + my $qname = quotemeta ($c->{jabberbot}->{aleesa}->{mucname}); if ($text =~ /^$qname$/) { - $bot->SendGroupMessage($hash{'reply_to'}, 'Чего тебе?'); + $bot->SendGroupMessage ($hash{'reply_to'}, 'Чего тебе?'); } elsif ($text =~ /^$qname[\,|\:]? (.+)/) { - $bot->SendGroupMessage($hash{'reply_to'}, $hailo->learn_reply($1)); + $bot->SendGroupMessage ($hash{'reply_to'}, $hailo->learn_reply($1)); } elsif ($text eq "$c->{jabberbot}->{aleesa}->{csign}пинг") { - $bot->SendGroupMessage($hash{'reply_to'}, 'Понг.'); + $bot->SendGroupMessage ($hash{'reply_to'}, 'Понг.'); } elsif ($text eq "$c->{jabberbot}->{aleesa}->{csign}ping") { - $bot->SendGroupMessage($hash{'reply_to'}, 'Pong.'); - } elsif (substr($text, 0, 1) eq $c->{jabberbot}->{aleesa}->{csign}) { - if (substr($text, 1, 3) eq 'rum') { + $bot->SendGroupMessage ($hash{'reply_to'}, 'Pong.'); + } elsif (substr ($text, 0, 1) eq $c->{jabberbot}->{aleesa}->{csign}) { + if (substr ($text, 1, 3) eq 'rum') { eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, - '/me притаскивает на подносе стопку рома для ' . (split(/\//,$hash{from_full}))[1] . ', края стопки искрятся кристаллами соли.' + '/me притаскивает на подносе стопку рома для ' . (split (/\//,$hash{from_full}))[1] . ', края стопки искрятся кристаллами соли.' ); }; - } elsif (substr($text, 1, 5) eq 'vodka') { + } elsif (substr ($text, 1, 5) eq 'vodka') { eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, - '/me подаёт водку с маринованным огурчиком для ' . (split(/\//,$hash{from_full}))[1] + '/me подаёт водку с маринованным огурчиком для ' . (split (/\//,$hash{from_full}))[1] ); }; } elsif (substr($text, 1, 4) eq 'beer') { eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, - '/me бахает об стол перед ' . (split(/\//,$hash{from_full}))[1] . ' кружкой холодного пива, часть пенной шапки сползает по запотевшей спенке кружки.' + '/me бахает об стол перед ' . (split (/\//,$hash{from_full}))[1] . ' кружкой холодного пива, часть пенной шапки сползает по запотевшей спенке кружки.' ); }; } elsif (substr($text, 1, 7) eq 'tequila') { eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, - '/me ставит рядом с ' . (split(/\//,$hash{from_full}))[1] . ' шот текилы, аккуратно на ребро стопки насаживает дольку лайма и ставит кофейное блюдце с горочкой соли.' + '/me ставит рядом с ' . (split (/\//,$hash{from_full}))[1] . ' шот текилы, аккуратно на ребро стопки насаживает дольку лайма и ставит кофейное блюдце с горочкой соли.' ); }; - } elsif (substr($text, 1, 6) eq 'whisky') { + } elsif (substr ($text, 1, 6) eq 'whisky') { eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, - '/me демонстративно достаёт из морозилки пару кубических камушков, бросает их в толстодонный стакан и аккуратно наливает Jack Daniels. Запускает стакан вдоль барной стойки, он останавливается около ' . (split(/\//,$hash{from_full}))[1] . '.' + '/me демонстративно достаёт из морозилки пару кубических камушков, бросает их в толстодонный стакан и аккуратно наливает Jack Daniels. Запускает стакан вдоль барной стойки, он останавливается около ' . (split (/\//,$hash{from_full}))[1] . '.' ); }; - } elsif (substr($text, 1, 8) eq 'absinthe') { + } elsif (substr ($text, 1, 8) eq 'absinthe') { eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, - "/me наливает абсент в стопку. Смочив кубик сахара в абсенте кладёт его на дырявую ложечку и пожигает. Как только пламя потухнет, $c->{jabberbot}->{aleesa}->{mucname} размешивает оплавившийся кубик в абсенте и подносит стопку " .(split(/\//,$hash{from_full}))[1] . '.' + "/me наливает абсент в стопку. Смочив кубик сахара в абсенте кладёт его на дырявую ложечку и пожигает. Как только пламя потухнет, $c->{jabberbot}->{aleesa}->{mucname} размешивает оплавившийся кубик в абсенте и подносит стопку " .(split (/\//,$hash{from_full}))[1] . '.' ); }; - } elsif (substr($text, 1, 2) eq 'w ' || substr($text, 1, 2) eq 'п ') { - my $city = substr($text, 2); + } elsif (substr ($text, 1, 2) eq 'w ' || substr ($text, 1, 2) eq 'п ') { + my $city = substr ($text, 2); eval { - $bot->SendGroupMessage( + $bot->SendGroupMessage ( $hash{'reply_to'}, weather($city) =~ tr/\n/ /r ); }; - } elsif (substr($text, 1) eq 'version' || substr($text, 1) eq 'ver') { - $bot->SendGroupMessage($hash{'reply_to'}, 'Версия нуль.чего-то_там.чего-то_там'); - } elsif (substr($text, 1) eq 'help' || substr($text, 1) eq 'помощь') { - $bot->SendGroupMessage($hash{'reply_to'}, <<"EOL" ); + } elsif (substr ($text, 1) eq 'version' || substr ($text, 1) eq 'ver') { + $bot->SendGroupMessage ($hash{'reply_to'}, 'Версия нуль.чего-то_там.чего-то_там'); + } elsif (substr ($text, 1) eq 'help' || substr ($text, 1) eq 'помощь') { + $bot->SendGroupMessage ($hash{'reply_to'}, <<"EOL" ); !help | !помощь - это сообщение !f | !ф | !fortune | !фортунка - рандомная фраза из сборника цитат fortune_mod !friday | !пятница - а не пятница ли сегодня? @@ -125,44 +123,44 @@ sub __new_bot_message { фраза++ | фраза-- - повысить или понизить карму фразы EOL - } elsif (substr($text, 1) eq 'lat' || substr($text, 1) eq 'лат') { - $bot->SendGroupMessage($hash{'reply_to'}, latAnswer()); - } elsif (substr($text, 1, 6) eq 'karma ' || substr($text, 1, 6) eq 'карма ' || substr($text, 1) eq 'karma' || substr($text, 1) eq 'карма') { - my $mytext = substr($text, 7); + } elsif (substr ($text, 1) eq 'lat' || substr ($text, 1) eq 'лат') { + $bot->SendGroupMessage ($hash{'reply_to'}, latAnswer ()); + } elsif (substr ($text, 1, 6) eq 'karma ' || substr($text, 1, 6) eq 'карма ' || substr ($text, 1) eq 'karma' || substr ($text, 1) eq 'карма') { + my $mytext = substr ($text, 7); if ($mytext ne '') { - chomp($mytext); - $mytext = trim($mytext); + chomp $mytext; + $mytext = trim $mytext; } - $bot->SendGroupMessage($hash{'reply_to'}, karmaGet($hash{'reply_to'}, $mytext)); - } elsif (substr($text, 1) eq 'friday' || substr($text, 1) eq 'пятница') { - $bot->SendGroupMessage($hash{'reply_to'}, friday()); - } elsif (substr($text, 1) eq 'fortune' || substr($text, 1) eq 'фортунка' || substr($text, 1) eq 'f' || substr($text, 1) eq 'ф') { - my $phrase = fortune(); + $bot->SendGroupMessage ($hash{'reply_to'}, karmaGet ($hash{'reply_to'}, $mytext)); + } elsif (substr ($text, 1) eq 'friday' || substr ($text, 1) eq 'пятница') { + $bot->SendGroupMessage ($hash{'reply_to'}, friday ()); + } elsif (substr ($text, 1) eq 'fortune' || substr ($text, 1) eq 'фортунка' || substr ($text, 1) eq 'f' || substr ($text, 1) eq 'ф') { + my $phrase = fortune (); # workaround Net::Jabber::Bot outgoing message ![:print:] replacement $phrase =~ s/\s\s+\-\-/\n \-\-/xmsg; - $bot->SendGroupMessage($hash{'reply_to'}, $phrase); + $bot->SendGroupMessage ($hash{'reply_to'}, $phrase); } else { - $hailo->learn($text); + $hailo->learn ($text); return; } - } elsif ((substr($text, -2) eq '++') || (substr($text, -2) eq '--')) { - my @arr = split(/\n/, $text); + } elsif ((substr ($text, -2) eq '++') || (substr ($text, -2) eq '--')) { + my @arr = split (/\n/, $text); if ($#arr < 1) { - my $reply = karmaSet($hash{'reply_to'}, substr($text, 0, -2), substr($text, -2)); - $bot->SendGroupMessage($hash{'reply_to'}, $reply); + my $reply = karmaSet($hash{'reply_to'}, substr ($text, 0, -2), substr ($text, -2)); + $bot->SendGroupMessage ($hash{'reply_to'}, $reply); } else { # just message in chat - $hailo->learn($text); + $hailo->learn ($text); } } else { - $hailo->learn($text); + $hailo->learn ($text); return; } } elsif ($hash{'type'} eq 'chat') { - $bot->SendPersonalMessage($hash{'reply_to'}, 'Я вас не знаю, идите нахуй.'); + $bot->SendPersonalMessage ($hash{'reply_to'}, 'Я вас не знаю, идите нахуй.'); return; } @@ -171,23 +169,23 @@ EOL sub run_jabberbot { - $hailo = Hailo->new( + $hailo = Hailo->new ( brain => $c->{jabberbot}->{aleesa}->{brain}, order => 2 ); my %conflist = (); $conflist{$c->{jabberbot}->{aleesa}->{room}} = []; - my $qname = quotemeta($c->{jabberbot}->{aleesa}->{mucname}); + my $qname = quotemeta ($c->{jabberbot}->{aleesa}->{mucname}); - my $bot = Net::Jabber::Bot->new( + my $bot = Net::Jabber::Bot->new ( server => $c->{jabberbot}->{aleesa}->{host}, server_host => $c->{jabberbot}->{aleesa}->{host}, conference_server => $c->{jabberbot}->{aleesa}->{confsrv}, tls => 0, username => $c->{jabberbot}->{aleesa}->{authname}, # threre is some nasty bug in module, so we have to set from_full explicitly - from_full => sprintf( + from_full => sprintf ( "%s@%s/%s", $c->{jabberbot}->{aleesa}->{room}, $c->{jabberbot}->{aleesa}->{confsrv}, @@ -206,7 +204,7 @@ sub run_jabberbot { while (sleep 3) { eval { $imonline = 0; - $bot->Start(); + $bot->Start (); }; } diff --git a/lib/karma.pm b/lib/karma.pm index 37d3ebe..0fa6857 100644 --- a/lib/karma.pm +++ b/lib/karma.pm @@ -9,16 +9,14 @@ use English qw( -no_match_vars ); use Digest::SHA qw(sha1_base64); use DB_File; use Carp qw(cluck); +use conf qw(loadConf); use vars qw/$VERSION/; use Exporter qw(import); our @EXPORT_OK = qw(karmaSet karmaGet); - $VERSION = '1.0'; -use conf qw(loadConf); - -my $c = loadConf(); +my $c = loadConf (); my $karmadir = $c->{karma}->{dir}; my $max = 5; diff --git a/lib/lat.pm b/lib/lat.pm index 73c1ec6..f8a13e4 100644 --- a/lib/lat.pm +++ b/lib/lat.pm @@ -8,18 +8,15 @@ use utf8; use open qw(:std :utf8); use English qw( -no_match_vars ); use Carp qw(cluck); - -use vars qw/$VERSION/; -use Exporter qw(import); -our @EXPORT_OK = qw(train latAnswer); - -$VERSION = '1.0'; - use Hailo; use File::Basename qw(dirname); use File::Path qw(mkpath); use conf qw(loadConf); -use botlib qw(logger); + +use vars qw/$VERSION/; +use Exporter qw(import); +our @EXPORT_OK = qw(train latAnswer); +$VERSION = '1.0'; my $c = loadConf(); my $brain = $c->{lat}->{brain};