forked from loweel/zabov
96 lines
3.8 KiB
Python
96 lines
3.8 KiB
Python
|
#!/bin/env python3
|
||
|
|
||
|
import os
|
||
|
import glob
|
||
|
import argparse
|
||
|
|
||
|
|
||
|
parser = argparse.ArgumentParser(description='Zabov logs analyzer')
|
||
|
|
||
|
parser.add_argument('--ip', dest="ip", metavar='IP', type=str,
|
||
|
help='filter by source IP (substring to match). Default: any')
|
||
|
|
||
|
parser.add_argument('--action', dest="action", metavar='action', type=str, default="killed",
|
||
|
help='filter action (substring to match): killed|forwarded|any. Default: killed')
|
||
|
|
||
|
parser.add_argument('--config', dest="config", metavar='name', type=str,
|
||
|
help='filter by config name (substring to match). Default: any')
|
||
|
|
||
|
parser.add_argument('--timetable', dest="timetable", metavar='name', type=str,
|
||
|
help='filter by timetable name (substring to match). Default: any')
|
||
|
|
||
|
parser.add_argument('--reqtype', dest="reqtype", metavar='TypeA', type=str, default="TypeA",
|
||
|
help='filter by reqtype name (substring to match): TypeA|TypeAAAA|TypeMX|...')
|
||
|
|
||
|
parser.add_argument('--domain', dest="domain", metavar='name', type=str,
|
||
|
help='filter by domain name (substring to match). Default: all')
|
||
|
|
||
|
parser.add_argument('--min-entries', dest="minentries", metavar='100', type=int, default=0,
|
||
|
help='filter output by minimum number of entries. Default: any')
|
||
|
|
||
|
parser.add_argument('--logs-path', dest="logs", metavar='path', type=str, default="./config/logs",
|
||
|
help='Zabov logs path')
|
||
|
|
||
|
|
||
|
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
|
||
|
timetables = {}
|
||
|
configs = {}
|
||
|
|
||
|
killed = {}
|
||
|
for x in glob.glob(os.path.join(args.logs, "*.log")):
|
||
|
#print (x)
|
||
|
f = open(x, "r")
|
||
|
f.readline()
|
||
|
if args.reqtype:
|
||
|
args.reqtype = args.reqtype.lower()
|
||
|
if args.domain:
|
||
|
args.domain = args.domain.lower()
|
||
|
|
||
|
for line in f.readlines():
|
||
|
linel = line.strip().lower()
|
||
|
fields = linel.split("\t")
|
||
|
|
||
|
timetables[fields[5]] = timetables.get(fields[5], 0) +1
|
||
|
configs[fields[4]] = configs.get(fields[4], 0) +1
|
||
|
|
||
|
ok = all((not args.action or fields[6].find(args.action)>=0 or fields[6] == "any", \
|
||
|
not args.timetable or fields[5].find(args.timetable)>=0 or fields[5] == "any", \
|
||
|
not args.config or fields[4].find(args.config)>=0 or fields[4] == "any", \
|
||
|
not args.ip or fields[1].find(args.ip)>=0 or fields[1] == "any",\
|
||
|
not args.domain or fields[2].find(args.domain)>=0 or fields[2] == "any", \
|
||
|
not args.reqtype or fields[3].find(args.reqtype)>=0 ))
|
||
|
if ok:
|
||
|
killed[fields[2]] = killed.get(fields[2], 0) +1
|
||
|
|
||
|
killed_sorted = {key: value for key, value in sorted(killed.items(), key=lambda item: item[1], reverse=True)}
|
||
|
|
||
|
total_queries_filtered = 0
|
||
|
total_domain_filtered = 0
|
||
|
total_queries = 0
|
||
|
for k in killed_sorted.keys():
|
||
|
if args.minentries == 0 or killed[k] >= args.minentries:
|
||
|
print (k, killed[k])
|
||
|
total_queries_filtered += killed[k]
|
||
|
total_domain_filtered+=1
|
||
|
total_queries += killed[k]
|
||
|
|
||
|
print("")
|
||
|
print("TOTAL domains (filtered):", total_domain_filtered )
|
||
|
print("TOTAL queries (filtred):", total_queries_filtered )
|
||
|
print("TOTAL domains:", len(killed_sorted.keys()) )
|
||
|
print("TOTAL queries:", total_queries )
|
||
|
|
||
|
|
||
|
timetables = {key: value for key, value in sorted(timetables.items(), key=lambda item: item[0], reverse=False)}
|
||
|
configs = {key: value for key, value in sorted(configs.items(), key=lambda item: item[0], reverse=False)}
|
||
|
|
||
|
print("all available timetables:")
|
||
|
for k in timetables.keys():
|
||
|
print(" '%s': %d items" % (k, timetables[k], ))
|
||
|
print("all available configs:")
|
||
|
for k in configs.keys():
|
||
|
print(" '%s': %d items" % (k, configs[k], ))
|