#!/usr/bin/python3 # из черновиков анализатора, для тестов норм, в норм виде на гитхабе пока не выложено, выдает только кортежи из рефереров print('1') name = 'iisus' version = '0.3-dev' description = 'Analyzer of web server standard access logs' # number of lines for each report, from 0 to None out_num = None # percent rounding r = 4 import sys import os import socket from urllib import parse from collections import Counter sys.argv.append('/home/user/python/NEW2/log-333-3') filename = str(sys.argv[1]) # получаем список строк with open(filename) as file: log_string_list = file.readlines() print('2') # создание списка таймзон tz_list = [] for i in range(len(log_string_list)): try: tz_list.append(log_string_list[i].split('"')[0].split(' ')[4][:-1]) except Exception: pass # печать часового пояса try: tz = Counter(tz_list).most_common()[0][0] print('Time zone in most lines: ' + 'UTC' + tz[0:3] + ':' + tz[3:5] + ' (' + str(len(tz_list)) + '/' + str(len(log_string_list)) + ')') except Exception: pass tz_list = None print('3') # число пустых строк строк в списке empty_lines_number = log_string_list.count('\n') # удаление пустых строк while True: try: log_string_list.remove('\n') except ValueError: break month_dict = { 'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06', 'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12' } # функция превращения списка строк в двухмерный список юнитов def log_string_processor(log_string): try: d = log_string.split('"')[0].split(' ')[3][1:] date = d[9:11] + month_dict[d[3:6]] + d[0:2] + d[12:14] + d[15:17] + d[18:20] date_min = date[:10] date_hour = date[:8] date_day = date[:6] date_month = date[:4] date_year = date[:2] date_hour_common = date[6:8] ip = log_string.split('"')[0].split(' ')[0] host = log_string.split('"')[0].split(' ')[1] status_code = log_string.split('"')[2].split(' ')[1] content_length = log_string.split('"')[2].split(' ')[2] r = log_string.split('"')[1].split(' ') request = r[0] + ' ' + r[1] request_method = r[0] referer = log_string.split('"')[3] user_agent = log_string.split('"')[5] except Exception: pass try: return [ date,#############0 date_min,#########1 date_hour,########2 date_day,#########3 date_month,#######4 date_year,########5 date_hour_common,#6 ip,###############7 host,#############8 status_code,######9 content_length,##10 request,#########11 request_method,##12 referer,#########13 user_agent]######14 except Exception: pass # получение двухмерного списка юнитов proc_list = [] for log_string in log_string_list: proc_list.append(log_string_processor(log_string)) log_string_list = None print('4') # число нестандартных строк логфайла, которые не удалось корректно обработать nonstandard_lines_number = proc_list.count(None) # удаление None из списка юнитов while True: try: proc_list.remove(None) except ValueError: break # общее число запросов, соответствующее длине двухмерного списка юнитов len_log = len(proc_list) print('5') # список, состоящий из списков юнитов одного типа # например, nonuniq_list[14] - список всех юзерагентов из всех запросов nonuniq_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]] for x in range(15): for i in range(len(proc_list)): nonuniq_list[x].append(proc_list[i][x]) # список, состоящих из списков уникальных юнитов одного типа # например, len(uniq_list[14][0]) - число уникальных юзерагентов uniq_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]] for i in range(15): uniq_list[i].append(list(set(nonuniq_list[i]))) print('6') # получаем список списков таплов, содежащих юниты и число запросов с ними sorted_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]] for i in range(15): sorted_list[i].append(Counter(nonuniq_list[i]).most_common(out_num)) print('7') # функция первода числа байт в человекочитаемый вид def human(num): b = str(num) c = len(b) if 1 <= c <= 3: h = b + ' B' elif 4 <= c <= 6: h = str(round(num / 1024, 2)) + ' KiB' elif 7 <= c <= 9: h = str(round(num / (1024 ** 2), 2)) + ' MiB' elif 10 <= c <= 12: h = str(round(num / (1024 ** 3), 2)) + ' GiB' else: h = str(round(num / (1024 ** 4), 2)) + ' TiB' return h # возвращает в человекочитаемом виде общую длину контента, принимает список длин контента def len_sum(len_list): summa = 0 for i in len_list: if i == '-': continue summa += int(i) return human(summa) # возвращает ip и hostname def ip_host(ip): try: ip = '{}{}({})'.format(ip, ' ' * (16 - len(ip)), socket.gethostbyaddr(ip)[0]) except Exception: pass return ip # печать общих топов по типам юнитов def top_printer(unit_num): # итерация по таплу for tuple in sorted_list[unit_num][0]: i = list(tuple) # i[0] - юнит одного типа # i[1] - число запросов по юниту percent = str(round(i[1] / len_log * 100, r)) space_abs = ' ' * (len(str(len_log)) - len(str(i[1]))) space_pro = ' ' * (2 - len(str(percent.split('.')[0]))) print('{}{}/{} : {}{}% : {}'.format(space_abs, i[1], len_log, space_pro, percent, parse.unquote(i[0]))) # визуализация почасового числа запросов def requests_by_hour(): x = sorted(uniq_list[2][0]) element = '+' max_number_of_elements = 20 for i in x: print('20{}-{}-{} {}'.format(i[:2], i[2:4], i[4:6], i[6:8]), element * round(nonuniq_list[2].count(i) / sorted_list[2][0][0][1] * max_number_of_elements)) referer_list = nonuniq_list[13] search_template_list = ['?q=', '&q=', '?query=', '?search=', '?text=', 'search?p='] search_query_list = [] search_template = search_template_list[1] for referer in referer_list: if search_template in referer: ref_splited = referer.split(search_template) right_one = ref_splited[1] if '&' not in right_one: search_query = right_one else: search_query = right_one.split('&')[0] search_query_list.append(parse.unquote(search_query).replace('+', ' ')) print('8') # print(search_query_list) search_query_counted = Counter(search_query_list).most_common() print('9') for i in search_query_counted: print(i) print('10')