我在编写日志解析器时遇到问题.我刚开始编写更大的Perl程序/脚本,但是很好地理解bash/ksh,所以我在较小的规模上有一些经验.我为大量的代码道歉,但我不知道我哪里出错了(错误可能会误导,所以我读过).我在这里查了一下,PerlMaven和其他一些网站,并不能让它工作.
我正在尝试将日志文件提供给此解析器,让它按每列拆分日志,并按特定列的实例计数.
在这个解析器中,$statusCode
代表一个成功的连接 - 所以我试图计算使用它成功连接的次数 - 以及有数据传输的成功连接的数量(如图所示$sentbyClientBytes > 0
).如果连接成功但发送了0个字节,我只想将一个总和增加一个实例(successconnect++
)
其余的数据暂时可以被丢弃,但我会做一些与其他一些列类似的东西 - 只是用不同的状态代码反复创建相同类型的函数.
在此先感谢Perl大师.你们和你的知识一起举办互联网.
#!/usr/bin/perl
#V0.1 - testing and initiation
use strict;
use warnings;
use Scalar::Util qw(looks_like_number);
my $filename = "/dir/log";
open( my $fh, '<', "/dir/log" ) or die "Cannot open < /root/fall_log";
while ( <$fh> ) {
# wraps whole process from here to end
my $sentcount = 0;
my $successconnect = 0;
# define the counts and variables we're using
my ( $date, $time, $clientIP, $clientPort, $username, $method, $stem,
$query, $statusCode, $SentByServerBytes, $SentByClientBytes,
$servername, $serverport ) = split;
chomp;
## (use $line parameter?)
foreach ( $statusCode ) { # SC 226 is successful action and usually
# indicates download or login
if ( $statusCode == "226" ) {
if ( looks_like_number($SentByClientBytes) ) {
# adding in looks like number because "-" shows up in the
# fields where there are null values
if ( $SentByClientBytes > 0 ) {
$sentcount++ && $successconnect++;
}
else {
$successconnect++;
}
}
# This function counts each successful established connection and
# determines whether bytes were sent - if bytes were sent it
# should register as a count of "one" for successful connection
# and sent count. These counts should be measured and totaled and
# will equal total number of successful downloads and total number
# of successful connections. The numbers should be very close to
# each other as nearly all successful connections will include a
# download.
print $sentcount & $successconnect;
}
}
}
Run Code Online (Sandbox Code Playgroud)
添加我要解析的部分日志(下面).之后尝试结果的说明:
2016-03-01 06:16:24 192.168.1.10 - - [5475]user USERNAME\admin - 331 - - - 9045
2016-03-01 06:16:25 192.168.1.10 - USERNAME\admin [5476]quit - - 221 - - - 9045
2016-03-01 06:26:25 192.168.1.10 - USERNAME\admin [5475]ssh_disconnect timeout - 421 - - - 9045
2016-03-01 06:26:25 192.168.1.10 - USERNAME\admin [5475]kick - - 421 - - - 9045
2016-03-01 06:26:26 192.168.1.10 - USERNAME\admin [5475]ssh_disconnect timeout - 421 - - - 9045
2016-03-01 06:26:26 192.168.1.10 - USERNAME\admin [5475]kick - - 421 - - - 9045
2016-03-01 06:26:26 192.168.1.10 - USERNAME\admin [5475]quit - - 226 - - - 9045
2016-03-01 06:31:26 192.168.1.10 - - [5516]user USERNAME\admin - 331 - - - 9045
2016-03-01 06:31:27 192.168.1.10 - - [5515]user USERNAME\admin - 226 - - - 9045
2016-03-01 06:31:28 192.168.1.10 - - [5516]user USERNAME\admin - 226 - - - 9045
2016-03-01 06:31:28 192.168.1.10 - - [5515]user USERNAME\admin - 226 - - - 9045
2016-03-01 06:31:28 192.168.1.10 - USERNAME\admin [5516]quit - - 221 - - - 9045
2016-03-01 06:41:29 192.168.1.10 - USERNAME\admin [5515]ssh_disconnect timeout - 421 - - - 9045
2016-03-01 06:41:29 192.168.1.10 - USERNAME\admin [5515]kick - - 421 - - - 9045
2016-03-01 06:41:30 192.168.1.10 - USERNAME\admin [5515]quit - - 221 - - - 9045
2016-03-01 06:46:30 192.168.1.10 - - [5545]user USERNAME\admin - 331 - - - 9045
2016-03-01 06:46:31 192.168.1.10 - - [5544]user USERNAME\admin - 331 - - - 9045
2016-03-01 06:46:31 192.168.1.10 - - [5545]user USERNAME\admin - 331 - - - 9045
2016-03-01 06:46:31 192.168.1.10 - - [5544]user USERNAME\admin - 331 - - - 9045
2016-03-01 06:46:32 192.168.1.10 - USERNAME\admin [5545]quit - - 221 - - - 9045
2016-03-01 06:56:32 192.168.1.10 - USERNAME\admin [5544]ssh_disconnect timeout - 421 - - - 9045
2016-03-01 06:56:32 192.168.1.10 - USERNAME\admin [5544]kick - - 421 - - - 9045
2016-03-01 06:56:33 192.168.1.10 - USERNAME\admin [5544]ssh_disconnect timeout - 421 - - - 9045
2016-03-01 06:56:33 192.168.1.10 - USERNAME\admin [5544]kick - - 421 - - - 9045
2016-03-01 06:56:33 192.168.1.10 - USERNAME\admin [5544]quit - - 221 - - - 9045
2016-03-01 07:00:01 192.168.1.10 - - [5565]user USERNAME\admin - 331 - - - 9045
2016-03-01 07:00:02 192.168.1.10 - - [5565]user USERNAME\admin - 331 - - - 9045
2016-03-01 07:00:03 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/5256570.pdf - 226 - 50935 - 9045
2016-03-01 07:00:04 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256534.pdf - 226 - 52404 - 9045
2016-03-01 07:00:05 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256671.pdf - 226 - 50336 - 9045
2016-03-01 07:00:06 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256565.pdf - 226 - 50858 - 9045
2016-03-01 07:00:06 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256634.pdf - 226 - 51039 - 9045
2016-03-01 07:00:07 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/5256536.pdf - 226 - 51657 - 9045
2016-03-01 07:00:07 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256668.pdf - 226 - 51219 - 9045
2016-03-01 07:00:08 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256666.pdf - 226 - 50397 - 9045
2016-03-01 07:00:09 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256641.pdf - 226 - 50652 - 9045
2016-03-01 07:00:09 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256648.pdf - 226 - 51529 - 9045
2016-03-01 07:00:10 192.168.1.10 - USERNAME\admin [5565]sent /root/files/otherfiles/75256525.pdf - 226 - 50913 - 9045
2016-03-01 06:46:30 192.168.1.10 - - [5545]USERNAME\Admin - 226 - - - 9045
2016-03-01 06:46:31 192.168.1.10 - - [5544]USERNAME\Admin -226 - - - 9045
2016-03-01 06:46:31 192.168.1.10 - - [5545]USERNAME\Admin - 331 - - - 9045
2016-03-01 06:46:31 192.168.1.10 - - [5544]USERNAME\Admin - 331 - - - 9045
Run Code Online (Sandbox Code Playgroud)
这应该检查第9列($statuscode)
包含226(成功连接)的所有实例,并将其与第10列($SentByServerBytes)
进行比较,以查看数据是否实际发送.如果第10列大于0,则将一个"实例"添加到$successconnect
一个实例$sentcount
.如果($SentByServerBytes)
列为零(意味着连接成功但没有传输任何数据(例如 - 日志文件中的第7,9,10和11行),则添加一个实例而$successconnect
不是一个实例$sentcount
.
重新说明一下:
如果$statuscode
是226,则始终向$ successconnect添加一个实例.仅当($SentByServerBytes)
大于0时,添加一个实例$sentcount
根据这个日志,我应该结束
$successconnect
= 17个成功连接
$sentcount
=发送了11个成功文件
我现在是喜剧
[root@localhost ~]# ./logcounter1.pl
Use of uninitialized value in string eq at ./logcounter1.pl line 22, <$fh> line 998.
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111[root@localhost ~]
Run Code Online (Sandbox Code Playgroud)
再次感谢大家的帮助!我很难过,但你们总是非常有帮助!!!!!
如果您可以提供输入数据样本和所需的输出,那将极大地帮助您.因为它是你的程序中有很多多余的代码
其他人发现的错误并不是真正的问题.(使用foreach
单个值只会执行一次循环,并且使用与字符串的数字比较将首先将字符串转换为整数.)但它确实表明对您所写的内容缺乏了解
您试图提取每行的第九个字段作为值$statusCode
和特定错误
在数字eq(==)中使用未初始化的值
几乎可以肯定,因为日志文件中的一行包含少于九个字段,因此变量设置为 undef
您也是按位打印,$sentcount
$successconnect
每次从文件中读取一行.这是一个非常奇怪的打印值,我想你想在读取整个文件后打印摘要
这是重写你的程序,做我认为你想要的
#!/usr/bin/perl
#V0.1 - testing and initiation
use strict;
use warnings 'all';
use Scalar::Util 'looks_like_number';
my $filename = '/dir/log';
open my $fh, '<', $filename or die qq{Unable to open "$filename" for input: $!};
my $sent_count = 0;
my $success_connect = 0;
while ( <$fh> ) {
my @fields = split;
next unless @fields >= 9;
my ( $status_code, $sent_by_client_bytes) = @fields[8,10];
if ( defined $status_code and $status_code eq '226' ) {
++$success_connect;
if ( defined $sent_by_client_bytes
and looks_like_number($sent_by_client_bytes)
and $sent_by_client_bytes > 0 ) {
++$sent_count;
}
}
}
print qq{\$success_connect = $success_connect\n};
print qq{\$sent_count = $sent_count\n};
Run Code Online (Sandbox Code Playgroud)