Поднялся у меня тут вопрос как логи с Mikrotik'а обрабатывать в FreeBSD... (Цель-сбор статистики по трафику, и по тому куда ходили через web-proxy)
Настроил я микротик чтобы он у меня логи писал в "remote"...
Syslogd логи принимает скидывает в файл всё ОК... и тут начинаются проблемы...
хочу разобрать эти логи и запихнуть, например, в MySQL... Подготовил соответствующую базу,
начал мастерить скрипт на shell... сделал скрипт:
Код: Выделить всё
#!/bin/sh
# Вводим данные для подключения к MySQL серверу
# IP адрес MySQL сервера
MySQLServer="localhost"
# Имя пользователя для доступа к БД в которой храниться траффик
username="traf"
# Пароль пользователя MySQL
user_passw="traf"
# Имя базы данных
db_name="traflog"
# поехали
# Сегодяшний день
day="`date +%Y-%m-%d`"
# Текущий год
year="`date +%Y`"
# Текущий месяц
month="`date +%m`"
# Местоположение исполняемого файла клиента MySQL
mysql="/usr/local/bin/mysql"
# Префикс для команд (лень же каждый раз набивать параметры подключения)
sql_preffix="${mysql} --host=${MySQLServer} --user=${username} --password=${user_passw} --database=${db_name}"
# Построчно превращаем файл со статистикой в набор переменных
grep "firewall" /tmp/pl_traf.log |
{
while read stroka
do
# Берем время из лога.
logtime=`echo "${stroka}" | awk '{print $3}'`
# Кусок строки лога которую нужно разбирать
logline=`echo "${stroka}" | awk '{split($0,a,": "); print a[3]}'`
# Вытягиваем сведения о протоколе
protocol=`echo "${logline}" | awk '{split($0,a,", "); if (substr(a[2],1,5)=="proto") print a[2]; else print a[3] }' | awk '{print $2}'`
# Вытягиваем подстроку типа 'адрес:порт->адрес:порт' ....
tmpline=`echo "${logline}" | awk '{split($0,a,", "); if (substr(a[2],1,5)=="proto") print a[3]; else print a[4] }'`
# .... и разбираем её на части ....
src_ip=`echo "${tmpline}" | awk '{split($0,a,"->"); split(a[1],b,":"); print b[1] }'`
src_port=`echo "${tmpline}" | awk '{split($0,a,"->"); split(a[1],b,":"); print b[2] }'`
dst_ip=`echo "${tmpline}" | awk '{split($0,a,"->"); split(a[2],b,":"); print b[1] }'`
dst_port=`echo "${tmpline}" | awk '{split($0,a,"->"); split(a[2],b,":"); print b[2] }'`
# Вытягиваем данные о колличестве отправленых/полученых байт
count=`echo "${logline}" | awk '{split($0,a,", "); if (substr(a[2],1,5)=="proto") print a[4]; else print a[5] }' | awk '{print $2}'`
# Загоняем полученный набор во временную таблицу
${sql_preffix} --execute="INSERT INTO \`$db_table\` (\`date\`, \`time\`, \`src_ip\`, \`src_port\`, \`dst_ip\`, \`dst_port\`, \`proto\`, \`count\`) \
values ('${day}', '${logtime}', '${src_ip}', '${src_port}', '${dst_ip}', '${dst_port}', '${protocol}', '${count}')"
done
}
# Очищаем файл c логами о том когда и по какому интерфейсу сохранялась статистика
cat /dev/null > /tmp/pl_traf.log
сразу хочу заметить что исходные логи несколько не пропорциональны... обычным awk, с лету, и не пропарсишь...
Вот, к примеру:
Код: Выделить всё
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: input: in:wan out:(none), src-mac 00:20:8f:0a:34:2a, proto 47, 62.5.223.2->81.195.131.123, len 91
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: forward: in:PPTP_FreeBSD out:lan, proto TCP (ACK,PSH), 192.168.23.205:3389->192.168.25.22:1030, len 55
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: forward: in:PPTP_FreeBSD out:lan, proto TCP (ACK,PSH), 192.168.23.205:3389->192.168.25.22:1030, len 55
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: forward: in:lan out:PPTP_FreeBSD, src-mac 00:14:d1:4b:43:58, proto TCP (ACK), 192.168.25.22:1030->192.168.23.205:3389, len 20
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: input: in:wan out:(none), src-mac 00:20:8f:0a:34:2a, proto 47, 62.5.223.2->81.195.131.123, len 12
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: input: in:wan out:(none), src-mac 00:20:8f:0a:34:2a, proto 47, 62.5.223.2->81.195.131.123, len 12
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: output: in:(none) out:lan, proto TCP (ACK), 192.168.25.1:8080->192.168.25.14:1038, len 20
Sep 23 16:42:32 192.168.23.6 firewall,info vlfw_: input: in:wan out:(none), src-mac 00:20:8f:0a:34:2a, proto TCP (ACK), 195.93.180.35:80->192.168.25.1:38398, len 32
скрипт работает, только НАСТОЛЬКО ДОЛГО.... мрак... скорость заполнения файла лога порядка 6000-7000 строк в минуту...
а скрипт обрабатывает около 1300 строк за 5 мин...
есть ли шансы как-нибудь ускорить этот процесс, может есть уже готовые решения?....
могу предположить что настолько долгое выполнение связано с постоянными запросами в БД и слишком навороченным методом разбора строки... но увы, что есть...
