Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 持续从文本文件读入数据的有效方法_Perl_Logging_Ftp - Fatal编程技术网

Perl 持续从文本文件读入数据的有效方法

Perl 持续从文本文件读入数据的有效方法,perl,logging,ftp,Perl,Logging,Ftp,我们在FTP端点上有一个脚本,用于监视FTP守护进程输出的FTP日志。 目前我们所做的是让一个perl脚本在文件上运行tail-F,并将每一行发送到一个远程MySQL数据库,根据记录类型使用稍微不同的列内容 该数据库具有用于tarball名称/内容以及所述包的FTP用户操作的表;下载、删除VSFTPd日志以及其他所有内容 我认为这特别糟糕,但我不确定有什么更好 替换的目标仍然是尽可能快地将日志文件内容输入数据库。我正在考虑做一些事情,比如制作一个FIFO/pipe文件来代替FTP日志文件,这样我

我们在FTP端点上有一个脚本,用于监视FTP守护进程输出的FTP日志。 目前我们所做的是让一个perl脚本在文件上运行tail-F,并将每一行发送到一个远程MySQL数据库,根据记录类型使用稍微不同的列内容

该数据库具有用于tarball名称/内容以及所述包的FTP用户操作的表;下载、删除VSFTPd日志以及其他所有内容

我认为这特别糟糕,但我不确定有什么更好

替换的目标仍然是尽可能快地将日志文件内容输入数据库。我正在考虑做一些事情,比如制作一个FIFO/pipe文件来代替FTP日志文件,这样我就可以周期性地读取一次,确保我不会在两次中读取相同的内容。假设VSFTPd能很好地解决这个问题(我想不会的,欢迎光临!)

FTP守护进程是VSFTPd,我至少相当肯定它们的日志功能范围是:xfer风格的日志、VSFTPd风格的日志,或者两者都有,或者根本没有日志


问题是,如果有的话,还有什么比我们正在做的更好呢?

您应该研究inotify(假设您使用的是一个不错的基于posix的操作系统),这样您就可以在日志文件更新时运行perl脚本。如果这一级别的IO导致问题,您可以始终将日志文件保存在RAMdisk上,以便IO非常快

这将帮助您设置:

老实说,我不认为你现在所做的有什么错
tail-f
非常有效。它唯一真正的问题是,如果您的watcher脚本死掉,它就会失去状态(这是一个用旋转日志文件来解决的半困难问题)。CPAN上还有一个很好的模块,它可以将您从shellout中解救出来,并提供一些很好的自定义功能


使用FIFO作为日志可以工作(只要vsftpd在任何时候都不尝试取消链接并重新创建日志文件,它可能会这样做),但我发现它有一个主要问题。如果没有人从FIFO的另一端读取数据(例如,如果脚本崩溃或从未启动),那么很快,所有对FIFO的写入都将开始阻塞。我还没有测试过这一点,但很可能日志文件写入块会导致整个服务器挂起。这不是一个很好的场景。

您可以将文件作为管道中的文件打开

open(my $file, '-|', '/ftp/file/path');

while (<$file>) {
    # you know the rest
}
open(我的$file'-|','/ftp/file/path');
而(){
#其余的你都知道
}
Tail可以做到这一点,加上启发式睡眠和良好的错误处理和恢复


编辑:再想一想,如果您能够管理一个真正的系统管道,它会更好。如果没有,则需要找到放入数据库的最后一个内容,并旋转文件,直到在进程启动时找到放入数据库的最后一个内容。要做到这一点并非易事,如果您无法确定从何处中断,则可能无法做到。

您在读取不断更新的文件时遇到的问题是,即使到达文件末尾,您仍希望继续读取。解决方法是重新查找文件中的当前位置:

查找文件句柄,0,1

下面是我做这类事情的代码:

open(FILEHANDLE,'<', '/var/log/file') || die 'Could not open log file';
seek(FILEHANDLE, 0, 2) || die 'Could not seek to end of log file';
for (;;) {
while (<FILEHANDLE>) {
    if ( $_ =~ /monitor status down/ ) {
            print "Gone down\n";
        }
    }
    sleep 1;
    seek FILEHANDLE, 0, 1;      # clear eof
}  

open(FILEHANDLE,'这不是什么“定时警报”,因为添加到日志文件的操作非常频繁。比方说……至少每5秒一次,每秒多次,其他几次每秒多次。这更多的是关于如何最好地主动获取内容并将其发送到某个地方。此外,高效且只需一次给定的条目。Perl模块和CPAN是我最好的朋友。轻视当我指向Net::FTP时,我们从perl脚本中发出FTP命令……;顺便说一句,你的代表疯了。太棒了。社区成员应该渴望和你一样有帮助。