Анализатор логов Apache своими руками и в одну строчку

О невероятной силе командной строки пост.

Мне приходится поддерживать работоспособность некоторых сайтов и одной из ключевых процедур в этом деле является выявление паразитного трафика и борьба с ним. Почти все CMS позволяют зафиксировать аномальные перегрузки и вычислить их источник. Иногда приходится делать хитрые запросы к СУБД. Но в сложных ситуациях приходится опускаться по уровням абстракции еще ниже и «листать» системные журналы web-сервера. Недавно как раз столкнулся с таким случаем.

Задача: есть журнал access.log размером около 300 Мб. Требуется быстро вычислить первую десятку IP, с которых поступило больше всего запросов.

Решение: поставить анализатор логов типа Webalizer или Awstat.

Так я и собирался поступить, но для этих систем сбора статистики требуется настраивать сервер, в них регулярно находят дырки, замедляется работа всего компа. Самое главное, посмотреть статистику требуется только 1 раз и ставить тяжелые пакеты для обработки и визуализации логов не хотелось.

Тогда я решил, что проще и быстрее написать свой скрипт. Я лучше всего знаю Ruby, поэтому его и решил использовать. Алгоритм:

  • читаем весь лог в память;
  • разбиваем по строкам;
  • каждую строку разбиваем на подстроки по регулярному выражению;
  • каждый IP (первый столбец каждой строки) является ключом хеша и значение увеличивается на 1 при каждом вхождении IP;
  • сортируем хэш по убыванию ключа;
  • печатаем первую десятку;
  • PROFIT!

Кинулся писать и почти сразу же вспомнил о команде cut. Можно же вычленить IP из всего лога одной командой. Записываю для интереса:

cat $1 | cut -d " " -f 1

Сразу приходит мысль: надо отсортировать, чтобы одинаковые IP шли друг за другом:

cat $1 | cut -d " " -f 1 | sort

Теперь самое время вспомнить о команде uniq. С помощью man освежаем в памяти детали и вспоминаем любопытную опцию -с, позволяющую не только оставить уникальные IP, но и подсчитать количество повторов:

cat $1 | cut -d " " -f 1 | sort | uniq -c

Получаем две колонки: в первой количество запросов с одного IP, в другой — сам IP. Но есть два минуса. Данные отсортированы по IP, а не по количеству повторов. Во-вторых, данных очень много, десятки тысяч строк и все вперемежку. Самое время снова применить sort. Надо лишь заставить sort воспринимать первый столбец как числа и сортировать в обратном порядке. Оказывается, и такие опции предусмотрены: -n и -r.

cat $1 | cut -d " " -f 1 | sort | uniq -c | sort -n -r

Отлично, но данных слишком много, а нам надо только первые 10. Тут даже домохозяйки и приравненные к ним пользователи Ubuntu вспомнят о существовании команды head. Добавляем и ее в общий конвейер и получаем окончательный вариант:

cat $1 | cut -d " " -f 1 | sort | uniq -c | sort -n -r | head -n 10

Получаем именно то, что нужно, причем без всякого стороннего софта и программирования. Данный пример раскрывает одно из самых сильных преимуществ интерфейса командной строки.

А что дальше?

Дальше комбинируем с командами mail и whois, добавляем скрипт в cron и начинаем получать каждодневные отчеты в удобной форме на email. Никогда еще банить малолетних каккеров не было так приятно. ;)

Ваша оценка: Нет Средняя оценка: 4 (4 votes)
11
pomodor

Можно было бы, конечно, сразу передавать IP в iptables, если количество повторов превышает заданный уровень, но так можно случайно забанить поисковых ботов.

Ваша оценка: Нет Средняя оценка: 4 (4 votes)
Отправить комментарий
КАПЧА
Вы человек? Подсказка: зарегистрируйтесь, чтобы этот вопрос больше никогда не возникал. Кстати, анонимные ссылки запрещены.
CAPTCHA на основе изображений
Enter the characters shown in the image.
Linux I класса
Linux II класса
Linux III класса
Счетчики
  • Самый популярный сайт о Linux и Windows 10
О Либератуме

Liberatum — это новости мира дистрибутивов Linux, обзоры, сборки, блоги, а также лучший сайт об Ubuntu*.