我正在开发一个项目,我正在读取日志文件并处理它们并将它们加载到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。我没有在我的代码中的任何地方设置此错误字符串。那么,这个字符串来自哪里?是否可以修改此字符串以指出其读取的文件? (我有一个文件名变量)。任何帮助表示赞赏。
感谢。
答案 0 :(得分: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