【问题标题】:Counting daily visitors in a log file在日志文件中计算每日访问者
【发布时间】:2016-12-11 06:31:50
【问题描述】:

我有一个跨越 1.5 年的访客日志文件。每行代表一个页面加载。每一行的结构如下:

2016-08-05 00:48:10 +0200 -> 170.67.51.153   -> Beijing - Beijing Shi: China -> http://example.com/?ref=1676 -> Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html) -> AS55966 Beijing Baidu Netcom Science and Technology Co., Ltd. -> Beijing Baidu Netcom Science and Technology Co. -> 0.9301

我使用“->”来分隔字段。

我的日志文件大小约为 50MB,解析整个文件以获取今天或昨天的访问者数量需要很长时间,因为这些实际行当然位于文件末尾。

我想使用 bash 命令“tac”,它是一个反向“cat”或类似的技术,以使行以相反的顺序排列。我的第一次尝试是(获取例如 2016-08-04 的每日访问者):

tac visitor_log.txt|grep 2016-08-04|cut -d " " -f 5|sort|uniq|wc -l

它当然会输出访问者计数,但不幸的是,它在读取整个文件时也很耗时,因为如果前一行匹配而实际行不匹配,则无法告诉“grep”停止匹配行'不匹配。

也许我应该在 Ruby 中模拟“tac”来有效地获取每日访问者数量?或者我应该使用“sed”中可能提供的一些触发器技术?不幸的是,我根本不知道“sed”。

【问题讨论】:

  • 50MB 是一个很小的文件,处理它需要几分之一秒。你是说50GB吗? Perl 最适合处理文本文件。
  • 你说“我用“->”来分隔字段”,但真正的分隔符是什么?发布问题时更改实时数据绝不是一个好主意。 cut -d " " -f 5 应该生产什么?从您的数据来看,这将是第二个->,但我想您的意思是第一个Beijing
  • 不知道为什么,但我想问。你为什么不为此使用服务? Google Analytics 非常容易实现,并且有一个 ruby​​ 应用程序客户端。它比解析文本文件要快得多,而且信息量更大。否则将其加载到数据库中,因为它再次执行比文本解析好得多。
  • 是的,我用“->”分隔字段,但是“cut”命令只能剪切输入一个字符,所以我用“”空格分割行,第5次分割正好IP 地址。
  • 文件现在只有 50 MB,但随着流量的增加和时间的推移,它会变得巨大。

标签: ruby bash perl logging sed


【解决方案1】:

如果没有更多信息,很难知道如何提供帮助,但是这个 Perl 程序会显示每天记录的访问次数

程序需要输入文件作为命令行上的参数。输出与您提供的示例数据一样简单,并显示 2016 年 8 月 5 日的一次访问

use strict;
use warnings 'all';

my %visits;

while ( <> ) {
    next unless /^(\d\d\d\d-\d\d-\d\d)/;
    ++$visits{$1};
}

for my $date ( sort keys %visits ) {
    printf "%s  --  %d\n", $date, $visits{$date};
}

输出

2016-08-05  --  1

如果您的文件真的只有 50MB,则应该只需要一两秒钟

我已经通过复制您显示的行来创建一个 50MB 文件进行测试,它在不到半秒的时间内处理完毕,一天报告了 162,823 次访问

我建议您将日志文件重新格式化为数据库,以便更轻松地查询它。这样,您只需处理一次日志文件;此后您的查询将是即时的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多