import collections
# Константы
BLACKLIST_IPS = {"85.234.12.1"}
def parse_log_line(line: str) -> dict:
"""Извлекает данные из строки лога и возвращает словарь."""
parts = line.split()
if len(parts) < 8:
return None
try:
# Извлекаем и очищаем данные
ip = parts[0]
user = parts[2] if parts[2] != "-" else None
# Метод: берем 4-й элемент, убираем лишние кавычки
method = parts[4].replace('"', '')
path = parts[5]
# Преобразование статус-кода с защитой от ошибок
status_code = int(parts[-1])
return {
"ip": ip,
"user": user,
"method": method,
"path": path,
"status_code": status_code
}
except (ValueError, IndexError):
return None
def is_suspicious(log_dict: dict, blacklist: set) -> bool:
"""Проверяет запись на подозрительную активность."""
if log_dict["ip"] in blacklist:
return True
if log_dict["status_code"] in [401, 403]:
return True
if log_dict["path"].startswith("/admin"):
return True
return False
def count_failed_logins(logs_list: list) -> dict:
"""Считает количество ошибок 401 для каждого IP."""
failed_counts = {}
for log in logs_list:
if log["status_code"] == 401:
ip = log["ip"]
failed_counts[ip] = failed_counts.get(ip, 0) + 1
return failed_counts
def get_most_frequent_path(logs_list: list) -> str:
"""Находит самый популярный URL-путь."""
paths = [log["path"] for log in logs_list]
if not paths:
return None
# Используем Counter для удобного подсчета
return collections.Counter(paths).most_common(1)[0][0]
def main():
all_logs = []
# 1. Чтение и парсинг файла
with open("network_log.txt", "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
parsed_data = parse_log_line(line)
if parsed_data:
all_logs.append(parsed_data)
else:
continue
# Тестирование парсинга первой строки (из этапа 1 задания)
if all_logs:
print("--- Тест парсинга первой строки ---")
print(all_logs[0])
print("-" * 35)
# 2. Формирование отчета о подозрительной активности
with open("suspicious_report.txt", "w", encoding="utf-8") as report:
for log in all_logs:
if is_suspicious(log, BLACKLIST_IPS):
report_line = f"[ВНИМАНИЕ] IP: {log['ip']} | Путь: {log['path']} | Код: {log['status_code']}\n"
report.write(report_line)
# 3. Вывод статистики в консоль
failed_logins = count_failed_logins(all_logs)
for ip, count in failed_logins.items():
print(f"IP {ip}: {count} неудачных попыток входа")
most_popular = get_most_frequent_path(all_logs)
print(f"\nСамый популярный путь: {most_popular}")
if __name__ == "__main__":
main()