如何在Perl DBI日志文件中获取时间戳?

时间:2009-08-18 23:34:27

标签: perl logging dbi

我遇到一个问题,即应用程序在DBI调用期间随机死亡。我们无法在测试或验收环境中可靠地重现这一点,因此我需要在我们的生产系统上对其进行监控,以试图弄清楚发生了什么。

我正在通过DBI环境变量记录所有DBI_TRACE流量。

DBI_TRACE=3=dbi.log script.pl

然而问题是DBI日志文件中没有时间戳,因此很难通过它们来查找死亡时发生的事情。

有没有办法启用带时间戳的DBI记录?

6 个答案:

答案 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访问中发生的情况:

  • 包含时间戳
  • 占位符(也称为绑定参数)替换为实际值,这使得直接在SQL中重新运行查询更容易进行调试,并且
  • 包含导致相应SQL查询的Perl代码的调用跟踪

答案 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__