Estoy analizando grandes registros de Apache como:
example.com:80 1.2.3.4 - - [01/Jul/2021:06:12:12 +0000] "GET /test/example/index.php?a=b&c=d HTTP/1.1" 302 486 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.3945.117 Safari/537.36"con:
import apache_log_parser, shlex parser = apache_log_parser.make_parser("%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"") with open("access.log") as f: for l in enumerate(f): x = parser(l) Para cada línea, se necesitan ~0,1 ms (portátil i5) / ~0,9 ms (CPU Atom de gama baja N2800 1,86 GHz)
Esto es bastante lento: ¡casi un milisegundo por cada línea!
Así que decidí hacer mi propio análisis con shlex (que trata muy bien con comillas como first "second block" "third block" fourth ).
¡Es peor! Obtengo, por línea, ~0,3 ms (portátil i5) / ~1,6 ms servidor de gama baja
with open("access.log") as f: for l in enumerate(f): x = shlex.split(l) Pregunta: ¿Qué método más rápido (¿quizás con expresiones regulares directas?) podría permitir el análisis de dichos registros? Solo necesito server port ip datetime url status bytes referer useragent .
Finalmente encontré una solución que mejora la velocidad x10: expresiones regulares puras.
import re r = re.compile(r'(?P<server>.*?):(?P<port>.*?) (?P<ip>.*?) (?P<remote_log_name>.*?) (?P<userid>.*?) \[(?P<date>.*?)\] \"(?P<request>.*?)\" (?P<status>.*?) (?P<length>.*?) \"(?P<referer>.*?)\" \"(?P<useragent>.*?)\"') with open("access.log") as f: for l in enumerate(f): d = next(r.finditer(l)).groupdict() d['url'] = d['request'].split()[1] if ' ' in d['request'] else '-' # d['date'] = datetime.datetime.strptime(d['date'], '%d/%b/%Y:%H:%M:%S %z').isoformat() # optional~ 0,01 ms por línea en mi portátil i5.