Часто возникает ситуация, когда надо быстро оценить, чем занимается ваш веб-сервер. Иногда для успокоения «вроде не он». Когда на сервере один апач, один сайт, нагрузка небольшая — проблем нет. Зашел, top посмотрел. /server-status посмотрел, tail -f на логи сделал, помедитировал — и обычно всё понятно. Однако бывает ситуация, когда сайтов много, много самих apache (почти все ОС сейчас из коробки умеют подымать несколько веб-серверов apache, но этим редко пользуются почему-то). Бывает ситуация, когда apache уже и ответить не может. Как было бы хорошо, хотя бы примерно прикинуть, что делают (или уже делали) воркеры апача. Представьте — делаете вы ps -aux, а у вас там — кто какие URL запрашивает, какой ширины канал занят, какова скорость работы — ня!
Я достаточно давно использую патч для apache, который после разбора строки запроса пишет в имя программы IP, откуда был запрос, то, что пришло в заголовке Host и саму строку запроса. Но этот двухстрочный патч был написан 12 лет назад для Apache версии 1.3. А потом руки не доходили. Тем более, с того времени появилось множество (я за пять минут нашел как минимум два) разновидностей модулей для тех целей, для более новых версий Apache. Однако, со временем мне стало маловато просто строк запросов. И… я написал свой модуль.
Доктор, откуда у Вас такие картинки?
Вначале я намучился с отсутствием документации для разработчиков у Apache. Нужные hook'и пришлось искать методом перечитывания всего исходного кода. Не, когда вы уже 10-ой модуль пишете, оно может и отлично, а когда первый и может быть последний — проблема.
Когда мне удалось найти хук ap_hook_monitor(), который вызывается из рутового процесса apache каждые 20 запросов или каждую 1 секунду, мною овладела жажда запихать в строку как можно больше крутой статистики. Я пробовал всякие статусы, количества, загрузку за 10 секунд, 1 минуту, 5 минут, аптайм… Но посмотрев на результат, я понял, что эта мишура только мешает и оставил только битрейт и запросы в секунду.
Самым главным новшеством модуля являются значения Complete и Incomplete Listen Queue Lenght. Это когда в httpd.conf пишем BackLog чтототам, то запросы, которые сервер не успевает принять, копятся в этой очереди. А когда очередь заполняется — начинают отбрасываться. Обычно такое происходит при хабраэффекте например, или если сайт обращается к стороннему ресурсу, а тот «лежит» или заблокирован (как например недавно github). И вот тут нашему глазу очень поможе цифра в listen queue и цифра qps.
Как всё плохо в этих ваших линуксах
Внезапно оказалось, что малыми жертвами модуль можно написать только под FreeBSD. Для изменения имени программы там есть функция setproctitle(), а посмотреть Complete и Incomplete Listen Queue Lenght можно через вызов getsockopt() с параметром SO_LISTENQLEN и SO_LISTENINCQLEN.
Для Linux всё сложнее. Требуется взять имя исполняемого файла и отдельно всегда его дописывать (FreeBSD делает это автоматически). Это нужно помому, что подавляющее большинство rc-скриптов используют имя, которое светится в ps в целях запуска/перезапуска.
Для Linux оказалось непросто и значения Listen Queue найти. Пока что мне видится вариант работы с netlink(7). Но детали ускользают.
Вливайся
Для FreeBSD + Apache 2.4 модуль абсолютно работоспособен. Можно попробовать его на других версиях Apache. Можно и нужно помочь портировать его на Linux.
Модуль распространяется в исходных кодах и вы можете сделать с ним всё, что захотите:
github.com/schors/mod_proctitle
P.S. Некстати, хочу дополнить его функцией периодического сброса статистики по UDP куда-нибудь. Чуть более полной.
Автор: schors