0

在使用 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 => 'myemail@mail.com',
    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

Log::Log4perl::Appender::Screen

当我运行我的脚本时,它会在屏幕上打印出“hi”。

因此,如果 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 => 'myemail@mail.com',
    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::ScreenLog::Dispatch::Screen也可以。所以也许会出现某种错误Log::Dispatch::Email

4

1 回答 1

0

在常见问题解答的帮助下找到问题,请单击此处

显然,有一些缓冲正在进行,因此电子邮件不会立即发送出去,直到达到生成的消息数量的某个阈值。虽然对于我来说为什么当代码在main包中时立即发送电子邮件对我来说仍然是一个谜。

所以这里是使用buffered属性设置为 0 的代码:

my $appender_email = Log::Log4perl::Appender->new(
    "Log::Dispatch::Email::SSMTP",
    threshold => "INFO",
    to => 'me@mymail.com',
    buffered => 0,
    subject => 'Perl script message'
);
于 2015-12-03T19:54:42.367 回答