Несколько скриптов для анализа логов Apache: различия между версиями
Rain (обсуждение | вклад) (Новая страница: «Ниже приводятся несколько скриптов, написанных для удобства быстрого анализа логов Apache …») |
|||
Строка 1: | Строка 1: | ||
Ниже приводятся несколько скриптов, написанных для удобства быстрого анализа логов Apache / Nginx (combined-формат логов) на предмет аномального пика активности или для поиска наиболее активных IP-адресов за промежуток времени. | Ниже приводятся несколько скриптов, написанных для удобства быстрого анализа логов Apache / Nginx (combined-формат логов) на предмет аномального пика активности или для поиска наиболее активных IP-адресов за промежуток времени. | ||
Скрипты | Скрипты написаны преимущественно с использованием mawk, поэтому он должен быть установлен в системе. Возможен вариант с использованием GNU awk, но он в разы более медленный. Кроме того, при необходимости используются параллельные версии декомпрессоров для GZ и BZ2 - pigz и pbzip2. | ||
== Скрипт 1 == | == Скрипт 1 == |
Текущая версия на 12:49, 16 августа 2012
Ниже приводятся несколько скриптов, написанных для удобства быстрого анализа логов Apache / Nginx (combined-формат логов) на предмет аномального пика активности или для поиска наиболее активных IP-адресов за промежуток времени.
Скрипты написаны преимущественно с использованием mawk, поэтому он должен быть установлен в системе. Возможен вариант с использованием GNU awk, но он в разы более медленный. Кроме того, при необходимости используются параллельные версии декомпрессоров для GZ и BZ2 - pigz и pbzip2.
Скрипт 1
Скрипт оформлен в виде функции. Использование:
apache_logstat file [h|m|s] [num]
где
- file
- путь к access_log-файлу, может быть plaintext'ом, в формате gzip или bzip2.
- [h|m|s]
- необязательный второй параметр, указывающий подробность отчета: h - почасово, m (дефолтный) - поминутно и s - посекундно
- num
- необязательный третий параметр (подразумевается, что при его наличии указан и 2-й параметр), указывающий, сколько запросов будет обозначено одним символьным блоком. Дефолтно для минутного разрешения используется 100 запросов на блок, для часового - 10000, для секундного - 5 запросов.
Пример работы скрипта:
# apache_logstat access.log h 2000 15/Aug/2012:03 R:1825 # 15/Aug/2012:04 R:2822 ## 15/Aug/2012:05 R:2668 ## 15/Aug/2012:06 R:5465 ### 15/Aug/2012:07 R:42915 ###################### 15/Aug/2012:08 R:30243 ################ 15/Aug/2012:09 R:18967 ########## 15/Aug/2012:10 R:15394 ######## 15/Aug/2012:11 R:14113 ######## 15/Aug/2012:12 R:11908 ###### 15/Aug/2012:13 R:11242 ###### 15/Aug/2012:14 R:6436 #### 15/Aug/2012:15 R:6234 ####
Код:
apache_logstat() {
[ -z "${1}" ] && echo -e "Usage: apache_logstat file [h|m|s] [num]\n\tfile - Apache common log file\n\tm|s - resolution in minutes or seconds\n\tnum - request count in block" || {
[ -z "${2}" ] && r='m' || r="${2}"
type="$(file "${1}" | grep -oE 'gzip|bzip')"
case "${type}" in
gzip) cmd='unpigz -c'
;;
bzip)
cmd='pbunzip2 -c'
;;
*)
cmd='cat'
;;
esac
$cmd "${1}" | mawk '
{
if ("'$r'"=="m") gsub(/:[0-9]+$/, "", $4)
if ("'$r'"=="h") gsub(/:[0-9]+:[0-9]+$/, "", $4)
a[$4]++
}
END {
for (i in a) {
j=i
gsub(/^\[/, "", i)
if ("'$3'"=="") {
if ("'$r'"=="m") b="100"
else if ("'$r'"=="h") b="10000"
else b="5"
}
else b="'$3'"
printf "%-30s", i"\tR:"a[j]
for (k=0; k<a[j]; k+=b) printf "%s", "#"
print ""
}
}' | sort
}
}
Скрипт 2
Данный скрипт показывает число запросов в минуту с одного IP-адреса с сортировкой по минутам. При обработке исключаются обращения с localhost и запрос jpg/jpeg-картинок. Параметр 1 - plaintext-файл лога; при необходимости можно добавить блок кода автоопределения передаваемого файла или архива по типу приведенного в первом скрипте.
Пример работы:
$ apache_ip_logstat access_log 48 188.26.24.214 2012/08/15 21:56 14 190.235.179.226 2012/08/15 21:57 19 95.25.19.190 2012/08/15 21:57 59 188.26.24.214 2012/08/15 21:57 20 95.27.72.24 2012/08/15 22:04 19 77.232.158.58 2012/08/15 22:13 32 178.168.30.155 2012/08/15 22:15
Код:
apache_ip_logstat() {
mawk '
! /127.0.0.1/ && ! /localhost/ && ! /.jpg / && ! /.jpeg/{
sub(/Jan/, "01", $4)
sub(/Feb/, "02", $4)
sub(/Mar/, "03", $4)
sub(/Apr/, "04", $4)
sub(/May/, "05", $4)
sub(/Jun/, "06", $4)
sub(/Jul/, "07", $4)
sub(/Aug/, "08", $4)
sub(/Sep/, "09", $4)
sub(/Oct/, "10", $4)
sub(/Nov/, "11", $4)
sub(/Dec/, "12", $4)
gsub(/:[0-9][0-9]$|^\[/, "", $4)
d[$1" "$4]++
}
END {
for (b in d) {
split(b, c)
split(c[2], e, "/")
split(e[3], f, ":")
if (d[b]>10) print d[b]"\t"c[1]"\t"f[1]""e[2]""e[1]""f[2]""f[3]
}
}' "${1}" | sort -nk3 | sed -r 's@([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$@\1/\2/\3 \4:\5@g'
}