Pull to refresh

Comments 23

Т.е. вы предлагаете на каждый syslog-пакет форкать внешний обработчик? Хлипковато как-то выглядит.
В смысле что у меня несколько гигабайт логов в день копятся, там сообщений мнооого…
Самое смешное то, что он не просто форкается и что-то шлет, он еще дергает Zabbix-API на каждый пакет.
При нормальной нагрузке это отличный способ убить сервер Заббикса.
Хотя, при нормальной нагрузке хранить сообщения в Postgres/MySQL базе Zabbix это уже плохая идея.

Если бы эта статья была не в блоге компании Zabbix, я бы посоветовал автору не мучаться, и использовать Graylog2/Logstash + Elasticsearch.
Да, все верно насчет форка, zabbix_sender'а, конечно это не лучший вариант с точки зрения производительности, и в какой-то момент может забуксовать.
В других случаях — это возможность работать с логами в той же консоли, где и остальной мониторинг (если используется Zabbix)
Zabbix API дергается только в случае нового хоста, а в других случаях берется их кэша.
Zabbix API используется только в том случае, если узел сети не кеширован. В любом случае повторное использование session id избавило бы от необходимости постоянно авторизоваться.
Конечно, тут есть что оптимизировать. Лучшим вариантом было бы накапливать данные и отправлять их одним махом на Zabbix сервер используя прямое TCP соединение без участия zabbix_sender.
Именно это и позволяет делать zbxlog — www.alixen.org/projects/zbxlog
Никаких форков — получил с сети syslog по UDP отправил заббикс серверу правильный пакет по TCP.

Данные о связках IP<->hostname он берет напрямую из БД и к тому же, насколько я помню, кеширует.
Обсуждение в www.zabbix.com/forum/showthread.php?t=19180
Представил себе это в нашей сети с сотнями сетевых железок и серверов… Ужаснулся.
Тут впору собирать под Zabbix кластер на блейд-серверах и бездонное хранилище впридачу =)
Бездонное хранилище не нужно. Достаточно ограничить время хранение логов в заббиксе в элементе данных чтобы срезать неактуальное.
Описанный вариант используется на инсталляции в 500 хостов в течение двух лет без каких либо проблем. Сервер стоит на IBM x3250M3 + два заббикс прокси на порезанных по памяти виртуалках.
Ну, у нас сильно больше 500 хостов.
А какая версия Zabbix у вас используется, и какая база данных? Partitioning используете?
Zabbix 2.4 + MySQL, Partitioning да, настроено.
«Срезать неактуальное» через время хранения в элементе данных возможно, только если включен housekeeper. На больших объёмах данных его рекомендуют выключать, поэтому эти логи у вас будут занимать место до тех пор, пока жива соответствующая партиция таблицы history_log. Как вариант, конечно, можно уменьшить время хранения партиций для history_log, оставив остальные таблицы как есть.
К слову:
У функций log, logrt есть параметр «output»:
log[«file»,«regexp»,«encoding»,«maxlines»,«mode»,«output»]
logrt[file_regexp,«regexp»,«encoding»,«maxlines»,«mode»,«output»]

У очень похожей функции eventlog данного параметра нет:
eventlog[name,«regexp»,«severity»,«source»,«eventid»,«maxlines»,«mode»]

Это очень затрудняет аккуратную настройку мониторинга виндового эвентлога. Подозреваю, что прикрутить к ней «output» совсем несложно, при наличии его уже реализованного в log, logrt.

Пытался поднять тему на форуме — www.zabbix.com/forum/showthread.php?t=48191. Тишина…
Вроде все нормально!
конечно у себя такое внедрять не буду, уж очень много данных и не все нужные.
Но хотел бы сделать пару замечаний.
1. писать скрипт не perl и потом из него дергать zabbix_sender, мне кажется не совсем правильным.
В свое время на просторах интернета нашел вот такое

sub zabbix_send{
        my $zabbixserver = "";
        my $hostname = "";
        my $item = "";
        my $data = "";
        ($zabbixserver,$hostname,$item,$data) = @_;
        my $timeout=10;
        my $result;

        my $request=sprintf("<req>\n<host>%s</host>\n<key>%s</key>\n<data>%s</data>\n</req>\n",encode_base64($hostname),encode_base64($item),encode_base64($data));

        my $sock = new IO::Socket::INET ( PeerAddr => $zabbixserver, PeerPort => '10051', Proto => 'tcp', Timeout => $timeout);
        die "Could not create socket: $!\n" unless $sock;
        $sock->send($request);
        my @handles=IO::Select->new($sock)->can_read($timeout);
#       print "item - $item, data - $data\n";
        if (scalar(@handles) > 0)
        {
         $sock->recv($result,1024);
#        print "answer from zabbix server $zabbixserver: $result\n";
        }
#       else
#       {
#        print "no answer from zabbix server\n";
#       }
        $sock->close();
}


использовать как
zabbix_send $zabbixserver, $hostname, $key, $value;


2. Хочется все таки более гибкого скрипта. Что бы при новой инсталляции не лезть в нутрь и править параметры. в своих скриптах использовал такую конструкцию
my $_hostname;
my $zabbix_conf = "/etc/zabbix/zabbix_agentd.conf";
my $zabbixhostnameitem;

open my $FH, $zabbix_conf or die "Cannot open file $zabbix_conf ($!)";
while(<$FH>){
        if(/^Hostname=(.*)$/){
                $_hostname = $1;
        }
        if(/^HostnameItem=system.hostname$/){
                $zabbixhostnameitem = hostname();
        }
}
close $FH;

if(defined($zabbixhostnameitem) and !defined($_hostname)){
        $_hostname = $zabbixhostnameitem;
}


Конечно это при условии что установлен zabbix_agent и настроен, конечно здесь только имя хоста определяется, но думаю мысль понятна.

Спасибо большое за важное дополнение! Протестировал и добавил функцию zabbix_send для отсылки через socket в скрипт. В статью тоже внес эти поправки.
Теперь /usr/bin/zabbix_sender не используется.

От конфига, к сожалению, труднее отказаться, так как там прописаны логин/пароль для API, которых нет в конфиге zabbix_agent…
Сегодня столкнулся с тем что надо было используя zabbix_sender послать не только данные но и время в которое были данные получены. Скрипт обработчик был написан на perl, поэтому использовал функцию. Ну и как положено она не заработала после небольшого дополнения.
В итоге после прочтения документации www.zabbix.org/wiki/Docs/protocols/zabbix_sender/2.0
Функция приняла такой вид
sub zabbix_send{
        my ($zabbixserver,$hostname,$item,$data, $timestamp) = @_;
        my $timeout=10;
        my $result;

        my $request = '{"request":"sender data","data":[{"value":"' . $data . '","host":"' . $hostname . '","key":"' . $item . '"';
        $request .= ',"clock":"' . $timestamp . '"' if defined $timestamp;
        $request .= '}]}';

        my $sock = new IO::Socket::INET ( PeerAddr => $zabbixserver, PeerPort => '10051', Proto => 'tcp', Timeout => $timeout);
        die "Could not create socket: $!\n" unless $sock;
        $sock->send($request);
        my @handles=IO::Select->new($sock)->can_read($timeout);
        if (scalar(@handles) > 0){
                $sock->recv($result,1024);
        }
        $sock->close();
}
Ребят, помогите переделать конфиг для syslog-ng, что-то навык слабоват.
Настроил сам:
template t_msgfmt {
    template("${ISODATE} [${HOST}] ${FACILITY} ${MSGHDR}${MSG}\n");
    #template_escape(no);
};

source s_udp {
        udp();
};

filter f_remote {
        host("192.168.0.*") or host("192.168.1.*");
};

destination df_remote {
        file("/var/log/hosts/$HOST-$LEVEL.log" template(t_msgfmt));
};

destination df_prog {
        #file("/var/log/hosts/$HOST-$LEVEL.log" template(t_msgfmt));
        program("/usr/lib/zabbix/externalscripts/zabbix_syslog_lkp_host.pl" template(t_msgfmt));
};


log {
        #file(t_msgfmt);
        source(s_udp);
        #filter(f_remote);
        destination(df_prog);
};

Осталось одно но — если выбрать назначением файл — прекрасно собирает логи, а если выбрать скрипт — то логи не пишутся в заббиксе, однако, если выполнить скрипт с параметром строки лога через shell, то в заббиксе данные появятся на нужном узле.

То есть скрипт работает, не работает лишь через syslog-ng.

Помогите?
вроде нет
root@zabbix:~# sestatus
The program 'sestatus' is currently not installed. You can install it by typing:
apt-get install policycoreutils
root@zabbix:~# cat /etc/sysconfig/selinux
cat: /etc/sysconfig/selinux: No such file or directory
Хотел еще добавить: если если подменить в скрипте
my $message = shift @ARGV   || die

на
my $message = "test [192.168.250.5]"   || die

То в заббиксе на узле 192.168.250.5 начинают появляться записи test [192.168.250.5]. Выходит, скрипт отрабатывает через syslog-ng, но не может получить строку лога как аргумент, либо не может его обработать?

Я к сожалению не специалист по Perl, очень трудно понять — почему так. Начитался всякого про буферизацию, пробовал методы отключения, но безуспешно.
Добавлю свои 5 копеек. Для проверки скрипта выполнял в CLI сервера что-то вроде
/usr/local/bin/zabbix_syslog_lkp_host.pl "asdsdasd [10.169.2.6] sadasd "


Первоначально была ошибка «Could not create socket: Connection refused». Добавил в /etc/hosts запись с hostname в строку 127.0.0.1 и ::1.

Спасибо, решение работает с zabbix 3.2.
Only those users with full accounts are able to leave comments. Log in, please.