4

DBI呼び出し中にアプリケーションがランダムに停止するという問題があります。テスト環境や受け入れ環境ではこれを確実に再現できないため、本番システムでこれを監視して、何が起こっているのかを把握する必要があります。

環境変数を介してすべてのDBIトラフィックをログに記録しています。DBI_TRACE

DBI_TRACE=3=dbi.log script.pl

ただし、問題は、DBIログファイルにタイムスタンプがないため、ダイの時点で何が発生していたかを見つけるためにタイムスタンプをさかのぼることが難しいことです。

タイムスタンプを使用してDBIのロギングを有効にする方法はありますか?

4

6 に答える 6

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

于 2009-08-19T00:58:09.950 に答える
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

そのフィルタリングプログラムは、 syslogdのおかげで私のシステムにタイムスタンプを追加するロガーでさえ、何でもかまいません。

于 2009-08-19T03:48:15.393 に答える
2

DBIドキュメントには、階層化されたファイルハンドルを使用してタイムスタンプ付きログを有効にする方法のコードが含まれています。欠点は、環境変数を使用する余裕がなくなり、コードでトレースパラメータを設定する必要があることです。

$dbh->trace('SQL', $fh);

$ fhは、PerlIO::Viaの「サブクラス」であるオブジェクトへの参照を保持します。

于 2009-08-19T04:10:13.867 に答える
2

DBI::Logを調べることをお勧めします。

デフォルトでは、STDERRに出力されるため、使用法を複製するには、次のように呼び出します。

perl -MDBI :: Log script.pl 2> dbi.log

出力により、DBIベースのSQLアクセスで何が起こったかの全体像がはるかによくわかります。

  • タイムスタンプを含む、
  • プレースホルダー(別名:バインドされたパラメーター)を実際の値に置き換えて、SQLで直接クエリを再実行してデバッグしやすくします。
  • それぞれのSQLクエリにつながったPerlコードの呼び出しトレースが含まれています。
于 2018-01-29T15:27:27.810 に答える
1

可能ではありますが、DBI自体に問題があるのではないかと思います。トレースレベル3を使用しているように見えますが、DBIのトレースは非常に冗長になる可能性があります。DBIx:: Log4perlを使用すると、構成可能なタイムスタンプ、メソッド呼び出し、SQL、バインディングなどのトレースを取得できます。必要なのは、接続呼び出しを変更することだけです。

于 2011-05-03T08:04:06.977 に答える
0

次のAPIを提供する構成可能な動的ロギングを備えた最小限のperlロガーを作成しました。

        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__
于 2011-04-21T20:32:57.533 に答える