Autor Zpráva
Stibi
Profil
Zdravím, potřebuju analyzovat data z logu webserveru, data z něj preparuju pomocí regulárního výrazu, ale teď jsem narazil a nevím jak dál.
Jeden řádek logu vypadá například takto:

82.178.123.45 - - [22/Dec/2007:12:35:36] "GET /design/ADMIN/img/header.jpg HTTP/1.0" 304 - "" ""

Potřebuju z něj dostat IP adresu, datum, typ požadavku a hlavně co bylo cílem požadavku. Všechno mám hotovo, až na ten cíl požadavku.

regular_expression = re.compile(r'(?P<IP>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - - (\[)(?P<DATE>[0-9]{2,2}/[a-zA-Z].+)(\]) (")(?P<REQUEST_TYPE>GET|POST)( )(?P<REQUEST>/.+")')

V případě ukázkového řádku co jsem tady dal, se mi pod REQUEST ukáže toto: /design/ADMIN/img/header.jpg HTTP/1.0" 304 - "" ""
Potřebuji jenom: /design/ADMIN/img/header.jpg
A to nevím jak zapsat. Komplikuje to to, že cíle můžou být různé.
Např.: /rss.xml, /blog/admin, /blog/save_comment/3, atd. Ale vždy je tam alespoň jedno lomítko.

Kdyby někoho napadla třeba jenom teoretická rada, za cokoli budu vděčný, už mě z toho bolí hlava :)
Jinak jsou to regulární výrazy Pythonu, které jsou tuším podobné jako v Perlu ..
Stibi
Profil
uf, mám vyřešeno .. stačilo trochu přemýšlet, jako vždy ..

regular_expression = re.compile(r'(?P<IP>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) - - (\[)(?P<DATE>[0-9]{2,2}/[a-zA-Z].+)(\]) (")(?P<REQUEST_TYPE>GET|POST)( )(?P<REQUEST>/+.+?) (.+)(")')
Stibi
Profil
ups, stejně to má mouchy, někdy se v logu vyskytuje user :

82.178.123.45 - stibi [22/Dec/2007:12:35:35] "GET /blog/admin/ HTTP/1.0" 200 2912 "" ""

Takže pro tento případ se to ještě musí odladit ...

UPDATE:
zdá se, že mám už opravdu hotovo :) Kdyby náhodou někdy někdo potřeboval, tak konečná podoba onoho regulárního výrazu je:

regular_expression = re.compile(r'(?P<IP>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) ([-] ([a-zA-Z]*|[-])) (\[)(?P<DATE>[0-9]{2,2}/[a-zA-Z].+)(\]) (")(?P<REQUEST_TYPE>GET|POST)( )(?P<REQUEST>/+.*?) (.+)(")')

Jinak jedná se o access log CherryPy.
S takovýmto regulárním výrazem není problém data vypsat na stdout nebo s nimi jakkoli dál pracovat.
Výpis do konzole:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import re

log_file = open('../logs/access2.log', 'r')

regular_expression = re.compile(r'(?P<IP>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) ([-] ([a-zA-Z]*|[-])) (\[)(?P<DATE>[0-9]{2,2}/[a-zA-Z].+)(\]) (")(?P<REQUEST_TYPE>GET|POST)( )(?P<REQUEST>/+.*?) (.+)(")')

log_lines = log_file.readlines()
log_lines_len = len(log_lines)

def vypis():
	line_number = 0
	for line in log_lines:
		line_number += 1
		for match in re.finditer(regular_expression, line):
			print "%s - IP: %s , DATE: %s , REQUEST-TYPE: %s , REQUEST: %s" % (line_number, match.group("IP"), match.group("DATE"), match.group("REQUEST_TYPE"), match.group("REQUEST"))
		
	print "\n počet řádků v logu: %s" % log_lines_len
	
vypis()
peta
Profil
platna IP ma ale reg vyraz:

var ip0 = "(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])"; //255-250 249-200 199-100 99-10 9-0
var ip = "(?:(?:"+ ip0 +"\\.){3}"+ ip0 +")";
Stibi
Profil
peta: ok, beru v úvahu, já jsem se tímhle hned nechtěl zabývat, chtěl jsem funkční kód a jelikož do toho logu se teoreticky jiná než platná IP adresa nemůže dostat, nebylo to pro mě prioritní a vystačil jsem si s omezením na 4 cifry které mohou nabývat jedné až tří číslic.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: