我遇到一个问题,即应用程序在DBI调用期间随机死亡。我们无法在测试或验收环境中可靠地重现这一点,因此我需要在我们的生产系统上对其进行监控,以试图弄清楚发生了什么。
我正在通过DBI
环境变量记录所有DBI_TRACE
流量。
DBI_TRACE=3=dbi.log script.pl
然而问题是DBI日志文件中没有时间戳,因此很难通过它们来查找死亡时发生的事情。
有没有办法启用带时间戳的DBI记录?
答案 0 :(得分:3)
您可以使用File::Tee重定向STDERR并添加带时间戳的前缀。
例如:
use strict;
use warnings;
use File::Tee 'tee';
my $logfile = "/path/to/timestamped/logfile.log";
my $filter = sub { return localtime() . ' ' . $_[0] };
my $pid = tee STDERR, { preprocess => $filter, reopen => $logfile };
print STDERR "something bad happened.";
这里的优点是它不会干扰您现有的STDERR - 所有错误消息将继续发送到同一个地方。但是流被复制并写入$logfile
,通过$filter
挂钩进行任何转换。
答案 1 :(得分:2)
如果覆盖STDERR
不是一个选项,并且如果您使用的是UNIXy系统(各种帖子建议您使用),则可以将跟踪输出定向到fifo并运行时间戳过滤器:
$ mkfifo /tmp/fifo
$ perl -MTime::HiRes=time -npe 's/^/time . " "/e' < /tmp/fifo > /tmp/timestamped.log &
[1] 12345
$ DBI_TRACE=1=/tmp/fifo script.pl
过滤程序可以是任何东西,甚至logger,在我的系统上添加时间戳由 syslogd 提供。
答案 2 :(得分:2)
DBI文档contains编码如何使用分层文件句柄启用带时间戳的日志。缺点是你失去了使用环境变量的奢侈,并且必须在代码中设置跟踪参数:
$dbh->trace('SQL', $fh);
其中$ fh持有对PerlIO::Via
的'子类'的对象的引用答案 3 :(得分:1)
我怀疑DBI本身存在问题,尽管有可能。虽然我看到你使用的是跟踪级别3,但DBI的跟踪可能非常冗长。使用DBIx :: Log4perl,您将获得可配置的时间戳,方法调用,SQL,绑定等跟踪,您需要做的就是更改您的连接呼叫。 / p>
答案 4 :(得分:1)
我建议您查看DBI::Log。
默认情况下,它会打印到STDERR,因此要复制您的用法,请按以下方式调用它:
perl -MDBI :: Log script.pl 2&gt; dbi.log
通过以下方式输出可以更好地了解基于DBI的SQL访问中发生的情况:
答案 5 :(得分:0)
我编写了一个带有可配置动态日志记录的简约perl logger,为您提供以下API:
use strict ; use warnings ; use Exporter;
use Configurator ;
use Logger ;
# anonymous hash !!!
our $confHolder = () ;
sub main {
# strip the remote path and keep the bare name
$0=~m/^(.*)(\\|\/)(.*)\.([a-z]*)/;
my $MyBareName = $3;
my $RunDir= $1 ;
# create the configurator object
my $objConfigurator = new Configurator($RunDir , $MyBareName );
# get the hash having the vars
$confHolder = $objConfigurator ->getConfHolder () ;
# pring the hash vars
print $objConfigurator->dumpIni();
my $objLogger = new Logger (\$confHolder) ;
$objLogger->LogMsg ( " START MAIN " ) ;
$objLogger->LogMsg ( "my \$RunDir is $RunDir" ) ;
$objLogger->LogMsg ( "this is a simple message" ) ;
$objLogger->LogErrorMsg ( "This is an error message " ) ;
$objLogger->LogWarningMsg ( "This is a warning message " ) ;
$objLogger->LogInfoMsg ( "This is a info message " ) ;
$objLogger->LogDebugMsg ( "This is a debug message " ) ;
$objLogger->LogTraceMsg ( "This is a trace message " ) ;
$objLogger->LogMsg ( "using the following log file " . "$confHolder->{'LogFile'}" ) ;
$objLogger->LogMsg ( " STOP MAIN \n\n" ) ;
} #eof main
#Action !!!
main();
1 ;
__END__