Анализ журнала (доступ к основным URL-адресам) с помощью Python

Я новичок, пытающийся использовать 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 в приведенном выше примере), подсчитайте уникальные экземпляры, ранжируйте и выплюните их в соответствии с количеством обращений, чтобы увидеть верхние URL. Есть ли способ заставить Python обрабатывать пробелы как отдельные объекты / столбцы и захватывать, например, 11-й объект?

Еще одним осложнением является то, что наши ежедневные файлы журнала ОГРОМНЫ (~15 ГБ), и в идеале я хочу, чтобы это занимало менее 20 минут, если это возможно.


Код Никласа Б. работает хорошо, и я могу распечатать лучшие IP-адреса, пользователей и т. Д.

К сожалению, я не могу заставить программу распечатать или записать это во внешний файл или по электронной почте. В настоящее время мой код выглядит следующим образом, и в файл записывается только последняя строка. В чем может быть проблема?

для ip, подсчитайте в heapq.nlargest(k, sourceip.iteritems(), key=itemgetter(1)): top = "%d %s" % (count, ip) v = open("C:/Users/guest/ Рабочий стол / Анализ журнала /urls.txt", "w")
печать >>v, верх

1 ответ

Решение

Да:

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-адреса в файл, состоит в том, что вы открываете файл заново на каждой итерации, таким образом отбрасывая содержимое файла каждый раз. Вы должны открыть файл вне цикла и писать только внутри.

Другие вопросы по тегам