如何从Apache日志文件生成完整的访问者计数

我描述了如何从Apache日志文件创建报告,以了解本地主机与其他主机之间的匹配次数。只需将IP地址替换为另一个地址,即可轻松更改该脚本,以提供针对任何单个IP地址(相对于世界其他地方)的报告。

也可以更改它以提供具有完整访问者人数的报告,以显示每个IP地址带来了多少点击。这样就很容易显示前10个来源,或以其他方式对其进行过滤。

背景

只需回想一下,默认格式下,Apache日志文件中的每一行都是这样开始的:

127.0.0.1 - - [10/Apr/2007:10:39:11 +0300] ...
127.0.0.1 - - [10/Apr/2007:10:39:11 +0300] ...
139.12.0.2 - - [10/Apr/2007:10:40:54 +0300] ...
217.1.20.22 - - [10/Apr/2007:10:40:54 +0300] ...1234复制代码类型:[html]

这意味着,如果我们将任何一行放入$line变量中,都可以通过以下代码提取IP地址:

my $length = index ($line, " ");
my $ip = substr($line, 0, $length);12复制代码类型:[html]

使用代码

为了计算任意一组字符串,我们需要一个可以将字符串映射到标量值的数据结构。在Perl中,此数据结构称为“关联数组”或简称为“哈希”。在其他语言中,类似的事物可能称为地图,字典或查找表。

哈希基本上是一组无序的键值对,其中键是唯一的字符串,并且值可以是任何标量值(数字,字符串或引用)。

在Perl中,井号用百分比字符(%)标记。因此,我们声明%count散列以将IP保留为“命中数”映射。大多数代码与前面的示例相同,但是我们没有增加两个单独的标量,而是使用以下结构来增加哈希的元素:

$count{$ip}++;1复制代码类型:[html]

当我们第一次遇到IP地址时,该地址$count{$ip}尚不存在。如果尚不存在值,则Perl会假定其中包含“undef”值。如果在某些数字操作(例如++自动增量)中使用了该字符,则它会假装为数字0。该数字变为1,并且此操作还会在哈希中创建适当的条目。键值对会自动出现。这也称为自生化。

如您所见,哈希值会自动增长。Perl负责所有内存管理。

完成此操作后,我们将获得一个哈希值,其中每个键是一个IP地址,每个值是IP地址出现在文件中的次数。该keys函数获取哈希作为参数,并返回哈希键的无序列表。此代码将打印所有具有相应匹配数的IP地址:

foreach my $ip (keys %count) {
 print "$ip   $count{$ip}\n";
}123复制代码类型:[html]

代码

完整的脚本在这里:

#!/usr/bin/perl
use strict;
use warnings;

my $file = shift or die "Usage: $0 FILENAME\n";
open my $fh, '<', $file or die "Could not open '$file': $!";

my %count;

while (my $line = <$fh>) {
 my $length = index ($line, " ");
 my $ip = substr($line, 0, $length);
 $count{$ip}++;
}

foreach my $ip (keys %count) {
 print "$ip   $count{$ip}\n";
}123456789101112131415161718复制代码类型:[html]

兴趣点

当然,对它们进行排序会更好,下面的代码可以做到

foreach my $ip (sort keys %count) {
 print "$ip   $count{$ip}\n";
}123复制代码类型:[html]

但这会根据ASCII表对IP地址进行排序。可能不是很有趣。

更好的排序可能是这样的:

foreach my $ip (reverse sort { $count{$a} <=> $count{$b} } keys %count) {
 print "$ip   $count{$ip}\n";
}123复制代码类型:[html]

在这里,我们根据相应的值对密钥进行排序,然后我们颠倒顺序以首先获得具有最大数字的IP。这是表达式,但让我们拆开它:

reverse sort { $count{$a} <=> $count{$b} } keys %count1复制代码类型:[html]

您可以对任何字符串列表进行排序。

sort @strings;1复制代码类型:[html]

默认情况下,此排序基于ASCII表对每两个值进行比较。

您还可以使用任何其他条件对它们进行排序。例如,字符串的长度:

sort { length($a) <=> length($b) } @strings;1复制代码类型:[html]

sort()Perl的函数将采用要比较的任何两个值,将它们放在两个变量$aand中$b,然后对块进行求值。根据结果,它将保留两个值的顺序或交换它们。

sort { $count{$a} <=> $count{$b} } keys %count1复制代码类型:[html]

该代码执行相同的操作,但是它对哈希的键进行排序,并且在比较两个键时,表达式将比较两个键的值。结果将以递增的顺序显示,但是如果我们想显示点击次数最多的IP,则需要反转结果:

reverse sort { $count{$a} <=> $count{$b} } keys %count1复制代码类型:[html]

在最后一个示例中,我们执行相同的操作,但是在显示时,我们使用帮助程序变量将项数限制为前两个IP地址。

my $top = 2;
foreach my $ip (reverse sort { $count{$a} <=> $count{$b} } keys %count) {
 print "$ip   $count{$ip}\n";
 $top--;
 if ($top <= 0) {
  last;
 }
}
(0)

相关推荐

  • Redis 数据结构

    一.Redis简介 Redis是一款基于key-value的高性能NoSQL数据库,开源免费,遵守BSD协议.支持string(字符串) . hash(哈希) .list(列表) . set(集合) ...

  • 仅需2张图!AI便可生成完整运动过程

    CVer 5天前 本文转载自:量子位(QbitAI) 先给一张侧脸(关键帧1): 再给一张正脸(关键帧2): 然后仅仅根据这两张图片,AI处理了一下,便能生成整个运动过程: 而且不只是简单的那种,连在 ...

  • Win7系统关闭日志文件的方法(图文)

    Win7系统运行一段时间后,会产生大量的日志文件,用垃圾清除类的软件能发现没用的日志文件,没用的日志文件反而占用内存空间.其实大家可以关闭日志文件,那么Win7系统怎么关闭日志文件?如果不知道具体操作 ...

  • 仅需2张图,AI便可生成完整运动过程

    Python爱好者社区 今天 金磊 发自 凹非寺  量子位 报道 | 公众号 QbitAI 先给一张侧脸(关键帧1): 再给一张正脸(关键帧2): 然后仅仅根据这两张图片,AI处理了一下,便能生成整个 ...

  • C#之winform捕获Console.WriteLine内容到日志文件

    问题描述 之前接手同事的项目,是一个类似于服务端后台的Winform程序,主界面隐藏起来,只再任务栏显示程序图标. 整个项目里面没有日志记录功能,全靠Console.WriteLine打印信息.自己调 ...

  • 使用Fluentd+MongoDB采集Apache日志

    我们之前介绍了EFK日志采集分析套件,今天再介绍一个组合:Fluentd+MongoDB,用以实时收集半结构化数据. 背景知识 日志接入Fluentd后,会以json的格式在Fluentd内部进行路由 ...

  • Python3.7 读取 mp3 音频文件生成波形图效果

    更新时间:2019年11月05日 08:26:42   作者:alpha这篇文章主要介绍了Python3.7 读取 mp3 音频文件生成波形图小编,本文通过实例代码给大家介绍的非常详细,具有一定的参考 ...

  • qt 将.ui文件生成.h或.cpp文件

    生成步骤: 1.将.ui文件复制到与uic.exe同一文件夹中 2.在计算机开始中打开cmd 3.输入一下命令: cd ***(文件夹位置路径) uic ***.ui -o ***.h (生成.h文件 ...

  • 检测bam文件的完整度-流程之殇

    本来以为有bai文件就说明是流程运行是完整的,事实上我还是太年轻,最近处理一个 600个病人的肿瘤WES数据,走流程过程发现卡在CNVKIT,部分样本出现了:   File "pysam/l ...

  • Win10统一更新平台UUP升级文件转换完整ESD/ISO镜像方法详解

    自Win10创意者更新发布后,微软讲逐步采用统一更新平台(unified update platform,简称UUP)取代老旧的Windows更新方式.有关UUP的详细介绍可参考微软官方博客<I ...