Источник:
В файлах журнала (логах) сервера записаны все запросы к серверу. Расположение и содержание файла определяются директивой CustomLog. Конечно, сохранение информации в access log — это только начало работы с логами. Следующий шаг — это анализ информации для формирования полезной статистики.
Анализ файлов журнала Apache
Принцип использования awk — это разбиение каждой строки файла на «поля» или «колонки», используя заданный разделитель. Поскольку каждая строка файла основываентся на стандартном формате, мы можем очень легко выполнить много разных вещей.
Используя разделитель по умолчанию, которым является белый пробел (пробел или табуляция) мы получаем следующее:
Теперь, когда вы понимаете основы разбора лог файлов и идентификации различных элементов, мы можем перейти к более практичным примерам. Но перед тем как сделать это, мы должны объяснить, как вы можете модифицировать формат ваших логов и быстро расширить возможности этих простых примеров.
Уже видели статью «Распространённые сниппеты .htaccess»?
Форматом аргумента директив LogFormat и CustomLog является строка. Эта строка используется для каждой записи в лог файла журнала. Она может содержать буквальные символы, копируемые в лог файлы, и управляющие символы в стиле C — “n” и “t”, обозначающие новую строку и табуляцию. Буквальные кавычки и обратные слеши должны быть экранированы.
Значения, которые мы хотим видеть в логах, заменяются символами, которым предшествует знак процента “%”. Далее дано описание формата строки, которая задаёт содержимое логов:
%%
Знак процента
%a
Удалённый IP-адрес
%A
Локальный IP-адрес
%B
Размер запроса в байтах, не включая HTTP заголовки.
%b
Размер запроса в байтах, не включая HTTP заголовки. В формате CLF format, например ‘-‘ вместо 0 когда байты не отправлены.
%{Foobar}C
Содержание кукиз Foobar в запросе, посланном серверу. Полностью поддерживается только версия кукиз 0.
%D
Время, затраченное на запрос, в миллисекундах
%{FOOBAR}e
Содержание переменной окружения FOOBAR
%f
Имя файла
%h
Удалённый хост
%H
Протокол запроса
%{Foobar}i
Содержимое Foobar: строки (строк) заголовка в отправленном на сервер запросе. Изменения, сделанные модулями (например, mod_headers) влияют на него. Если вам интересно, что в заголовке запроса было до того как большинство модулей модифицировали его, используйте mod_setenvif для копирования заголовка в переменную внутреннего окружения и записывайте эту величину в файл журнала с помощью %{VARNAME}, которая описана выше.
%k
Количество keepalive запросов, обрабатывающихся на этом соединении. Интересно, что если KeepAlive используется, то тогда, например, ‘1’ означает первый запрос keepalive первый запрос keepalive после исходного запроса, ‘2’ — второй и т.д….; в противном случае он всегда равен 0 (показывает на начальный запрос). Доступ в версии 2.2.11 и более поздних
%l
Удалить logname (из identd, если они присланы). Будет возвращено тире, если mod_ident отсутствует или IdentityCheck не установлена на On.
%m
Метод запроса
%{Foobar}n
Содержание заметки Foobar от другого модуля.
%{Foobar}o
Содержание Foobar: строка (строки) заголовка в ответе.
%p
Канонический порт по которому сервер обрабатывает запросы
%{format}p
Канонический порт по которому сервер обрабатывает запросы или действительный порт сервера или действительный порт клиента. Валидные форматы: канонический, локальный или удалённый.
%P
ID дочернего процесса, который обслуживает запрос.
%{format}P
ID дочернего процесса или id дочернего потока, который обслуживает запрос. Валидные форматы: pid, tid и hextid. hextid требует APR 1.2.0 или выше.
%q
Строка запроса (предваряется ? если строка запроса существует, в противном случае, пустая строка)
%r
Первая строка запроса
%R
Обработчик генерации ответа (если таковые имеются).
%s
Статус. Для запросов, которые получили внутреннюю переадресацию, это статус опционального запроса — %>s для последнего.
%t
Время получения запроса (стандартный английский формат)
%{format}t
Время в форме, которая задана форматом, который должен быть в расширенном формате strftime(3) (потенциально локализованном). Если формат начинается с начала: (по умолчанию) время в начале процесса запроса. Если начинается с конца: это время, когда сделана запись в файл журнала, оно близко к окончанию процесса запроса. В дополнение к форматам, поддерживаемыми trftime(3), поддерживаются следующие форматы маркеров:
sec
количество секунд начиная с Эпохи Linux
msec
количество миллисекунд начиная с Эпохи Linux
usec
количество микросекунд начиная с Эпохи Linux
msec_frac
миллисекундная доля
usec_frac
микросекундная доля
Эти маркеры не могут быть объединены друг с другом или форматированием strftime(3) в одной и той же форматированной строке. Вместо них вы можете использовать маркер %{format}t. Расширенный маркер strftime(3) доступен в 2.2.30 и более поздних.
%T
Время, затраченное на обслуживание запроса в секундах.
%{UNIT}T
Время затраченное на обработку запроса, в единицу времени, заданной в UNIT. Валидные юниты: ms в качестве миллисекунд, us для микросекунд, и s для секунд. Использование s даёт тот же результат, что и %T без какого-либо формата; использование us даёт тот же результат, что и %D. Комбинирование %T с юнитом доступно в 2.2.30 и более поздних версиях.
%u
Удалённый пользовать (значение получается от процесса авторизации; оно может быть поддельным, если возвращён статус (%s) 401).
%U
Запрошенный путь URL без включения каких-либо строк запросов.
%v
Каноническое ServerName сервера обслуживающего запросы.
%V
Имя сервера в соответствии с настройкой UseCanonicalName.
%X
Статус соединения, когда ответ завершён.
X =
соединение прервано до окончания ответа.
+ =
соединение может быть сохранено alive после отправки ответа.
– =
соединение будет закрыты после отправки ответа.
(Эта директива была в %c в давних версиях Apache 1.3, но это конфликтовало с исторически сложившемся C-синтаксисом ssl %{var}).
%I
Байт получена, включая запрос и заголовки, не может быть нулём. Вам нужно включить mod_logio для использования этого.
%O
Байт отправлено, включая заголовки, не может быть нулём. Вам нужно включить mod_logio для использования этого.
%{VARNAME}^ti
Содержание VARNAME: трейлер строки (строк) в отправленном на сервер запросе.
%{VARNAME}^to
Содержимое VARNAME: трейлер строки (строк) в ответе отправленном с сервера.
Список всех пользовательских агентов, отсортированных по количеству раз, которое они появлялись
Выявляем проблемы с вашим сайтом
Выявляем проблемы с вашим сайтом анализом различных ответов сервера и запросов, которые вызвали их:
Вывод показывает как много типов запросов получил ваш сайт. «Нормальный» результат запроса — это код 200, который означает, что страница или файл были запрошены и доставлены. Но возможны и многие другие варианты.
Наиболее распространённые ответы:
200 – OK
206 – Partial Content (частичное содержимое)
301 – Moved Permanently (перемещено навсегда)
302 – Found (найдено)
304 – Not Modified (не изменилось)
401 – Unauthorised (password required) (не авторизованы — требуется пароль)
403 – Forbidden (запрещено)
404 – Not Found (не найдено)
Что является причиной ошибок 404?
Ошибка 404 говорит об отсутствующем ресурсе. Посмотрите на запрашиваемые URI, которые получили эту ошибку.
Запрос на ответ 404
Уникальные IP сделавшие запрос:
Уникальные IP сделавшие запрос — резолвим (определяем) страну:
Нам нужно:
Кто вставляет мои изображения на своём сайте (делает хотлинг)?
Что-то, что по настоящему раздражает некоторых людей, это когда их полоса пропускания используется для вставки их изображений напрямую на чужой веб-сайт.
Пустой пользовательский агент
«Пустой» пользовательский агент обычно говорит о том, что запрос исходит от автоматического скрипта или от кого-то, кто действительно ценит свою конфиденциальность. Следующая команда выдаст список ip адресов для этих пользовательских агентов и уже на основе него вы сможете решить, что с ними делать дальше — блокировать или пусть заходят:
Слишком большая нагрузка из одного источника?
Когда ваш сайт находится под тяжёлой нагрузкой, вам следует разобраться, нагрузка исходит от реальных пользователей или от чего-нибудь ещё:
10 самых активных IP:
Трафик в килобайтах по кодам статуса:
10 самых популярных рефереров:
10 самых популярных пользовательских агентов
Насколько это просто? Пользовательские агенты — это шестая колонка вместо четвёртой и нам не нужно искать по регулярным выражениям, поэтому их не нужно объяснять:
Генерируем список, который показывает последние 10,000 хитов на сайт.
Запросы за день:
Запросы за час:
Запросы за минуту:
Всего уникальных посетителей:
Уникальные посетители сегодня:
Уникальные посетители в этом месяце:
Уникальные посетители на произвольную дату:
Уникальные посетители за месяц:
Отсортированная статистика по “количеству посетителей/запросов” “IP адреса посетителей”:
Наиболее популярные URL:
Запросы в реальном времени:
Резолвим IP адреса в реальном времени:
Уникальные IP адреса:
Уникальные IP адреса с отметкой даты-времени:
Уникальные IP адреса и браузеры:
Уникальные IP адреса и ОС:
Уникальные IP адреса, дата-время и метод запроса:
Уникальные IP адреса, дата-время и запрошенный URL:
Ссылка скрыта от гостей
В файлах журнала (логах) сервера записаны все запросы к серверу. Расположение и содержание файла определяются директивой CustomLog. Конечно, сохранение информации в access log — это только начало работы с логами. Следующий шаг — это анализ информации для формирования полезной статистики.
Анализ файлов журнала Apache
Принцип использования awk — это разбиение каждой строки файла на «поля» или «колонки», используя заданный разделитель. Поскольку каждая строка файла основываентся на стандартном формате, мы можем очень легко выполнить много разных вещей.
Используя разделитель по умолчанию, которым является белый пробел (пробел или табуляция) мы получаем следующее:
Код:
awk ‘{print $1}’ access.log # ip адрес (%h)
awk ‘{print $2}’ access.log # RFC 1413 identity (%l)
awk ‘{print $3}’ access.log # userid (%u)
awk ‘{print $4,5}’ access.log # дата/время (%t)
awk ‘{print $9}’ access.log # код статуса (%>s)
awk ‘{print $10}’ access.log # размер (%b)
awk -F” ‘{print $2}’ access.log # запрашиваемая строка (%r)
awk -F” ‘{print $4}’ access.log # referer (источник)
awk -F” ‘{print $6}’ access.log # пользовательский агент
Теперь, когда вы понимаете основы разбора лог файлов и идентификации различных элементов, мы можем перейти к более практичным примерам. Но перед тем как сделать это, мы должны объяснить, как вы можете модифицировать формат ваших логов и быстро расширить возможности этих простых примеров.
Уже видели статью «Распространённые сниппеты .htaccess»?
Форматом аргумента директив LogFormat и CustomLog является строка. Эта строка используется для каждой записи в лог файла журнала. Она может содержать буквальные символы, копируемые в лог файлы, и управляющие символы в стиле C — “n” и “t”, обозначающие новую строку и табуляцию. Буквальные кавычки и обратные слеши должны быть экранированы.
Значения, которые мы хотим видеть в логах, заменяются символами, которым предшествует знак процента “%”. Далее дано описание формата строки, которая задаёт содержимое логов:
%%
Знак процента
%a
Удалённый IP-адрес
%A
Локальный IP-адрес
%B
Размер запроса в байтах, не включая HTTP заголовки.
%b
Размер запроса в байтах, не включая HTTP заголовки. В формате CLF format, например ‘-‘ вместо 0 когда байты не отправлены.
%{Foobar}C
Содержание кукиз Foobar в запросе, посланном серверу. Полностью поддерживается только версия кукиз 0.
%D
Время, затраченное на запрос, в миллисекундах
%{FOOBAR}e
Содержание переменной окружения FOOBAR
%f
Имя файла
%h
Удалённый хост
%H
Протокол запроса
%{Foobar}i
Содержимое Foobar: строки (строк) заголовка в отправленном на сервер запросе. Изменения, сделанные модулями (например, mod_headers) влияют на него. Если вам интересно, что в заголовке запроса было до того как большинство модулей модифицировали его, используйте mod_setenvif для копирования заголовка в переменную внутреннего окружения и записывайте эту величину в файл журнала с помощью %{VARNAME}, которая описана выше.
%k
Количество keepalive запросов, обрабатывающихся на этом соединении. Интересно, что если KeepAlive используется, то тогда, например, ‘1’ означает первый запрос keepalive первый запрос keepalive после исходного запроса, ‘2’ — второй и т.д….; в противном случае он всегда равен 0 (показывает на начальный запрос). Доступ в версии 2.2.11 и более поздних
%l
Удалить logname (из identd, если они присланы). Будет возвращено тире, если mod_ident отсутствует или IdentityCheck не установлена на On.
%m
Метод запроса
%{Foobar}n
Содержание заметки Foobar от другого модуля.
%{Foobar}o
Содержание Foobar: строка (строки) заголовка в ответе.
%p
Канонический порт по которому сервер обрабатывает запросы
%{format}p
Канонический порт по которому сервер обрабатывает запросы или действительный порт сервера или действительный порт клиента. Валидные форматы: канонический, локальный или удалённый.
%P
ID дочернего процесса, который обслуживает запрос.
%{format}P
ID дочернего процесса или id дочернего потока, который обслуживает запрос. Валидные форматы: pid, tid и hextid. hextid требует APR 1.2.0 или выше.
%q
Строка запроса (предваряется ? если строка запроса существует, в противном случае, пустая строка)
%r
Первая строка запроса
%R
Обработчик генерации ответа (если таковые имеются).
%s
Статус. Для запросов, которые получили внутреннюю переадресацию, это статус опционального запроса — %>s для последнего.
%t
Время получения запроса (стандартный английский формат)
%{format}t
Время в форме, которая задана форматом, который должен быть в расширенном формате strftime(3) (потенциально локализованном). Если формат начинается с начала: (по умолчанию) время в начале процесса запроса. Если начинается с конца: это время, когда сделана запись в файл журнала, оно близко к окончанию процесса запроса. В дополнение к форматам, поддерживаемыми trftime(3), поддерживаются следующие форматы маркеров:
sec
количество секунд начиная с Эпохи Linux
msec
количество миллисекунд начиная с Эпохи Linux
usec
количество микросекунд начиная с Эпохи Linux
msec_frac
миллисекундная доля
usec_frac
микросекундная доля
Эти маркеры не могут быть объединены друг с другом или форматированием strftime(3) в одной и той же форматированной строке. Вместо них вы можете использовать маркер %{format}t. Расширенный маркер strftime(3) доступен в 2.2.30 и более поздних.
%T
Время, затраченное на обслуживание запроса в секундах.
%{UNIT}T
Время затраченное на обработку запроса, в единицу времени, заданной в UNIT. Валидные юниты: ms в качестве миллисекунд, us для микросекунд, и s для секунд. Использование s даёт тот же результат, что и %T без какого-либо формата; использование us даёт тот же результат, что и %D. Комбинирование %T с юнитом доступно в 2.2.30 и более поздних версиях.
%u
Удалённый пользовать (значение получается от процесса авторизации; оно может быть поддельным, если возвращён статус (%s) 401).
%U
Запрошенный путь URL без включения каких-либо строк запросов.
%v
Каноническое ServerName сервера обслуживающего запросы.
%V
Имя сервера в соответствии с настройкой UseCanonicalName.
%X
Статус соединения, когда ответ завершён.
X =
соединение прервано до окончания ответа.
+ =
соединение может быть сохранено alive после отправки ответа.
– =
соединение будет закрыты после отправки ответа.
(Эта директива была в %c в давних версиях Apache 1.3, но это конфликтовало с исторически сложившемся C-синтаксисом ssl %{var}).
%I
Байт получена, включая запрос и заголовки, не может быть нулём. Вам нужно включить mod_logio для использования этого.
%O
Байт отправлено, включая заголовки, не может быть нулём. Вам нужно включить mod_logio для использования этого.
%{VARNAME}^ti
Содержание VARNAME: трейлер строки (строк) в отправленном на сервер запросе.
%{VARNAME}^to
Содержимое VARNAME: трейлер строки (строк) в ответе отправленном с сервера.
Список всех пользовательских агентов, отсортированных по количеству раз, которое они появлялись
Код:
awk -F" '{print $6}' access.log | sort | uniq -c | sort -fr
Выявляем проблемы с вашим сайтом
Выявляем проблемы с вашим сайтом анализом различных ответов сервера и запросов, которые вызвали их:
Код:
awk '{print $9}' access.log | sort | uniq -c | sort
Вывод показывает как много типов запросов получил ваш сайт. «Нормальный» результат запроса — это код 200, который означает, что страница или файл были запрошены и доставлены. Но возможны и многие другие варианты.
Наиболее распространённые ответы:
200 – OK
206 – Partial Content (частичное содержимое)
301 – Moved Permanently (перемещено навсегда)
302 – Found (найдено)
304 – Not Modified (не изменилось)
401 – Unauthorised (password required) (не авторизованы — требуется пароль)
403 – Forbidden (запрещено)
404 – Not Found (не найдено)
Ссылка скрыта от гостей
.Что является причиной ошибок 404?
Ошибка 404 говорит об отсутствующем ресурсе. Посмотрите на запрашиваемые URI, которые получили эту ошибку.
Код:
$ grep " 404 " access.log | cut -d ' ' -f 7 | sort | uniq -c | sort -nr
Запрос на ответ 404
Код:
$ cat access.log | awk '($9 ~ /404/)' | awk '{ print $7 }' | sort | uniq -c | sort -rn | head -n 25
Уникальные IP сделавшие запрос:
Код:
$ cat access.log | awk '{ print $1 }' | sort | uniq -c | sort -rn | head -n 25
Уникальные IP сделавшие запрос — резолвим (определяем) страну:
Нам нужно:
Код:
apt-get install geoip-bin geoip-database-extra
$ cat access.log | awk '{ print $1 }' | sort | uniq -c | sort -rn | head -n 25 | awk '{ printf("%5dt%-15st", $1, $2); system("geoiplookup " $2 " | cut -d \: -f2 ") }'
Кто вставляет мои изображения на своём сайте (делает хотлинг)?
Что-то, что по настоящему раздражает некоторых людей, это когда их полоса пропускания используется для вставки их изображений напрямую на чужой веб-сайт.
Код:
awk -F" '($2 ~ /.(jpg|gif)/ && $4 !~ /^http://www.codeby.net/blogs/){print $4}' access.log | sort | uniq -c | sort
Пустой пользовательский агент
«Пустой» пользовательский агент обычно говорит о том, что запрос исходит от автоматического скрипта или от кого-то, кто действительно ценит свою конфиденциальность. Следующая команда выдаст список ip адресов для этих пользовательских агентов и уже на основе него вы сможете решить, что с ними делать дальше — блокировать или пусть заходят:
Код:
awk -F" '($6 ~ /^-?$/)' access.log | awk '{print $1}' | sort | uniq
Когда ваш сайт находится под тяжёлой нагрузкой, вам следует разобраться, нагрузка исходит от реальных пользователей или от чего-нибудь ещё:
- Проблем в настройке или в системе
- Пользовательское приложение или бот запрашивает информацию с вашего сайта слишком быстро
- Атака отказ-в-обслуживании
Код:
cat access.log | cut -d ' ' -f 1 | sort | uniq -c | sort -nr
10 самых активных IP:
Код:
cat access.log | awk '{ print $1 ; }' | sort | uniq -c | sort -n -r | head -n 10
Трафик в килобайтах по кодам статуса:
Код:
cat access.log | awk ' { total[$9] += $10 } END { for (x in total) { printf "Status code %3d : %9.2f Kbn", x, total[x]/1024 } } '
10 самых популярных рефереров:
Код:
cat access.log | awk -F" ' { print $4 } ' | grep -v '-' | grep -v 'https://codeby.net' | sort | uniq -c | sort -rn | head -n 10
10 самых популярных пользовательских агентов
Насколько это просто? Пользовательские агенты — это шестая колонка вместо четвёртой и нам не нужно искать по регулярным выражениям, поэтому их не нужно объяснять:
Код:
cat access.log | awk -F" ' { print $6 } ' | sort | uniq -c | sort -rn | head -n 10
Генерируем список, который показывает последние 10,000 хитов на сайт.
Код:
tail -10000 access.log| awk '{print $1}' | sort | uniq -c |sort -n
Запросы за день:
Код:
awk '{print $4}' access.log | cut -d: -f1 | uniq -c
Запросы за час:
Код:
grep "29/Jul" access.log | cut -d[ -f2 | cut -d] -f1 | awk -F: '{print $2":00"}' | sort -n | uniq -c
Запросы за минуту:
Код:
grep "29/Jul/2015:06" access.log | cut -d[ -f2 | cut -d] -f1 | awk -F: '{print $2":"$3}' | sort -nk1 -nk2 | uniq -c | awk '{ if ($1 > 10) print $0}'
Всего уникальных посетителей:
Код:
cat access.log | awk '{print $1}' | sort | uniq -c | wc -l
Уникальные посетители сегодня:
Код:
cat access.log | grep `date '+%e/%b/%G'` | awk '{print $1}' | sort | uniq -c | wc -l
Уникальные посетители в этом месяце:
Код:
cat access.* | grep `date '+%b/%G'` | awk '{print $1}' | sort | uniq -c | wc -l
Уникальные посетители на произвольную дату:
Код:
cat access.* | grep 28/Jul/2015 | awk '{print $1}' | sort | uniq -c | wc -l
Уникальные посетители за месяц:
Код:
cat access.* | grep Jun/2015 | awk '{print $1}' | sort | uniq -c | wc -l
Отсортированная статистика по “количеству посетителей/запросов” “IP адреса посетителей”:
Код:
cat access.log | awk '{print "requests from " $1}' | sort | uniq -c | sort
Наиболее популярные URL:
Код:
$ cat access.log | awk '{ print $7 }' | sort | uniq -c | sort -rn | head -n 25
Запросы в реальном времени:
Код:
$ tailf access.log | awk '{ printf("%-15st%st%st%sn", $1, $6, $9, $7) }'
Резолвим IP адреса в реальном времени:
Код:
$ tailf access.log | awk '{ "geoiplookup " $1 " | cut -d \: -f2 " | getline geo printf("%-15st%st%st%-20st%sn", $1, $6, $9, geo, $7); }'
Уникальные IP адреса:
Код:
cat access.log | awk '{print $1}' | sort | uniq
Уникальные IP адреса с отметкой даты-времени:
Код:
cat access.log | awk '{print $1 " " $4}' | sort | uniq
Уникальные IP адреса и браузеры:
Код:
cat access.log | awk '{print $1 " " $12 " " $19}' | sort | uniq
Уникальные IP адреса и ОС:
Код:
cat access.log | awk '{print $1 " " $13}' | sort | uniq
Уникальные IP адреса, дата-время и метод запроса:
Код:
cat access.log | awk '{print $1 " " $4 " " $6}' | sort | uniq
Уникальные IP адреса, дата-время и запрошенный URL:
Код:
cat access.log | awk '{print $1 " " $4 " " $7}' | sort | uniq
Последнее редактирование: