0

我需要创建一份关于历史唯一访问者(由 IP 地址标识)的一次性报告,并以默认格式从 Apache 访问日志中按日期和操作系统进行组织。例子:

Date OS    Count
3/1 iPhone 23
3/1 Windows 402
3/2 iPhone 32
etc..

我今天尝试了许多工具(Octupussy、AWStats、goaccess、appachetop),但没有找到任何能够以这种方式分解日志的工具。操作系统报告在所有这些中都可以找到,但不是每天,而是整个日志。任何人都知道具有该功能的任何东西?

另外:我正在考虑编写一个 python 程序,它将遍历日志并使用正则表达式或系统 grep/awk 命令,但如果有一个快速工具或者 awk 可以轻松完成,我会很感激轻推。我在今天之前从未使用过 awk,但它似乎非常强大,如果我有更多经验,它可以让它变得简单。

4

2 回答 2

2

您没有在示例输出中包含 IP 地址,我正在编写输出中包含 IP 地址的答案。

access.log我的 apache文件的示例日志行:

27.0.0.1 - - [28/Oct/2012:21:38:34 +0530] "GET /phpmyadmin HTTP/1.1" 301 559 "-" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"

要根据他们使用的操作系统获取每天唯一身份访问者的数量:

awk '$6 ~ /GET/ \
{ gsub("[[]", "", $4); \ 
gsub(":.*", "", $4); \
print $1,$4,$14}' access.log | \

sort -t ' ' -k 2 | \
uniq -c|awk '{print $3,$2}'|uniq -c|awk '{print $3, $2, $1}'

以下答案适用于基于日期、每个操作系统的每个 IP 的唯一用户。

一个从上面获得所需输出的衬垫:

awk '$6 ~ /GET/ \
{ gsub("[[]", "", $4); \ 
gsub(":.*", "", $4); \
print $1,$4,$14}' access.log | \

sort -t ' ' -k 2 | \
uniq -c|awk '{print $3,$2,$4,$1}'

说明

awk 的第一行是过滤带有GET请求的行。

第二条 awk 行用于删除多余的右方括号[

第三行将从 apache 日志中的 datetime 字段中删除时间。

第四行打印必填字段。

第五行根据日期对输出进行排序。

最后,使用uniqawk再次以您想要的格式打印输出。

输出:

28/Oct/2012 127.0.0.1 Linux 1
于 2013-03-30T09:25:53.043 回答
0

对于组合日志格式,您可以像这样扫描它:

In [1]: import re

In [2]: text = '127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"'

In [3]: logitems = re.compile('^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) ([^ ]*) ([^ ]*) \[([^\]]*)\] "([^"]*)" \d+ \d+ "([^"]*)" "([^"]*)"')

In [4]: logitems.findall(text)
Out[4]: [('127.0.0.1', '-', 'frank', '10/Oct/2000:13:55:36 -0700', 'GET /apache_pb.gif HTTP/1.0', 'http://www.example.com/start.html', 'Mozilla/4.08 [en] (Win98; I ;Nav)')]

假设text包含日志文件文本,usingre.findall将生成一个包含您想要的信息的元组列表。

假设你有这个元组列表,使用一个列表推导和一个集合来获取唯一的 IP(我在这里使用一个简单的 2 元组进行演示):

In [4]: lst = [('127.0.0.1', 'foo'), ('192.168.0.1', 'bar'), ('123.022.200.023', 'baz'), ('127.0.0.1', 'double')]

In [5]: [i[0] for i in lst]
Out[5]: ['127.0.0.1', '192.168.0.1', '123.022.200.023', '127.0.0.1']

In [6]: list(set([i[0] for i in lst]))
Out[6]: ['192.168.0.1', '123.022.200.023', '127.0.0.1']

对于所有 IP 地址,您可以获得所有访问权限:

In [8]: [i for i in lst if i[0] == '127.0.0.1']
Out[8]: [('127.0.0.1', 'foo'), ('127.0.0.1', 'double')]

datetime.datatime然后,您可以按日期(将其转换为!)和操作系统进一步过滤。

于 2013-03-30T09:39:10.663 回答