Зручний моніторинг Syslog повідомлень c мережевих залозок у Zabbix

Невід'ємною частиною мережевого моніторингу є збір логів з контрольованих серверів та інших залозок. Адже скільки б ми не створили окремих елементів даних і тригерів до них, в якийсь момент виникне ситуація, що щось важливе ми випустили з уваги і не контролюємо. Підсумок: «У нас нічого не працює», а система моніторингу каже, що все добре.

Тому перше, що хотілося зробити — збирати всі логи в заббиксе, згрупувавши їх по вузлу мережі для того, щоб завжди можна було пробігтися за повідомленнями очима, не витрачаючи час на доступ на обладнання.
Другий — звернути увагу і на ті події, про які й не підозрюєш.

Як це зробити на серверах і комп'ютерах, де встановлено заббикс-агент, багато знають — є вбудовані елементи даних log[], logrt[].

Але як бути, коли треба збирати логи з мережевого обладнання, на яке ніяк не поставити Zabbix-agent? Взагалі-то можна, звичайно, налаштувати syslog-сервер на тому ж ПК, на якій є заббикс-агент, а далі за допомогою log[] переносити ці дані в заббикс. Ось тільки елементи даних і тригери з нього будуть прикріплені до вузла мережі з заббикс-агентом, що інтуїтивно малозрозуміло. А можна прикріпити ці дані безпосередньо до мережного пристрою? Можна.

Для цього нам знадобиться zabbix_sender, Zabbix API і rsyslog на машині з заббикс-сервером або заббикс-проксі. В якості бонусу також отримаємо швидкий контекстний перехід в журнал syslog-повідомлень з карти мережі.
Як буде виглядати результат? Ну, приблизно ось так:
Контекстний дзвінок:




How to
Великими мазками архітектура рішення виглядає ось так:

1. Всі логи з мережевих пристроїв падають на сервер з Zabbix або проксі сервером, на якому за сумісництвом розташований rsyslog.
2. rsyslog запускаємо скрипт, який визначає (3) з якого вузла мережі у Заббиксе прийшло повідомлення
4. Повідомлення йде в заббикс через утиліту zabbix_sender
Ну що, почнемо «прорубувати» шлях повідомленням від мережевої залізяки до заббикс

На мережевому обладнанні
Тут все просто. Вкажіть в якості адресата для syslog повідомлень машину з Zabbix-сервером або Zabbix-proxy. Налаштуйте обладнання на відсилання повідомлень будь-яких severity і facility.

На якомусь D-Link'e це може виглядати приблизно ось так:
enable syslog
create syslog host 1 ipaddress 10.2.0.21 severity debug state enable

А скажімо на Cisco роутері ось так:
cisco1#
cisco1#config terminal
Enter configuration commands, one per line. End with CNTL/Z.
cisco1(config)#logging 10.2.0.21
cisco1(config)#service timestamps debug datetime localtime show-timezone msec
cisco1(config)#service timestamps log datetime localtime show-timezone msec
cisco1(config)#logging facility local3
cisco1(config)#logging trap informational
cisco1(config)#end

Набудували? Йдемо далі.

У веб-інтерфейсі Заббикса
Почнемо з самого простого і зрозумілого. У Zabbix'e створимо шаблон Template_Syslog і додамо в ньому один єдиний елемент даних:


Заповнимо поля наступним чином:
Поле
Значення
Примітка
Ім'я Syslog
Тип Zabbix траппер
Ключ syslog Важливо, щоб було саме таке ім'я (для подальшої коректної роботи Zabbix API)
Тип інформації Журнал(лог)
Формат часу в журналі(балці) yyyyxMMxddxhhxmmxssxxxxxx Маска для правильного визначення дати за форматом в RFC5424


Далі прикріплюємо цей шаблон до усіх вузлів мережі, з яких будемо збирати syslog-повідомлення. Важливо в інтерфейсах вказати IP-адреси, з яких будуть приходити логи в Заббикс. Інакше просто не вийде ідентифікувати джерело повідомлення.


Syslog-сервер
Налаштуємо syslog-сервер на хості з Zabbix-сервером. У нашому випадку це поширений rsyslog, який йде у багатьох дистрибутивах Linux. Якщо у вас syslog-ng, то там все можна зробити практично так само.

У найпростішому випадку syslog сервер розкладає отримані повідомлення файлів в залежності від facility і severity повідомлень. Однак, є й інші можливості. Наприклад, в rsyslog існує можливість запуску довільного скрипта для кожного повідомлення. Цією функцією ми і скористаємося.
Друге питання, яке потрібно вирішити — ідентифікація обладнання, щоб визначити, в лог якогось вузла додавати повідомлення в Заббиксе. Його ми вирішимо, додавши в рядок з самим повідомленням ip-адреса джерела в квадратних скобах.

Для всього цього створимо конфіг-файл /etc/rsyslog.d/zabbix_rsyslog.conf
#add template for network devices
$template network-fmt,"%TIMESTAMP:::date-rfc3339% [%fromhost-ip%] %pri-text% %syslogtag%%msg%\n"

#exclude unwanted messages:
:msg, contains, "Child connection from ::ffff:10.2.0.21" ~
:msg, contains, "exit after auth (ubnt): Disconnect received" ~
:msg, contains, "password auth succeeded for 'ubnt' from ::ffff:10.2.0.21" ~
:msg, contains, "exit before auth: Exited normally" ~
#action for every message:
if $fromhost-ip != '127.0.0.1' then ^/usr/local/bin/zabbix_syslog_lkp_host.pl;network-fmt 
& ~

Ми тільки що створили налаштування для rsyslog, яка буде всі повідомлення отримані не з локального хоста форматувати певним чином і запускати наш скрипт /usr/local/bin/zabbix_syslog_lkp_host.pl з syslog-повідомленням в якості аргументу.

Заодно в розділі #exclude unwanted messages ми можемо відкидати засмічують логін повідомлення, якщо вони заздалегідь відомі. Пара повідомлень залишена тут в якості прикладу.

Під кінець налаштування rsyslog не забудьте ще розкоментувати наступні рядки у файлі /etc/rsyslog.conf для прийому Syslog-повідомлень по мережі через UDP.:
$ModLoad imudp
$UDPServerRun 514


І все ж, що робить скрипт /usr/local/bin/zabbix_syslog_lkp_host.pl, який ми вказали запускати rsyslog'? Якщо коротко, він просто через zabbix_sender шле повідомлення на Zabbix_server або на Zabbix_proxy, ну ось приблизно за таким шаблоном:
/usr/bin/zabbix_sender-z *ІМ'Я_СЕРВЕРА* -k syslog-o *SYSLOG-ПОВІДОМЛЕННЯ* -s *ИМЯУЗЛА*

Але звідки скрипту знати, яке буде *ИМЯУЗЛА* (тобто до якогось вузла кріпити повідомлення), адже відомий тільки IP-адресу, з якої прийшло повідомлення?
Для цього ми будемо використовувати Zabbix API, саме через нього ми і зможемо знайти *ИМЯУЗЛА* по IP-адресою.

/usr/local/bin/zabbix_syslog_lkp_host.pl
#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use JSON::RPC::Legacy::Client;
use Data::Dumper;
use Config::General;
use CHI;
use List::MoreUtils qw (any);
use English '-no_match_vars';
use Readonly;
our $VERSION = 1.1;

Readonly my $CACHE_TIMEOUT => 600;
Readonly my $CACHE_DIR => '/tmp/zabbix_syslog_cache';

my $conf = Config::General->new('/usr/local/etc/zabbix_syslog.cfg');
my %Config = $conf->getall;

#Authenticate yourself
my $client = JSON::RPC::Legacy::Client->new();
my $url = $Config{'url'} || die "URL is missing in zabbix_syslog.cfg\n";
my $user = $Config{'user'} || die "API user is missing in zabbix_syslog.cfg\n";
my $password = $Config{'password'} || die "API user password is missing in zabbix_syslog.cfg\n";
my $server = $Config{'server'} || die "server hostname is missing in zabbix_syslog.cfg\n";
my $zabbix_sender = $Config{'zabbix_sender'} || '/usr/local/bin/zabbix_sender';

die "Problems with zabbix_sender binary: $ERRNO\n"
unless-e-x $zabbix_sender; #check zabbix_sender exists and is executable

my $debug = $Config{'debug'};
my ( $authID, $response, $json );
my $id = 0;

my $message = shift @ARGV || die "Syslog message required as an argument\n"; #Grab syslog message from rsyslog

#get ip from message
my $ip;

#IP regex patter part
my $ipv4_octet = q/(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/;

if ( $message=~ / \[ ((?:$ipv4_octet[.]){3}${ipv4_octet}) \]/msx ) {
$ip = $1;
}
else {
die "No IP in square brackets found in '$message', cannot continue\n";
}

my $cache = CHI->new(
driver => 'File',
root_dir => $CACHE_DIR,
);

my $hostname = $cache->get($ip);

if ( !defined $hostname ) {

$authID = login();
my @hosts_found;
my $hostid;
foreach my $host ( hostinterface_get() ) {

$hostid = $host->{'hostid'};

if ( any { /$hostid/msx } @hosts_found ) {
next;
} #check if $hostid is already in array then skip(next)
else { push @hosts_found, $hostid; }

###########now get hostname
if ( get_zbx_trapper_syslogid_by_hostid($hostid) ) {

my $result = host_get($hostid);

#return hostname if possible
if ( $result->{'host'} ) {

if ( $result->{'proxy_hostid'} == 0 ) #check if host monitored directly or via proxy
{
#lease $server as is
}
else {
#assume that rsyslogd and zabbix_proxy are on the same server
$server = 'localhost';
}
$hostname = $result->{'host'};
}

}

}
logout);
$cache->set( $ip, $hostname, $CACHE_TIMEOUT );
}

system $zabbix_sender. '-z '
. $server
. '-k syslog-o \"
. $message
. '\' -s '
. $hostname; #run zabbix_sender

#______ SUBS
sub login {

$json = {
jsonrpc => '2.0',
method => 'user.login',
params => {
user => $user,
password => $password

},
id => $id++,
};

$response = $client->call( $url, $json );

# Check if response was successful
die "Authentication failed\n" unless $response->content->{'result'};

if ( $debug > 0 ) { print Dumper $response->content->{'result'}; }

return $response->content->{'result'};

}

sub logout {

$json = {
jsonrpc => '2.0',
method => 'user.logout',
params => {},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );

# Check if response was successful
warn "Logout failed\n" unless $response->content->{'result'};

return;
}

sub hostinterface_get {

$json = {

jsonrpc => '2.0',
method => 'hostinterface.get',
params => {
output => [ 'ip', 'hostid' ],
filter => { ip => $ip, },

# limit => 1,
},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );

if ( $debug > 0 ) { print Dumper $response; }

# Check if response was successful (not empty array in result)
if ( !@{ $response->content->{'result'} } ) {
logout);
die "hostinterface.get failed\n";
}

return @{ $response->content->{'result'} }

}

sub get_zbx_trapper_syslogid_by_hostid {

my $hostids = shift;

$json = {
jsonrpc => '2.0',
method => 'item.get',
params => {
output => ['itemid'],
hostids => $hostids,
search => {
'key_' => 'syslog',
type => 2, #type => 2 is zabbix_trapper
status => 0,

},
limit => 1,
},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );
if ( $debug > 0 ) { print Dumper $response; }

# Check if response was successful
if ( !@{ $response->content->{'result'} } ) {
logout);
die "item.get failed\n";
}

#return itemid of syslog key (trapper type)
return ${ $response->content->{'result'} }[0]->{itemid};
}

sub host_get {
my $hostids = shift;

$json = {

jsonrpc => '2.0',
method => 'host.get',
params => {
hostids => [$hostids],
output => [ 'host', 'proxy_hostid', 'status' ],
filter => { status => 0, }, # only use hosts enabled
limit => 1,
},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );

if ( $debug > 0 ) { print Dumper $response; }

# Check if response was successful
if ( !$response->content->{'result'} ) {
logout);
die "host.get failed\n";
}
return ${ $response->content->{'result'} }[0]; #return result
}




Копіюємо скрипт на сервер шляхом /usr/local/bin/zabbix_syslog_lkp_host.pl також створюємо конфігураційний файл
/usr/local/etc/zabbix_syslog.cfg з параметрами підключення до Заббиксу через API. Конфіг буде виглядати приблизно ось так:
url = http://zabbix.local/zabbix/api_jsonrpc.php
user = api_user
password = password
server = zabbix.local
debug=0
zabbix_sender= /usr/bin/zabbix_sender

Скрипт використовує кілька модулів Perl з CPAN, щоб встановити їх виконайте команди:
PERL_MM_USE_DEFAULT=1 perl-MCPAN-e 'install Readonly'
PERL_MM_USE_DEFAULT=1 perl-MCPAN-e 'install CHI'
PERL_MM_USE_DEFAULT=1 perl-MCPAN-e 'install JSON::RPC::Legacy::Client'
PERL_MM_USE_DEFAULT=1 perl-MCPAN-e 'install Config::General'

Також налаштовуємо права на ці наші нові файли:
chmod +x /usr/local/bin/zabbix_syslog_lkp_host.pl
chown zabbix:zabbix /usr/local/etc/zabbix_syslog.cfg
chmod 700 /usr/local/etc/zabbix_syslog.cfg

Все готово для відправки повідомлень в Заббикс, залишилося тільки перезавантажити rsyslog:
service rsyslog restart


З цього моменту ми вже можемо побачити повідомлення у заббиксе окремо для кожного вузла мережі, відкриваючи Останні дані -> потрібний вузол мережі -> Syslog


Тригери
Можливість читання логів в системі без ходіння по інтерфейсах обладнання — це добре (не кажучи навіть про те, що як правило логи на обладнанні лежать в пам'яті і не переживають ребут), але давайте не забудемо і про тригери. Як і у випадку інших протоколів вони допоможуть нам не проспати якесь важливе повідомлення на нашій мережі.

У кожного обладнання і у кожного виробника обладнання свої повідомлення, тому, як шукати важливе повідомлення, не знаючи, як воно виглядає? А ось наступним чином:
Всі повідомлення syslog класифікуються за допомогою атрибута severity, який згідно RFC5424 може приймати наступні значення:
0 Emergency: system is unusable
1 Alert: action must be taken immediately
2 Critical: critical conditions
3 Error: error conditions
4 Warning: warning conditions
5 Notice: normal but significant condition
6 Informational: informational messages
7 Debug: debug level messages
є у severity не тільки кількісну, але і текстове скорочене позначення, присутнє в остаточному повідомленні, яке передається в Zabbix через zabbix_sender.
Таким чином, ми можемо шукати ті повідомлення, якими сама залізка (тобто її виробник) присвоїла досить високу важливість, і повідомляти про них. Для цього в наш шаблон Template_Syslog додамо тригери, для сповіщення про всі події з severity=warning:



Останнє, що залишилося зробити — це оповіщення (дія) про цих нових syslog-повідомленнях. В умовах зазначимо, що ім'я тригера містить [SYSLOG], і що відправляти повідомлення потрібно через електронну пошту.







У підсумку, кожен раз, коли в syslog впаде повідомлення високої важливості, ми будемо отримувати повідомлення виду:

І до речі, наш шаблон з тригерами по критичності аварій вже готовий:
Template_Syslog
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>2.0</version>
<date>2015-03-13T14:27:56Z</date>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<templates>
<template>
<template>Template_Syslog</template>
<name>Template_Syslog</name>
<description/>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<applications>
<application>
<name>Log</name>
</application>
</applications>
<items>
<item>
<name>Syslog</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>syslog</key>
<delay>0</delay>
<history>3</history>
<trends>365</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description/>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Log</name>
</application>
</applications>
<valuemap/>
<logtimefmt>yyyyxMMxddxhhxmmxssxxxxxx</logtimefmt>
</item>
</items>
<discovery_rules/>
<macros/>
<templates/>
<screens/>
</template>
</templates>
<triggers>
<trigger>
<expression>({Template_Syslog:syslog.str(.alert)}=1)and({Template_Syslog:syslog.nodata(900)}=0)</expression>
<name>[SYSLOG] Alert message received</name>
<url/>
<status>0</status>
<priority>4</priority>
<description/>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>({Template_Syslog:syslog.str(.crit)}=1)and({Template_Syslog:syslog.nodata(900)}=0)</expression>
<name>[SYSLOG] Critical message received</name>
<url/>
<status>0</status>
<priority>3</priority>
<description/>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>({Template_Syslog:syslog.str(.emerg)}=1)and({Template_Syslog:syslog.nodata(900)}=0)</expression>
<name>[SYSLOG] Emergency message received</name>
<url/>
<status>0</status>
<priority>5</priority>
<description/>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>({Template_Syslog:syslog.str(.err)}=1)and({Template_Syslog:syslog.nodata(900)}=0)</expression>
<name>[SYSLOG] Error received</name>
<url/>
<status>0</status>
<priority>2</priority>
<description/>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>({Template_Syslog:syslog.str(.warning)}=1)and({Template_Syslog:syslog.nodata(900)}=0)</expression>
<name>[SYSLOG] Warning received</name>
<url/>
<status>0</status>
<priority>1</priority>
<description/>
<type>0</type>
<dependencies/>
</trigger>
</triggers>
</zabbix_export>




Звичайно, не обов'язково відловлювати всі повідомлення warning, error, critical і так далі. Це просто узагальнений варіант, який допомагає не втратити що-то позаштатне. Використовуючи функції тригерів iregxp(), regxp(), str(), завжди можна фіксувати в логах більш специфічні події.

Автоматичне кріплення до карти
Торкнемося ще один важливий момент, який спрощує роботу з syslog-повідомленнями — контекстний перехід з карти мережі.


Можна витратити день-другий і вистраждати додавання URL-посилань для кожного вузла мережі на його syslog елемент даних руками:


Але швидше за руки отсохнут клікати по мишці, або розумом торкнеш. Краще знову звернімося до Zabbix API за допомогою автоматизації цього рутинної справи:
Для цього накидаем скрипт, який буде
1) Брати всі елементи карти мережі
2) Для всіх елементів типу вузол мережі перевіряти, чи немає у нього елемента даних з key=syslog
3) Якщо є, додавати до списку існуючих URL посилання на перегляд цього елемента даних (якщо URL на Syslog вже є, то нічого не робити)
Коли скрипт буде готовий, ми розгорнемо його тільки на Zabbix-server'mssql е:
/usr/local/bin/zabbix_syslog_create_urls.pl
#!/usr/bin/perl
#URL for fixed ZBX 2.4

use 5.010;
use strict;
use warnings;
use JSON::RPC::Legacy::Client;
use Data::Dumper;
use Config::General;
our $VERSION = 1.1;
my $conf = Config::General->new('/usr/local/etc/zabbix_syslog.cfg');
my %Config = $conf->getall;

#Authenticate yourself
my $client = JSON::RPC::Legacy::Client->new();
my $url = $Config{'url'} || die "URL is missing in zabbix_syslog.cfg\n";
my $user = $Config{'user'} || die "API user is missing in zabbix_syslog.cfg\n";
my $password = $Config{'password'} || die "API user password is missing in zabbix_syslog.cfg\n";
my $server = $Config{'server'} || die "server hostname is missing in zabbix_syslog.cfg\n";

my $debug = $Config{'debug'};
my ( $authID, $response, $json );
my $id = 0;



$authID = login();

my $syslog_url_base = 'history.php?action=showvalues';

my @selements;

foreach my $map ( @{ map_get_extended() } ) {
my $mapid=$map->{sysmapid};
#next unless ($mapid == 120 or $mapid == 116); #debug
#put all mapelements into array @selements (so you can update map later!)
@selements = @{ $map->{selements} };

foreach my $selement (@selements) {
my $syslog_button_exists = 0;

if ( $debug > 0 ) {
print 'Object ID: '
. $selement->{selementid}
. 'Type: '
. $selement->{elementtype}
. 'Elementid '
. $selement->{elementid} . " \n";
}

# elementtype=0 hosts
if ( $selement->{elementtype} == 0 ) {

my $hostid = $selement->{elementid};

my $itemid = get_syslogid_by_hostid($hostid);
if ($itemid) {

#and add urls:

my $syslog_exists = 0;
foreach my $syslog_url ( @{ $selement->{urls} } ) {
$syslog_exists = 0;

if ( $syslog_url->{name} =~ 'Syslog' ) {

$syslog_exists = 1;
$syslog_url->{'name'} = 'Syslog';

$syslog_url->{'url'} =
$syslog_url_base
. '&itemids['
. $itemid . ']='
. $itemid;
}
}
if ( $syslog_exists == 0 ) {

#syslog item doesn't exist... add it
push @{ $selement->{urls} },
{
'name' => 'Syslog',
'url' => $syslog_url_base
. '&itemids['
. $itemid . ']='
. $itemid
};
}

}

}

}
map_update($mapid,\@selements);
}



logout);

#______ SUBS
sub get_syslogid_by_hostid {
my $hostids = shift;

$json = {
jsonrpc => '2.0',
method => 'item.get',
params => {
output => ['itemid'],
hostids => $hostids,
search => { 'key_' => 'syslog' },
limit => 1,
},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );

# Check if response was successful
if ( !$response->content->{'result'} ) {
logout);
die "item.get failed\n";
}

#return itemid of syslog key (trapper type)
return ${ $response->content->{'result'} }[0]->{itemid};
}

sub login {

$json = {
jsonrpc => '2.0',
method => 'user.login',
params => {
user => $user,
password => $password

},
id => $id++,
};

$response = $client->call( $url, $json );

# Check if response was successful
die "Authentication failed\n" unless $response->content->{'result'};

if ( $debug > 0 ) { print Dumper $response->content->{'result'}; }

return $response->content->{'result'};

}

sub map_get {

#retrieve all maps
$json = {
jsonrpc => '2.0',
method => 'map.get',
params => {
output => ['sysmapid']
},
id => $id++,
auth => "$authID",
};

$response = $client->call( $url, $json );

# Check if response was successful
if ( !$response->content->{'result'} ) {
logout);
die "map.get failed\n";
}

if ( $debug > 1 ) { print Dumper $response->content->{result}; }
return $response->content->{result};

}

sub logout {

$json = {
jsonrpc => '2.0',
method => 'user.logout',
params => {},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );

# Check if response was successful
warn "Logout failed\n" unless $response->content->{'result'};

return;
}

sub map_get_extended {
$json = {
jsonrpc => '2.0',
method => 'map.get',
params => {
selectSelements => 'extend',
#sysmapids => $map,
},
id => $id++,
auth => $authID,
};

$response = $client->call( $url, $json );

# Check if response was successful
if ( !$response->content->{'result'} ) {
logout);
die "map.get failed\n";
}
if ( $debug > 1 ) {

print Dumper $response->content->{'result'};
}

return $response->content->{'result'};
}

sub map_update {
my $mapid = shift;
my $selements_ref = shift;
$json = {
jsonrpc => '2.0',
method => 'map.update',
params => {
selements => [@{$selements_ref}],
sysmapid => $mapid,
},
id => $id++,
auth => $authID,
};

if ( $debug > 0 ) {
print "About to map.update this\n:";
print Dumper $json;
}

$response = $client->call( $url, $json );

if ( $debug > 0 ) {
print Dumper $response;
}

# Check if response was successful
if ( !$response->content->{'result'} ) {
logout);
die "map.update failed\n";
}
return;
}


І відразу додамо скрипт в cron (краще всього під користувачем zabbix) на машині з Zabbix Server, одного разу на добу може виявитися цілком достатньо.
* 1 * * * /usr/local/bin/zabbix_syslog_create_urls.pl

Також не забудемо зробити файл виконуваним:
chmod +x /usr/local/bin/zabbix_syslog_create_urls.pl

Готово!

Разом
Заббикс багато чого вміє «з коробки». Однак, якщо немає того, що потрібно Вам — зневірятися рано. Zabbix API, а також zabbix_sender, модулі, UserParameter — всі ці інструменти ваші послуг, щоб розширити можливості системи.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.