Я вижу поведение, которое не могу объяснить, при использовании log4perl для отправки сообщения по электронной почте.
Таким образом, следующий тестовый скрипт работает нормально, и электронное письмо отправляется без проблем:
#!/usr/bin/perl
use strict;
use warnings;
use Log::Log4perl qw(:easy);
use Log::Dispatch;
my $appender_email = Log::Log4perl::Appender->new(
"Log::Dispatch::Email::SSMTP",
threshold => "INFO",
to => '[email protected]',
subject => 'Perl script message'
);
my $email_logger = get_logger();
$email_logger->level($INFO);
$email_logger->add_appender($appender_email);
$email_logger->info('hi');
Log::Dispatch::Email::SSMTP
— это модуль, который я написал для отправки электронных писем с помощью команды ssmtp.
Странности начинаются, когда точно такой же код перемещается в другой пакет в другом файле в том же каталоге, что и мой исходный скрипт. Когда я делаю это и использую этот пакет из своего исходного скрипта, электронная почта не отправляется и ошибок не возникает.
Однако, если я изменю:
Log::Dispatch::Email::SSMTP
to
Log::Log4perl::Appender::Screen
Он отлично печатает «привет» на экране, когда я запускаю свой скрипт.
Итак, если log4perl работает при отправке сообщения на экран, почему он не работает при попытке отправить электронное письмо? И почему один и тот же код запускает электронное письмо из исходного скрипта, а не из пакета? Опять же, нет никаких ошибок или каких-либо указаний на то, что что-то пошло не так. И я проверил, что мой модуль загружается операторами печати. Таким образом, код моего модуля определенно загружается, но электронное письмо все еще не срабатывает.
ОБНОВЛЕНИЕ Вот код, когда он не работает по запросу в комментариях.
maillog.pl
#!/usr/bin/perl
BEGIN { unshift @INC, "/home/steve/perl/perl-lib" }
use strict;
use warnings;
use Testy;
print 'start' . "\n";
Вот пакет Testy.pm
:
package Testy;
BEGIN { unshift @INC, "/home/steve/perl/perl-lib" }
use strict;
use warnings;
use Log::Log4perl qw(:easy);
use Log::Dispatch;
print 'end' . "\n";
my $appender_email = Log::Log4perl::Appender->new(
"Log::Dispatch::Email::SSMTP",
#"Log::Log4perl::Appender::Screen",
threshold => "INFO",
to => '[email protected]',
subject => 'Perl script message'
);
my $email_logger = get_logger();
$email_logger->level($INFO);
$email_logger->add_appender($appender_email);
$email_logger->info('hi');
1;
А вот и мой модуль SSMTP
, расположенный в /home/steve/perl/perl-lib/Log/Dispatch/Email/SSMTP
:
package Log::Dispatch::Email::SSMTP;
use strict;
use warnings;
use Log::Dispatch::Email;
use Data::Dumper;
use base qw( Log::Dispatch::Email );
print "hi, i'm here!\n";
sub send_email {
my $self = shift;
my %p = @_;
my $to = escape ( join ',', @{$self->{to}} );
my $subject = $self->{subject};
my $message = $p{message};
$message =~ s/'/'\\''/g;
print $to . "\n";
print $subject . "\n";
print $message . "\n";
print "I'm working!";
system("echo 'To: $to\nFrom: \'Me\' <myemail\@gmail.com>\nSubject:$subject\n\n$message' | /usr/sbin/ssmtp $to");
}
sub escape {
my $address = shift;
$address =~ s/@/\\@/g;
return $address;
}
1;
Когда я запускаю ./maillog.pl
, электронное письмо не отправляется при использовании кода в пакете Testy
(тот же код работает в файле maillog.pl
. Однако, если я раскомментирую Log::Dispatch::Email::SSMTP
и заменю на Log::Log4perl::Appender::Screen
, он сработает.
ОБНОВЛЕНИЕ #2 Если я изменю Log::Log4perl::Appender::Screen
на Log::Dispatch::Screen
, это тоже сработает. Так может пришёл какой-то баг в Log::Dispatch::Email
?
Log::Dispatch
иLog::Log4Perl
— разные решения для ведения журнала; кажется, вы написали приложение для электронной почты дляLog::Dispatch
, но используете его вLog::Log4Perl
..? - person Kenney   schedule 03.12.2015Testy.pm
, единственное реальное различие — это адрес электронной почты ([email protected]
противs@dondley....
) — вы, вероятно, изменили его для публикации здесь, так что, вероятно, это не так? - person Kenney   schedule 03.12.2015Log::Dispatch::EMail
будет сбрасывать при уничтожении. Может деструктор не вызывается при загрузке через модуль? Однако буферизация удобна для получения только одного письма за один запуск скрипта; вы можете рассмотреть другой обходной путь, напримерEND { $appender_email->flush() }
.. - person Kenney   schedule 03.12.2015