Skip to main content
 首页 » 编程设计

python之使用 Python 进行日志分析(访问的热门 URL)

2025年05月04日9Leo_wl

我是一个新手,正在尝试使用 Python 来分析我公司的日志文件。它们有不同的格式,所以在线日志分析器不能很好地处理它们。

格式如下:

localtime time-taken x-cs-dns c-ip sc-status s-action sc-bytes 
cs-bytes cs-method cs-uri-scheme cs-host cs-uri-port cs-uri-path 
cs-uri-query cs-username cs-auth-group s-hierarchy s-supplier-name 
rs(Content-Type) cs(Referer) cs(User-Agent) sc-filter-result 
cs-categories x-virus-id s-ip 

例子:

"[27/Feb/2012:06:00:01 +0900]" 65 10.184.17.23 10.184.17.23 200 
TCP_NC_MISS 99964 255 GET http://thumbnail.image.example.com 80 
/mall/shop/cabinets/duelmaster/image01.jpg - - - 
DIRECT thumbnail.image.example.com image/jpeg - "Wget/1.12 
(linux-gnu)" OBSERVED "RC_White_list;KC_White_list;Shopping" - 
10.0.201.17 

我现在要做的主要事情是获取所有 cs-host 和 cs-uri-path 字段,将它们连接在一起(以获取 http://thumbnail.image.example.com/mall/shop/cabinets/duelmaster/image01.jpg 在上面的例子中),计算唯一实例,并根据访问次数排名并吐出它们,以查看排名靠前的网址。例如,有没有办法让 Python 将空格视为单独的对象/列并获取第 11 个对象?

另一个复杂因素是我们的每日日志文件非常大(~15GB),理想情况下我希望尽可能在 20 分钟内完成。


Niklas B. 的代码运行良好,我可以打印出排名靠前的 IP、用户等。

不幸的是,我无法让程序打印或将其写入外部文件或电子邮件。目前我的代码看起来像这样,只有最后一行被写入文件。可能是什么问题?

for ip, count in heapq.nlargest(k, sourceip.iteritems(), key=itemgetter(1)): top = "%d %s" % (count, ip) v = open("C:/Users/guest/Desktop/Log analysis/urls.txt", "w")
print >>v, top

请您参考如下方法:

是的:

from collections import defaultdict 
from operator import itemgetter 
 
access = defaultdict(int) 
 
with open("/path/to/file.log", "wb") as f: 
  for line in f: 
    parts = line.split() # split at whitespace 
    access[parts[11] + parts[13]] += 1 # adapt indices here 
 
# print all URLs in descending order 
for url, count in sorted(access.iteritems(), key=lambda (_, c): -c): 
  print "%d %s" % (count url) 
 
# if you only want to see the top k entries: 
import heapq 
k = 10 
for url, count in heapq.nlargest(k, access.iteritems(), key=itemgetter(1)): 
  print "%d %s" % (count, url) 

未经测试。另一种可能性是使用 Counter:

from collections import Counter 
with open("/path/to/file.log", "wb") as f: 
  counter = Counter(''.join(line.split()[11:14:2]) for line in f) 
 
# print top 10 (leave argument out to list all) 
for url, count in counter.most_common(10): 
  print "%d %s" % (count, url) 

顺便说一句,将 URL 写入文件的代码的问题是您在每次迭代中重新打开文件,因此每次都会丢弃文件的内容。您应该在循环外打开文件,并且只在循环内写入。