Анализатор логов 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 (4 оценки)

Комментарии

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

Оценка: 
Средняя: 4 (4 оценки)

Комментировать

Filtered HTML

  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.
  • Доступны HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <strike> <code> <h2> <h3> <h4> <h5> <del> <img>
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.