воскресенье, 22 ноября 2015 г.


Установка Zabbix 2.4 в CentOS 6.5. Сбор информации syslog с устройств с помощью Zabbix

1. Установка rsyslog
# yum shell
Loaded plugins: fastestmirror
Setting up Yum Shell
> install rsyslog7
Loading mirror speeds from cached hostfile
* base: mirror.yandex.ru
* epel: fedora-mirror01.rbc.ru
* extras: mirror.yandex.ru
* updates: mirror.yandex.ru
Setting up Install Process
> remove rsyslog
Setting up Remove Process
> run
--> Running transaction check
---> Package rsyslog.x86_64 0:5.8.10-8.el6 will be erased
---> Package rsyslog7.x86_64 0:7.4.10-3.el6_6 will be installed


Произойдет установка .............................
Finished Transaction
> Выходим из shell - CTRL + C

2. Запуск и добавление в автозагрузку rsyslog
Запускаем службу
# service rsyslog start
Добавляем в автозапуск
# chkconfig rsyslog on

3. Создаем дополнительный конфигурационный файл rsyslog
# touch /etc/rsyslog.d/zabbix_rsyslog.conf
# nano /etc/rsyslog.d/zabbix_rsyslog.conf

Помещаем в файл
#add template for network devices
$template network-fmt,"%TIMESTAMP:::date-rfc3339% [%fromhost-ip%] %pri-text% %syslogtag%%msg%\n"
#$template network-fmt,"[%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_1.sh;network-fmt
& ~


4. Вносим изменения в файл /etc/rsyslog.conf для приема Syslog-сообщений по сети через UDP:
# nano /etc/rsyslog.conf
Необходимо раскомментировать следующие директивы:
$ModLoad imudp
$UDPServerRun 514


5. Создаем скрипты, необходимые для приема syslog сообщений zabbix-ом
# touch /usr/local/bin/zabbix_syslog_lkp_host.pl
# chmod +x /usr/local/bin/zabbix_syslog_lkp_host.pl
# nano /usr/local/bin/zabbix_syslog_lkp_host.pl

Вставляем туда содержимое файла zabbix_syslog_lkp_host.pl
Содержимое файл внизу статьи.
Далее:
# touch /usr/local/bin/zabbix_syslog_lkp_host_1.sh
# chmod +x /usr/local/bin/zabbix_syslog_lkp_host_1.sh
# nano /usr/local/bin/zabbix_syslog_lkp_host_1.sh

Вставляем туда:
#!/bin/bash
/usr/bin/perl /usr/local/bin/zabbix_syslog_lkp_host.pl "$1"

Затем:
# touch /usr/local/etc/zabbix_syslog.cfg
# nano /usr/local/etc/zabbix_syslog.cfg

Вставляем туда
url = http://localhost/zabbix/api_jsonrpc.php
user = <логин zabbix api>
password = <пароль zabbix api>
server = localhost
debug=0

Меняем права:
# chown zabbix:zabbix /usr/local/etc/zabbix_syslog.cfg
# chmod 700 /usr/local/etc/zabbix_syslog.cfg


6. Для работы всей системы нужно установить ряд модулей perl
# cpan -i YAML
Во время работы отвечаем везде yes (нажимаем ENTER)
Затем
# 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'


7. Выполняем рестарт rsyslog
# service rsyslog restart

ПРИМЕЧАНИЕ:
И все же, что делает скрипт /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 *ИМЯУЗЛА*

Попробовать работы системы:
/usr/local/bin/zabbix_syslog_lkp_host.pl '2015-07-15T14:20:00.741158+04:00 [10.200.255.10] local0.notice 15476: 015473: Jul 15 14:21:50 MSK: %SYS-5-CONFIG_I: Configured from console by vitalij on vty1'

=======================================================

Ссылка на оригинал: http://habrahabr.ru/company/zabbix/blog/252915/
Содержимое файла 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;
use MIME::Base64 qw(encode_base64);
use IO::Socket::INET;
our $VERSION = 2.0;

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 $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 already is 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 );
}

zabbix_send( $server, $hostname, 'syslog', $message );

#______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
}

sub zabbix_send {
    my $zabbixserver = shift;
    my $hostname     = shift;
    my $item         = shift;
    my $data         = shift;
    Readonly my $SOCK_TIMEOUT     => 10;
    Readonly my $SOCK_RECV_LENGTH => 1024;

    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 = IO::Socket::INET->new(
        PeerAddr => $zabbixserver,
        PeerPort => '10051',
        Proto    => 'tcp',
        Timeout  => $SOCK_TIMEOUT
    );

    die "Could not create socket: $ERRNO\n" unless $sock;
    $sock->send($request);
    my @handles = IO::Select->new($sock)->can_read($SOCK_TIMEOUT);
    if ( $debug > 0 ) { print "item - $item, data - $data\n"; }

    if ( scalar(@handles) > 0 ) {
        $sock->recv( $result, $SOCK_RECV_LENGTH );
        if ( $debug > 0 ) {
            print "answer from zabbix server $zabbixserver: $result\n";
        }
    }
    else {
        if ( $debug > 0 ) { print "no answer from zabbix server\n"; }
    }
    $sock->close();
    return;
}

1 комментарий:

  1. If you are looking into making money from your websites/blogs with popunder ads, you can try one of the biggest companies - Propeller Ads.

    ОтветитьУдалить