1

我正在做一个项目,我正在读取日志文件并处理它们并将它们加载到 Postgres 数据库中。这些日志文件按月分开,这意味着我给我的脚本一个特定的月份,它会遍历目录(实际上它们是每个服务器的目录,有 8 个服务器)并抓取文件并上传它们。这段代码将它们加载到数据库中:

sub insert_n_gridftp_usage {
eval {
    $sth = $dbh->prepare("INSERT into $stats_table VALUES ($epoch, '$servername', $currentnumhash{'RETR'}, $currentbyteshash{'RETR'}, $currentnumhash{'STOR'}, $currentbyteshash{'STOR'}, $currentnumhash{'ERET'}, $currentbyteshash{'ERET'}, $currentnumhash{'ESTO'}, $currentbyteshash{'ESTO'}, $currentnumhash{'LIST'}, $currentbyteshash{'LIST'}, $currentnumhash{'NLST'}, $currentbyteshash{'NLST'}, $currentnumhash{'MLSD'}, $currentbyteshash{'MLSD'}, $currentnum, $currentbytes);") || die; 
    $sth->execute;
    $dbh->commit;
} or
do {
    $stats_fails++;
    eval { $dbh->rollback };
}   

}

该表具有唯一索引约束,可防止加载重复记录。现在,当此语句遇到重复时,我在 stderr 上收到此错误:

DBD::Pg::st execute failed: ERROR:  duplicate key value violates unique constraint "transfer_unique"DETAIL:  Key (starttime, endtime, file)=(1366822840, 1366822840, /dev/null) already exists. at ./database_load_script.pl line 196, <LOGFILE> line 1332302.

LOGFILE 是我的变量,字行后面的数字是我的变量 $linenum。我没有在我的代码中的任何地方设置这个错误字符串。那么,这个字符串是从哪里来的呢?是否可以修改此字符串以指出其读取的文件?(我有一个文件名变量)。任何帮助表示赞赏。

谢谢。

4

1 回答 1

2

当您的查询失败时,您确实可以修改输出内容。目前你正在做:

$sth = $dbh->prepare("...") || die;

这意味着它die采用其默认参数,即 的值$!。但是,您也可以将自定义字符串传递给die,它会在标准错误时输出该字符串;该字符串,如果双引号,可以像其他任何变量一样插入变量。关于die参数的另一件事是它们很神奇,因为缺少尾随换行符将导致die在您的代码以及您碰巧正在阅读的任何文件中附加有关错误位置的信息时间; 如果您在die参数中包含尾随换行符,则不会发生这种情况。

因此,假设您的文件名包含在变量$filename中,您可以这样做:

$sth = $dbh->prepare('...') || die "$! at $filename line $linenum\n";

这将导致类似于以下的错误:

DBD::Pg::st_execute failed: ERROR: [...] at /path/to/logfile line 12345
于 2013-07-30T14:25:14.450 回答