Bash → sams+локальные домены
Sams представляет из себя хороший анализатор логов squid, но в текущей стабильной версии есть некоторая недоработка — нормально не работает список локальных доменов. Тоесть можно, конечно, забить в него список подсетей, по которым не нужно вести подсчет трафика, и поставить галочку «преобразовывать днс имена», но после этого он начинает работать весьма нестабильно. Так как «с/c++» програмист из меня никакой, то для решения данной проблемы родилась следующая связка bash скриптов. Это первая более-менее «нормально» работающая версия.
Скрипты нужно запускать в последний день месяца. Смысл работы в том, что делается выборка из всех урлов, по которым был совершен переход за месяц — проверка их на принадлежность к сети, по которой не нужно считать трафик, составления из них нового списка локальных доменов и персчет статистики за текущий месяц.
Первый скирпт делает выборку, проверку, составляет новый список локальных доменов и очищает статистику за текущий месяц.
Скрипт urls
Задача следующего скрипта — сливать все логи сквида за текущий месяц в один лог (оформлено с учетом ротации логов в CentOS, тоесть хранить 5 последних, ротация раз в неделю)
Скрипт logaccess
И управляющий скрипт, который все это дело запускает (для CentOS)
Все скрипты должны лежать в одной папке, в ней же должна быть подпапка tmp и лежать файл subnet_addres, где в двоичном виде записаны подсети, по которым трафик считать не следует, а через слеш — маска подсети (используется для проверки урла на принадлежность локальным доменам, сделано для того чтобы не переводить каждый раз в двоичный вид; долго — bash все-таки;)
*Этот список для нижегородского адс
subnet_addres
Также со скриптами должен лежать файл ixnet, в котором записано то же самое, только в нормальном виде (список пересоздается по-новой, полностью сети добавляются на случай — если кто-нибудь будет использовать ip вместо доменного имени).
ixnet
Доступ к mysql базе осуществляеться через .my.cnf
Что касается времени работы — то скрипт urls у меня отрабатывает примерно час: идет обработка всех уникальных урлов за месяц, минус yandex и прочее, что точно не входит в нижегородское кольцо; всего обрабатывается порядка 8000-12000 доменов.
Остальное зависит от мощности вашего компьютера)
PS: на кроссплатформенность не тестировалось.
Скрипты нужно запускать в последний день месяца. Смысл работы в том, что делается выборка из всех урлов, по которым был совершен переход за месяц — проверка их на принадлежность к сети, по которой не нужно считать трафик, составления из них нового списка локальных доменов и персчет статистики за текущий месяц.
Первый скирпт делает выборку, проверку, составляет новый список локальных доменов и очищает статистику за текущий месяц.
Скрипт urls
#!/bin/bash
#Берем данные с базы за текущий месяц
start_date="`date +%Y`-`date +%m`-01"
#Последняя дата месяца
#end_date="`date +%Y`-`date +%m`-`cal|xargs|awk '{print $NF}'`"
end_date="`date +%Y-%m-%d`"
#нужно инициализировать для возврата из функции больших значений
bin=
home="/root/test"
cd $home
rm -f tmp/*
#Функция для перевода десятичных чисел в двоичный вид
dec_bin(){
bin=
for i in 1 2 3 4
do
octet="`echo $1|cut -d. -f$i`"
bin_oc="`echo "obase=2;$octet" |bc`"
n="${#bin_oc}"
if [ "$n" != 8 ]
then
while [ "${#bin_oc}" -lt 8 ]
do
bin_oc='0'${bin_oc}
done
fi
bin=${bin}${bin_oc}
done
}
#Функция для определения принадлежности ip-адреса внутренней сети
localdomain(){
for url in $1;
do
ip_addr="`host -t a $url|grep "\([0-9]\{1,3\}\.\)\{3\}"|cut -d' ' -f4|tail -n1`"
if [ -z "$ip_addr" ]
then
continue
fi
dec_bin "$ip_addr"
bin_ip_addr=$bin
cat subnet_addres | while read subnet
do
bin_net_addr="`echo $subnet|cut -d/ -f1`"
mask="`echo $subnet|cut -d/ -f2`"
if [ "`echo $bin_ip_addr|cut -c1-$mask`" = "`echo $bin_net_addr|cut -c1-$mask`" ]
then
echo $url>>$2
fi
done
done
}
start(){
MYSQL_RESULT=`mysql -sse "select substring_index(trim(leading \"ftp://\" from trim(leading \"http://\" from substring_index(url,'/',3))),':',1) as norm_url from cache where date between '$start_date' and '$end_date' group by norm_url"|grep -E -v "([0-9]{1,3}.){3}|yandex.(ru|net)|mail.ru|rambler.ru|vkontakte.ru|narod.ru|list.ru|odnokla(ss|s)niki.ru|google.(com|ru)|imageshack.us|yahoo.com|eset.com|spylog.com|googlevideo.com|youtube.com|vkadre.ru"|cut -d'@' -f2`
localdomain "$MYSQL_RESULT" "tmp/ixnn"
}
new_local(){
mysql -sse "select url from urls where type = \"local\"" --database=squidctrl|grep -v "\([0-9]\{1,3\}\.\)\{3\}"|sort>tmp/loc_old
cat tmp/ixnn|sort>tmp/ixnn_sort
new="`comm -13 tmp/ixnn_sort tmp/loc_old`"
localdomain "$new" "tmp/ixnn_old"
cat ixnet tmp/ixnn >tmp/local
cat tmp/ixnn_old|grep -E -v "^nnov.ru|^nn.ru|^$">>tmp/local
mysql -sse "delete from urls where type = \"local\"" --database=squidctrl
cat tmp/local|while read locurl
do
mysql -sse "INSERT INTO urls SET url=\"$locurl\",type=\"local\"" --database=squidctrl
done
}
clear_table(){
mysql -sse "DELETE FROM cache WHERE date between \"$start_date\" and \"$end_date\""
mysql -sse "DELETE FROM cachesum WHERE date between \"$start_date\" and \"$end_date\""
mysql -sse "OPTIMIZE TABLE cache"
mysql -sse "OPTIMIZE TABLE cachesum"
#Эти mysql запросы делают тоже самое что и sams -c
# mysql -sse "update squidusers SET size=\"0\"" --database=squidctrl
# mysql -sse "update squidusers SET hit=\"0\"" --database=squidctrl
# mysql -sse "update squidusers SET enabled=\"1\" where enabled=\"0\"" --database=squidctrl
sams -c
mysql -sse "update sams SET endvalue=\"0\"" --database=squidctrl
}
start
new_local
clear_table
Задача следующего скрипта — сливать все логи сквида за текущий месяц в один лог (оформлено с учетом ротации логов в CentOS, тоесть хранить 5 последних, ротация раз в неделю)
Скрипт logaccess
#!/bin/bash
#Путь к папке с логами squid
squd_log="/var/log/squid"
month="`date +%m`"
home="/root/test"
rm -f $home/tmp/*
start_log(){
#первое число текущего месяца
ymd="`date +%Y%m01`"
start_date="`date +%s -d$ymd`"
#Общее число строк в файле access.log.* содержащем лог за первые числа месяца
n_end="`cat $1|wc -l`"
cat $1|cut -d. -f1|while read i
do
n=$((n+1))
if [ $start_date -le $i ]
then
count_strings=$((n_end-n+1))
tail -n$count_strings $1 >$home/tmp/access.log_month
break
fi
done
}
start(){
cd $squd_log
echo "`ls --full-time access.log*|awk '{print($6,$9)}'|tac`"|while read file
do
if [ "`echo $file|cut -d'-' -f2`" -ge "$month" ]
then
loggz="`echo $file|awk '{print($2)}'`"
log="`basename $loggz .gz`"
cp $loggz $home/tmp
if [ -f "$home/tmp/access.log_month" ]
then
gzip -dq $home/tmp/$loggz
cat $home/tmp/$log >> $home/tmp/access.log_month
else
gzip -dq $home/tmp/$loggz
start_log $home/tmp/$log
fi
fi
done
}
start
rm -f $squd_log/access.log
cp $home/tmp/access.log_month $squd_log/access.log
chown squid:squid $squd_log/access.log
И управляющий скрипт, который все это дело запускает (для CentOS)
#!/bin/bash
service squid stop
service sams stop
./urls
./logaccess
service squid start
service sams start
Все скрипты должны лежать в одной папке, в ней же должна быть подпапка tmp и лежать файл subnet_addres, где в двоичном виде записаны подсети, по которым трафик считать не следует, а через слеш — маска подсети (используется для проверки урла на принадлежность локальным доменам, сделано для того чтобы не переводить каждый раз в двоичный вид; долго — bash все-таки;)
*Этот список для нижегородского адс
subnet_addres
11000011011000100010000000000000/19
11010100010111001000000000000000/18
01011001101111010000000000000000/19
01011100111100100100000000000000/19
11000011011110101110000000000000/19
11000010101111101011000000000000/20
11000001011111010100011000000000/23
00111110110111000010000000000000/20
01001110001010001011100000000000/21
11011001000101110001000000000000/20
01010101100011110000000000000000/20
01011001000111001100011100000000/24
01011110000110010100111000000000/24
11010100010000110000000000000000/19
01011100111101101000000000000000/19
01010010110100000100000000000000/18
11010101101100010110000000000000/19
01011001011011010000000000000000/18
01001111011111100000000000000000/17
01011101011110001000000000000000/17
01011111001001010000000000000000/16
11010101101111101110000000000000/19
Также со скриптами должен лежать файл ixnet, в котором записано то же самое, только в нормальном виде (список пересоздается по-новой, полностью сети добавляются на случай — если кто-нибудь будет использовать ip вместо доменного имени).
ixnet
195.98.32.0/19
212.92.128.0/18
89.189.0.0/19
92.242.64.0/19
195.122.224.0/19
194.190.176.0/20
193.125.70.0/23
62.220.32.0/20
78.40.184.0/21
217.23.16.0/20
85.143.0.0/20
89.28.199.0/24
94.25.78.0/24
212.67.0.0/19
92.246.128.0/19
82.208.64.0/18
213.177.96.0/19
89.109.0.0/18
79.126.0.0/17
93.120.128.0/17
95.37.0.0/16
213.190.224.0/19
Доступ к mysql базе осуществляеться через .my.cnf
[client]
user = sams
password = пароль
#socket=/var/lib/mysql/mysql.sock
[mysql]
database = squidlog
Что касается времени работы — то скрипт urls у меня отрабатывает примерно час: идет обработка всех уникальных урлов за месяц, минус yandex и прочее, что точно не входит в нижегородское кольцо; всего обрабатывается порядка 8000-12000 доменов.
Остальное зависит от мощности вашего компьютера)
PS: на кроссплатформенность не тестировалось.
- +3
- CraDem
- 19 сентября 2009, 00:58
Комментарии (1)
- alexzulu
- 19 сентября 2009, 11:21
- #
- ↓
- -1
Может скажу немного не по теме, но правила русского языка ещё никто не отменял. Пожалуйста исправьте грамматические ошибки в статье.