Installing and Configuring Zabbix

Here I'll show you how to install and configure the Zabbix server and client, the Zabbix server will installed in Debian Wheezy and another in CentOS 7, sometimes we shall need to install or in one or in another.

Let's roll up our sleeves and start to work.

  • Debian Wheezy Zabbix Server ip: 192.168.1.100
  • CentOS 7 Zabbix Server ip: 192.168.1.102

If you need to check out how to configure the clients please check this tutorial: http://wiki.douglasqsantos.com.br/doku.php/instalacao_e_configuracao_do_zabbix_2.0.5_no_debian_squeeze_pt_br

We need to get the repository to install Zabbix with the lastest version is always the best way to install the Zabbix because we always will have more features and new resources to work.

cd /tmp && wget -c http://repo.zabbix.com/zabbix/2.4/debian/pool/main/z/zabbix-release/zabbix-release_2.4-1+wheezy_all.deb

Now we need to install the repository like this

dpkg -i /tmp/zabbix-release_2.4-1+wheezy_all.deb

Now we need to update the repositories cache with the follow command

aptitude update

Now let's intall the Zabbix Server with MySQL support and its dependencies.

aptitude install zabbix-server-mysql zabbix-sender -y
  • We shall need to configure an MySQL password and confirm it, I'll use the secretP4ssw0rd
  • After it we need to choose no because the database needs configuration yet

Let's create the database and set up the permission to zabbix user like this

mysql -u root -p
create database zabbix character set utf8;
grant all on zabbix.* to 'zabbix'@'localhost' identified by 'secretP4ssw0rd';
flush privileges;
quit

Now we need to import the database structure with the follow commands

cd /usr/share/zabbix-server-mysql
mysql -u zabbix -psecretP4ssw0rd zabbix < schema.sql 
mysql -u zabbix -psecretP4ssw0rd zabbix < images.sql
mysql -u zabbix -psecretP4ssw0rd zabbix < data.sql

Now we need to configure the zabbix_server.conf to connect on the database like this

vim /etc/zabbix/zabbix_server.conf
[...]
DBName=zabbix
[...]
DBUser=zabbix
[...]
DBPassword=secretP4ssw0rd

Now we need to restart the Zabbix Server like this

/etc/init.d/zabbix-server restart

Now we're able to see the logs with the follow command

tail -f /var/log/zabbix/zabbix_server.log
  7425:20150316:103253.365 server #3 started [poller #1]
  7424:20150316:103253.367 server #2 started [db watchdog #1]
  7423:20150316:103253.368 server #1 started [configuration syncer #1]
  7459:20150316:103253.376 server #20 started [history syncer #1]
  7462:20150316:103253.376 server #23 started [history syncer #4]
  7461:20150316:103253.377 server #22 started [history syncer #3]
  7464:20150316:103253.377 server #25 started [proxy poller #1]
  7465:20150316:103253.377 server #26 started [self-monitoring #1]
  7463:20150316:103253.377 server #24 started [escalator #1]
  7460:20150316:103253.377 server #21 started [history syncer #2]

We can double check to see if the zabbix_serer is running

ps -C zabbix_server
  PID TTY          TIME CMD
 7420 ?        00:00:00 zabbix_server
 7423 ?        00:00:00 zabbix_server
 7424 ?        00:00:00 zabbix_server
 7425 ?        00:00:00 zabbix_server
 7426 ?        00:00:00 zabbix_server
 7427 ?        00:00:00 zabbix_server
 7428 ?        00:00:00 zabbix_server
 7429 ?        00:00:00 zabbix_server
 7430 ?        00:00:00 zabbix_server
 7431 ?        00:00:00 zabbix_server
 7432 ?        00:00:00 zabbix_server
 7433 ?        00:00:00 zabbix_server
 7434 ?        00:00:00 zabbix_server
 7435 ?        00:00:00 zabbix_server
 7436 ?        00:00:00 zabbix_server
 7437 ?        00:00:00 zabbix_server
 7438 ?        00:00:00 zabbix_server
 7439 ?        00:00:00 zabbix_server
 7440 ?        00:00:00 zabbix_server
 7441 ?        00:00:00 zabbix_server
 7459 ?        00:00:00 zabbix_server
 7460 ?        00:00:00 zabbix_server
 7461 ?        00:00:00 zabbix_server
 7462 ?        00:00:00 zabbix_server
 7463 ?        00:00:00 zabbix_server
 7464 ?        00:00:00 zabbix_server
 7465 ?        00:00:00 zabbix_server

We need to install the Zabbix frontend that will be used to manager the zabbix and their clients

aptitude install zabbix-frontend-php php5-mysql -y

Now we need to create the Virtualhost that will be used by the Zabbix Frontend

vim /etc/apache2/sites-available/zabbix.conf
<VirtualHost *:80>
    ServerAdmin webmaster@douglasqsantos.com.br
    ServerName zabbix.douglasqsantos.com.br
    DocumentRoot /usr/share/zabbix

<Directory "/usr/share/zabbix">
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
    php_value max_execution_time 300
    php_value memory_limit 128M
    php_value post_max_size 16M
    php_value upload_max_filesize 2M
    php_value max_input_time 300
    php_value date.timezone America/Sao_Paulo
</Directory>

<Directory "/usr/share/zabbix/conf">
    Order deny,allow
    Deny from all
    <files *.php>
        Order deny,allow
        Deny from all
    </files>
</Directory>

<Directory "/usr/share/zabbix/api">
    Order deny,allow
    Deny from all
    <files *.php>
        Order deny,allow
        Deny from all
    </files>
</Directory>

<Directory "/usr/share/zabbix/include">
    Order deny,allow
    Deny from all
    <files *.php>
        Order deny,allow
        Deny from all
    </files>
</Directory>

<Directory "/usr/share/zabbix/include/classes">
    Order deny,allow
    Deny from all
    <files *.php>
        Order deny,allow
        Deny from all
    </files>
</Directory>
   ErrorLog /var/log/apache2/zabbix.douglasqsantos.com.br-error.log
   LogLevel warn
   CustomLog /var/log/apache2/zabbix.douglasqsantos.com.br-access.log combined
</VirtualHost>

Now we need to disable de default virtual host and enable the zabbix's virtual host

a2dissite default
a2ensite zabbix.conf

Now restart the apache server like this

/etc/init.d/apache2 restart

Now we need to configure the frontend access http://192.168.1.100 or http://zabbix.douglasqsantos.com.br

  • In the first page click on Next
  • If the all prerequisites is ok click on Next or configure the ones that need to be fixed
  • Here we need to configure the Database:
    • Database type: MySQL
    • Database host: localhost
    • Database port: 0
    • Database name: zabbix
    • User: zabbix
    • Password: secretP4ssw0rd
    • Click in Test connection to continue and Click in Next
  • Now we need to only to click on Next because the default configuration is ok
  • Now click on Next again
  • Now click on Finish

Now we can login as user: admin password: zabbix

Let's install the packets to enable the Zabbix Client, here needs to install the zabbix-get too to get information about the clients and to troubleshooting the problems.

aptitude install zabbix-agent zabbix-get  -y

Now needs to configure the client the configuration is very simple we need to change only two lines

vim /etc/zabbix/zabbix_agentd.conf
[...]
Server=127.0.0.1
[...]
Hostname=Zabbix server

Now we need to remove the current file on the zabbix_agentd.d

rm -rf /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf

Now needs to restart the Zabbix client service like this

/etc/init.d/zabbix-agent restart

Let's double check if the zabbix-agent is working properly as we need

ps -C zabbix_agentd
  PID TTY          TIME CMD
 9930 ?        00:00:00 zabbix_agentd
 9932 ?        00:00:00 zabbix_agentd
 9933 ?        00:00:00 zabbix_agentd
 9934 ?        00:00:00 zabbix_agentd
 9935 ?        00:00:00 zabbix_agentd
 9936 ?        00:00:00 zabbix_agentd

Let's get the kernel version from the client

zabbix_get -s127.0.0.1 -p10050 -ksystem.uname
Linux debian100 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64

Now getting the agent version like this

zabbix_get -s127.0.0.1 -p10050 -kagent.version
2.4.4

Now we can access http://192.168.1.100 or http://zabbix.douglasqsantos.com.br inform the user and password

  • On Configuration/Hosts
  • Click on Disabled to enable the Zabbix server and click Ok
  • Now if the system gets some problem it will be shown in the Monitoring/Dashboard

We need to get the repository to install Zabbix with the lastest version is always the best way to install the Zabbix because we always will have more features and new resources to work.

cd /tmp && wget -c wget -c http://repo.zabbix.com/zabbix/2.4/rhel/7/x86_64/zabbix-release-2.4-1.el7.noarch.rpm

Now we need to install the repository like this

rpm -ivh /tmp/zabbix-release-2.4-1.el7.noarch.rpm

Now we need to update the repositories cache with the follow command

yum check-update

Now let's intall the Zabbix Server with MySQL support and its dependencies.

yum install zabbix-server-mysql mariadb-server -y

Now we need to check the services files for systemd

systemctl list-unit-files | egrep "(maria|zabbix)"
mariadb.service                             disabled
zabbix-server.service                       disable

Now we need to enable both services

systemctl enable mariadb.service
systemctl enable zabbix-server.service

Now let's start the MariaDB

systemctl start mariadb.service

Now we need to set up the MariaDB password

mysqladmin -u root password 'secretP4ssw0rd'

Let's create the database and set up the permission to zabbix user like this

mysql -u root -p
create database zabbix character set utf8;
grant all on zabbix.* to 'zabbix'@'localhost' identified by 'secretP4ssw0rd';
flush privileges;
quit

Now we need to import the database structure with the follow commands

cd /usr/share/doc/zabbix-server-mysql-*/create
mysql -u zabbix -psecretP4ssw0rd zabbix < schema.sql 
mysql -u zabbix -psecretP4ssw0rd zabbix < images.sql
mysql -u zabbix -psecretP4ssw0rd zabbix < data.sql

Now we need to configure the zabbix_server.conf to connect on the database like this

vim /etc/zabbix/zabbix_server.conf
[...]
DBName=zabbix
[...]
DBUser=zabbix
[...]
DBPassword=secretP4ssw0rd

Now we need to start the Zabbix Server like this

systemctl start zabbix-server.service

Now we're able to see the logs with the follow command

tail -f /var/log/zabbix/zabbix_server.log
 17673:20150316:143653.434 server #8 started [unreachable poller #1]
 17674:20150316:143653.436 server #9 started [trapper #1]
 17677:20150316:143653.436 server #12 started [trapper #4]
 17682:20150316:143653.436 server #17 started [timer #1]
 17687:20150316:143653.439 server #22 started [history syncer #3]
 17670:20150316:143653.439 server #5 started [poller #3]
 17676:20150316:143653.441 server #11 started [trapper #3]
 17666:20150316:143653.441 server #1 started [configuration syncer #1]
 17685:20150316:143653.441 server #20 started [history syncer #1]
 17684:20150316:143653.819 server #19 started [discoverer #1]

We can double check to see if the zabbix_serer is running

ps -C zabbix_server
  PID TTY          TIME CMD
17661 ?        00:00:00 zabbix_server
17666 ?        00:00:00 zabbix_server
17667 ?        00:00:00 zabbix_server
17668 ?        00:00:00 zabbix_server
17669 ?        00:00:00 zabbix_server
17670 ?        00:00:00 zabbix_server
17671 ?        00:00:00 zabbix_server
17672 ?        00:00:00 zabbix_server
17673 ?        00:00:00 zabbix_server
17674 ?        00:00:00 zabbix_server
17675 ?        00:00:00 zabbix_server
17676 ?        00:00:00 zabbix_server
17677 ?        00:00:00 zabbix_server
17678 ?        00:00:00 zabbix_server
17679 ?        00:00:00 zabbix_server
17680 ?        00:00:00 zabbix_server
17681 ?        00:00:00 zabbix_server
17682 ?        00:00:00 zabbix_server
17683 ?        00:00:00 zabbix_server
17684 ?        00:00:00 zabbix_server
17685 ?        00:00:00 zabbix_server
17686 ?        00:00:00 zabbix_server
17687 ?        00:00:00 zabbix_server
17688 ?        00:00:00 zabbix_server
17689 ?        00:00:00 zabbix_server
17690 ?        00:00:00 zabbix_server
17691 ?        00:00:00 zabbix_server

We need to install the Zabbix frontend that will be used to manager the zabbix and their clients

yum install zabbix-web-mysql -y

Now we need to now the name of the Apache on the CentOS to put into the boot time

systemctl list-unit-files | egrep http
httpd.service                               disabled

Let's enable this service

systemctl enable httpd.service

Let's move two files from the httpd configuration

cd /etc/httpd/conf.d/ && mv userdir.conf zabbix.conf /usr/src

Now we need to create the Virtualhost that will be used by the Zabbix Frontend

vim /etc/httpd/conf.d/zabbix.conf
<VirtualHost *:80>
    ServerAdmin webmaster@douglasqsantos.com.br
    ServerName zabbix.douglasqsantos.com.br
    DocumentRoot /usr/share/zabbix

<Directory "/usr/share/zabbix">
    Options FollowSymLinks
    AllowOverride None
    Require all granted
    php_value max_execution_time 300
    php_value memory_limit 128M
    php_value post_max_size 16M
    php_value upload_max_filesize 2M
    php_value max_input_time 300
    php_value date.timezone America/Sao_Paulo
</Directory>

<Directory "/usr/share/zabbix/conf">
    Require all granted
</Directory>

<Directory "/usr/share/zabbix/api">
    Require all granted
</Directory>

<Directory "/usr/share/zabbix/include">
    Require all granted
</Directory>

<Directory "/usr/share/zabbix/include/classes">
    Require all granted
</Directory>

<Location /server-status>
  SetHandler server-status
  Allow from 127.0.0.1 ::1
</Location>

   ErrorLog /var/log/httpd/zabbix.douglasqsantos.com.br-error.log
   LogLevel warn
   CustomLog /var/log/httpd/zabbix.douglasqsantos.com.br-access.log combined
</VirtualHost>

Now restart the apache server like this

systemctl restart httpd.service

Let's check if the apache is running

systemctl status httpd.service
httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
   Active: active (running) since Mon 2015-03-16 14:46:56 BRT; 4s ago
 Main PID: 17802 (httpd)
   Status: "Processing requests..."
   CGroup: /system.slice/httpd.service
           ├─17802 /usr/sbin/httpd -DFOREGROUND
           ├─17804 /usr/sbin/httpd -DFOREGROUND
           ├─17805 /usr/sbin/httpd -DFOREGROUND
           ├─17806 /usr/sbin/httpd -DFOREGROUND
           ├─17807 /usr/sbin/httpd -DFOREGROUND
           └─17808 /usr/sbin/httpd -DFOREGROUND

Mar 16 14:46:56 centos102 systemd[1]: Started The Apache HTTP Server.

Now we need to configure the frontend access http://192.168.1.102 or http://zabbix.douglasqsantos.com.br

  • In the first page click on Next
  • If the all prerequisites is ok click on Next or configure the ones that need to be fixed
  • Here we need to configure the Database:
    • Database type: MySQL
    • Database host: localhost
    • Database port: 0
    • Database name: zabbix
    • User: zabbix
    • Password: secretP4ssw0rd
    • Click in Test connection to continue and Click in Next
  • Now we need to only to click on Next because the default configuration is ok
  • Now click on Next again
  • Now click on Finish

Now we can login as user: admin password: zabbix

Let's install the packets to enable the Zabbix Client, here needs to install the zabbix-get too to get information about the clients and to troubleshooting the problems.

yum install zabbix-agent zabbix-get -y

Now we need to enable the zabbix agent

systemctl enable zabbix-agent.service

Now needs to configure the client the configuration is very simple we need to change only two lines

vim /etc/zabbix/zabbix_agentd.conf
[...]
Server=127.0.0.1
[...]
Hostname=Zabbix server

Now we need to remove the current file on the zabbix_agentd.d

rm -rf /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf

Now needs to restart the Zabbix client service like this

systemctl restart zabbix-agent.service

Let's double check if the zabbix-agent is working properly as we need

ps -C zabbix_agentd
  PID TTY          TIME CMD
17968 ?        00:00:00 zabbix_agentd
17969 ?        00:00:00 zabbix_agentd
17970 ?        00:00:00 zabbix_agentd
17971 ?        00:00:00 zabbix_agentd
17972 ?        00:00:00 zabbix_agentd
17973 ?        00:00:00 zabbix_agentd

Let's get the kernel version from the client

zabbix_get -s127.0.0.1 -p10050 -ksystem.uname
Linux centos102 3.10.0-123.20.1.el7.x86_64 #1 SMP Thu Jan 29 18:05:33 UTC 2015 x86_64

Now getting the agent version like this

zabbix_get -s127.0.0.1 -p10050 -kagent.version
2.4.4

Now we can access http://192.168.1.102 or http://zabbix.douglasqsantos.com.br inform the user and password

  • On Configuration/Hosts
  • Click on Disabled to enable the Zabbix server and click Ok
  • Now if the system gets some problem it will be shown in the Monitoring/Dashboard

Templates

NOTE: This commands will be used by all the templates.

We need to use two commands to sum the amount of memory used by some kind of application and users therewith we need to create the follow zabbix agent file

vim /etc/zabbix/zabbix_agentd.d/config-misc.conf
UserParameter=proc.mem.rss.proc[*],sudo /bin/ps ho rss $(pgrep -of "$1")
UserParameter=proc.mem.rss.user[*],VER=$(sudo /bin/ps ho rss $(pgrep -U "$1")); SUM=0; for end in $VER; do SUM=$(($SUM + $end)) ; done; echo $SUM
UserParameter=sshversion,/usr/bin/ssh -V
UserParameter=dhcpversion,sudo /usr/sbin/dhcpd --version
UserParameter=cupsversion,sudo /usr/sbin/cupsctl -h | head -n 2 | tail -n 1 | awk '{print $3}'
UserParameter=postgresversion,sudo /usr/lib/postgresql/9.1/bin/postgres --version | awk '{print $3}'
UserParameter=namedversion,sudo /usr/sbin/named -v | awk '{print $2}' | cut -d '-' -f 1
UserParameter=amavisversion,sudo /usr/sbin/amavisd-agent -c 1 | grep sysDescr | awk '{print $3}' | cut -d '-' -f 3
UserParameter=openvpnversion,sudo /usr/sbin/openvpn --version | head -n 1 | cut -d ' ' -f 2
UserParameter=ldapversion,sudo /usr/bin/dpkg -l | egrep slap | awk '{print $3}' | cut -d 'p' -f 1 | cut -d '-' -f 1
UserParameter=jabberversion,sudo /usr/bin/dpkg -l | egrep jabber | awk '{print $3}' | cut -d '-' -f 1
UserParameter=check.version[*],sudo /usr/bin/dpkg -l | egrep "$1" | awk '{print $$3}' | cut -d '-' -f 1 | cut -d ':' -f 2 | cut -d '.' -f 1-3
UserParameter=asterisk.version,sudo /usr/sbin/asterisk -V | awk '{print $2}'

Let's configure the Sudo for Zabbix like this

visudo
[...]
#Defaults    requiretty
[...]
Cmnd_Alias ZCMD = /usr/bin/smbstatus, /usr/bin/testparm, /usr/sbin/postconf, /usr/sbin/smbd, /usr/sbin/apachectl, /usr/sbin/dhcpd, /usr/sbin/cupsctl, /usr/sbin/named, /usr/bin/nmap, /usr/bin/traceroute, /usr/sbin/amavisd-agent, /bin/ps, /usr/lib/postgresql/9.1/bin/postgres, /usr/sbin/openvpn, /usr/bin/dpkg, /usr/sbin/asterisk
zabbix ALL = NOPASSWD: ZCMD

Now we need to restart the zabbix agent like this.

/etc/init.d/zabbix-agent restart

We can run a test like this, getting information about a single process

zabbix_get -s 127.0.0.1 -k "proc.mem.rss.proc[master]"
 2480

We can run a test like this, getting information about a process of a user

zabbix_get -s 127.0.0.1 -k "proc.mem.rss.user[postfix]"
25680

Issue: https://support.zabbix.com/browse/ZBX-4532

We can use the following templates rather then the default available on Zabbix 2.4, so back up the Linux and Windows default template and remove them after that import the following templates.

After get the tarball extract it, after that in the frontend.

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Note: Make sure you are using at least Python version 3.2 or above if the path of you python is different from the scripts please change it.

Here is the scripts to check the named files, please make sure that you change the files path if the structure you are using is different from mine.

Checking the default files to named

vim /usr/local/bin/check_named_default_files.py
#!/usr/bin/python3.2

import json
import subprocess

def main():
    new = subprocess.check_output("ls -l /etc/bind/* | egrep '(db|named).*' 2> /dev/null | awk '{print $9}' | egrep -v '^$' | cut -d '/' -f 4", shell=True)
    output = str(new,'UTF-8')
    data = list()

    for line in output.split("\n"):
        if line:
            data.append({"{#FILEPATH}": "/etc/bind/" + line,"{#FILENAME}": line})
    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Chcking the external configuration files

vim /usr/local/bin/check_named_external_files.py
#!/usr/bin/python3.2

import json
import subprocess

def main():
    new = subprocess.check_output("ls -l /etc/bind/zones/external/* 2> /dev/null | egrep '(db|named).*' | awk '{print $9}' | egrep -v '^$' | cut -d '/' -f 6", shell=True)
    output = str(new,'UTF-8')
    data = list()

    for line in output.split("\n"):
        if line:
            data.append({"{#FILEPATH_EXT}": "/etc/bind/zones/external/" + line,"{#FILENAME_EXT}": line})
    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Chcking the internal configuration files

vim /usr/local/bin/check_named_internal_files.py
#!/usr/bin/python3.2

import json
import subprocess

def main():
    new = subprocess.check_output("ls -l /etc/bind/zones/internal/* 2> /dev/null | egrep '(db|named).*' | awk '{print $9}' | egrep -v '^$' | cut -d '/' -f 6", shell=True)
    output = str(new,'UTF-8')
    data = list()

    for line in output.split("\n"):
        if line:
            data.append({"{#FILEPATH_INT}": "/etc/bind/zones/internal/" + line,"{#FILENAME_INT}": line})
    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Checking master zone files

vim /usr/local/bin/check_named_master_zones_files.py
#!/usr/bin/python3.2

import json
import subprocess

def main():
    new = subprocess.check_output("ls -l /var/lib/named/var/cache/bind/master/db.* 2> /dev/null | awk '{print $9}' | egrep -v '^$' | cut -d '/' -f 9", shell=True)
    output = str(new,'UTF-8')
    data = list()

    for line in output.split("\n"):
        if line:
            data.append({"{#FILEPATH_MZ}": "/var/lib/named/var/cache/bind/master/" + line,"{#FILENAME_MZ}": line})
    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Checking internal zone files

vim /usr/local/bin/check_named_slave_zones_files.py
#!/usr/bin/python3.2

import json
import subprocess

def main():
    new = subprocess.check_output("ls -l /var/lib/named/var/cache/bind/slave/db.* 2> /dev/null | awk '{print $9}' | egrep -v '^$' | cut -d '/' -f 9", shell=True)
    output = str(new,'UTF-8')
    data = list()

    for line in output.split("\n"):
        if line:
            data.append({"{#FILEPATH_SZ}": "/var/lib/named/var/cache/bind/slave/" + line,"{#FILENAME_SZ}": line})
    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Now we need to set the execution permission to the scripts as follows

chmod +x /usr/local/bin/check_named_*

Creating the zabbix client configuration file

vim /etc/zabbix/zabbix_agentd.d/config-named.conf
UserParameter=named.default.discover_files,/usr/local/bin/check_named_default_files.py
UserParameter=named.internal.discover_files,/usr/local/bin/check_named_internal_files.py
UserParameter=named.external.discover_files,/usr/local/bin/check_named_external_files.py
UserParameter=named.master.zones.discover_files,/usr/local/bin/check_named_master_zones_files.py
UserParameter=named.slave.zones.discover_files,/usr/local/bin/check_named_slave_zones_files.py

Now let's restart the zabbix-agent to reload the newest configurations

/etc/init.d/zabbix-agent restart

Now need to import the Template for named and link to the servers that work as DNS Server.

After get the tarball extract it, after that in the frontend.

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Note: Make sure you are using at least Python version 3.2 or above if the path of you python is different from the scripts please change it.

Here is the scripts to check the Asterisk files.

Checking the default files to Asterisk

vim /usr/local/bin/check_asterisk_default_files.py
#!/usr/bin/python3.2

import json
import subprocess

def main():
    new = subprocess.check_output("ls -l /etc/asterisk/* 2> /dev/null | egrep -v '*.(old|bkp|template|sample|orig)' | awk '{print $9}' | egrep -v '^$' | cut -d '/' -f 4", shell=True)
    output = str(new,'UTF-8')
    data = list()

    for line in output.split("\n"):
        if line:
            data.append({"{#FILEPATH_AST}": "/etc/asterisk/" + line,"{#FILENAME_AST}": line})
    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Now we need to set the execution permission to the scripts as follows

chmod +x /usr/local/bin/check_asterisk_default_files.py

Creating the zabbix client configuration file

vim /etc/zabbix/zabbix_agentd.d/config-asterisk.conf
UserParameter=asterisk.default.discover_files,/usr/local/bin/check_asterisk_default_files.py
UserParameter=asterisk.active.calls,sudo /usr/sbin/asterisk -rx 'core show calls' | egrep 'active' | awk '{print $1}'
UserParameter=asterisk.processed.calls,sudo /usr/sbin/asterisk -rx 'core show calls' | egrep 'processed' | awk '{print $1}'

Now let's restart the zabbix-agent to reload the newest configurations

/etc/init.d/zabbix-agent restart

Now need to import the Template for Asterisk and link.

After get the tarball extract it, after that in the frontend.

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to get the template to work with MySQL because we're using the MySQL backend here, get in http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_mysql_templates.xml.zip we need to import the files with the browser therewith download the files on your desktop. After get the tarball extract it.

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to create the database and configure the client side.

Note: The password cannot have any special character.

Now we need to create the user in the MySQL that will be monitoring the MySQL

mysql -u root -p
GRANT USAGE ON *.* TO 'zabbix-monitor'@'localhost' IDENTIFIED BY 'password';
flush privileges;
quit

Now on the Zabbix Client we need to create the MySQL template configuration like this

vim /etc/zabbix/zabbix_agentd.d/config-mysql.conf
# Mysql User Params
#
# create a mysql user to collect zabbix agent data
# GRANT USAGE ON *.* TO 'zabbix'@'localhost' IDENTIFIED BY 'YOUR_PASSWORD_HERE';
#

UserParameter=mysql.status[*],(test -f /usr/bin/mysqladmin && mysqladmin -u $1 -p$2 extended-status | grep -w "$3" | awk '{print $$4}')
UserParameter=mysql.ping[*],(test -f /usr/bin/mysqladmin && mysqladmin -u $1 -p$2 ping | grep alive | wc -l)
UserParameter=mysql.version,(test -f /usr/bin/mysql && /usr/bin/mysql -V | awk '{print $5}' | tr -d ',')

Now we need to restart the client to get the newest configuration with the follow command

/etc/init.d/zabbix-agent restart

Now we need to configure the Zabbix Client to use the new template.

  • On Configuration/Hosts/Zabbix server
  • Click on Templates
    • Now Click Select and select the Template Name
    • Now Click on Add
  • Now Click on Macros
    • Now we need to create two MACROS one for the user and other for the password that will be monitoring the MySQL Server
    • In Macro: {$MYSQL_PASS}
    • In Value: password
    • Click on Add
    • In Macro: {$MYSQL_USER}
    • In Value: zabbix-monitor
    • Click on Add
    • Now Click Update

Let's check if the template is working we need to get some value with the follow command

zabbix_get -s127.0.0.1 -p10050 -k "mysql.status[zabbix-monitor,sci134,Com_begin]"
1314

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

Now we can see the information about the lastest data from Zabbix Server, just expand the + icon and click in Graph to see the graph about the resource.

If you got 28 items for the MySQL need to remove the template and add again and configure the host, afterwards we'll have only 14 items that is the correct one.

We have more important one that will monitoring the Apache server

Now let's create the client file for this template like we do for Apache

vim /etc/zabbix/zabbix_agentd.d/config-apache.conf
UserParameter=apache[*],/usr/local/bin/check_apache \$1

Now we need to create the script like this

vim  /usr/local/bin/check_apache
#!/bin/bash
#
# Name: check_apache
#
# Checks Apache activity.
#
# Author: Alejandro Michavila
# Modified for Scoreboard Values: Murat Koc, murat@profelis.com.tr
# Modified for using also as external script: Murat Koc, murat@profelis.com.tr
# Modified for outputting usage or ZBX_NOTSUPPORTED: Alejandro Michavila
# Modified by Douglas Q. dos Santos
# Version: 1.4
#

check_apache="1.4"
rval=0

function usage()
{
    echo "check_apache version: $check_apache"
    echo "usage:"
    echo "    $0 TotalAccesses                   -- Check total accesses."
    echo "    $0 TotalKBytes                     -- Check total KBytes."
    echo "    $0 Uptime                          -- Check uptime."
    echo "    $0 ReqPerSec                       -- Check requests per second."
    echo "    $0 BytesPerSec                     -- Check Bytes per second."
    echo "    $0 BytesPerReq                     -- Check Bytes per request."
    echo "    $0 BusyWorkers                     -- Check busy workers."
    echo "    $0 IdleWorkers                     -- Check idle workers."
    echo "    $0 version                         -- Version of this script."
    echo "    $0 WaitingForConnection            -- Check Waiting for Connection processess."
    echo "    $0 StartingUp                      -- Check Starting Up processess."
    echo "    $0 ReadingRequest                  -- Check Reading Request processess."
    echo "    $0 SendingReply                    -- Check Sending Reply processess."
    echo "    $0 KeepAlive                       -- Check KeepAlive Processess."
    echo "    $0 DNSLookup                       -- Check DNSLookup Processess."
    echo "    $0 ClosingConnection               -- Check Closing Connection Processess."
    echo "    $0 Logging                         -- Check Logging Processess."
    echo "    $0 GracefullyFinishing             -- Check Gracefully Finishing Processess."
    echo "    $0 IdleCleanupOfWorker             -- Check Idle Cleanup of Worker Processess."
    echo "    $0 OpenSlotWithNoCurrentProcess    -- Check Open Slots with No Current Process."
}

########
# Main #
########

if [[ $# ==  1 ]];then
    #Agent Mode
    VAR=$(wget --quiet -O - http://localhost/server-status?auto)
    CASE_VALUE=$1
elif [[ $# == 2 ]];then
    #External Script Mode
    VAR=$(wget --quiet -O - http://$1/server-status?auto)
    CASE_VALUE=$2
else
    #No Parameter
    usage
    exit 0
fi

if [[ -z $VAR ]]; then
    echo "ZBX_NOTSUPPORTED"
    exit 1
fi

case $CASE_VALUE in
'TotalAccesses')
    echo "$VAR"|grep -i "Total Accesses:"|awk '{print $3}'
    rval=$?;;
'TotalKBytes')
    VER=$(echo "$VAR"|grep -i "Total kBytes:"|awk '{print $3}')
    MULT=$(($VER * 1024))
    echo "$MULT"
    rval=$?;;
'Uptime')
    echo "$VAR"|grep -i "Uptime:"|awk '{print $2}'
    rval=$?;;
'ReqPerSec')
    echo "$VAR"|grep -i "ReqPerSec:"|awk '{print $2}'
    rval=$?;;
'BytesPerSec')
    echo "$VAR"|grep -i "BytesPerSec:"|awk '{print $2}'
    rval=$?;;
'BytesPerReq')
    echo "$VAR"|grep -i "BytesPerReq:"|awk '{print $2}'
    rval=$?;;
'BusyWorkers')
    echo "$VAR"|grep -i "BusyWorkers:"|awk '{print $2}'
    rval=$?;;
'IdleWorkers')
    echo "$VAR"|grep -i "IdleWorkers:"|awk '{print $2}'
    rval=$?;;
'WaitingForConnection')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "_" } ; { print NF-1 }'
    rval=$?;;
'StartingUp')
    echo "$VAR"|grep "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "S" } ; { print NF-1 }'
    rval=$?;;
'ReadingRequest')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "R" } ; { print NF-1 }'
    rval=$?;;
'SendingReply')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "W" } ; { print NF-1 }'
    rval=$?;;
'KeepAlive')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "K" } ; { print NF-1 }'
    rval=$?;;
'DNSLookup')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "D" } ; { print NF-1 }'
    rval=$?;;
'ClosingConnection')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "C" } ; { print NF-1 }'
    rval=$?;;
'Logging')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "L" } ; { print NF-1 }'
    rval=$?;;
'GracefullyFinishing')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "G" } ; { print NF-1 }'
    rval=$?;;
'IdleCleanupOfWorker')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "I" } ; { print NF-1 }'
    rval=$?;;
'OpenSlotWithNoCurrentProcess')
    echo "$VAR"|grep -i "Scoreboard:"| awk '{print $2}'| awk 'BEGIN { FS = "." } ; {data_type>0 print NF-1 }'
    rval=$?;;
'version')
    ApacheVersion=$(sudo /usr/sbin/apachectl -v 2> /dev/null | head -n 1 | awk '{print $3}' | cut -d '/' -f 2 | tail -n 1)
    echo "$ApacheVersion"
    exit $rval;;
*)
    usage
    exit $rval;;
esac

if [ "$rval" -ne 0 ]; then
      echo "ZBX_NOTSUPPORTED"
fi

exit $rval

Now needs to change the permission

chmod +x /usr/local/bin/check_apache

Now we need to restart the zabbix agent

/etc/init.d/zabbix-agent restart

Let's run a test

zabbix_get -s127.0.0.1 -p10050 -k"apache[BytesPerReq]"
190

We can check like this as well

lynx http://localhost/server-status

Note: I don't have a clue what's happen with Debian Squeeze because this motherfucking doesn't show the information here only in the frontend.

Note the module status needs to be enabled and the configuration is like this

vim /etc/apache2/mods-enabled/status.conf
<IfModule mod_status.c>
#
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
# Uncomment and change the "192.0.2.0/24" to allow access from other hosts.
#
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1 ::1
#    Allow from 192.0.2.0/24
</Location>

# Keep track of extended status information for each request
ExtendedStatus On

# Determine if mod_status displays the first 63 characters of a request or
# the last 63, assuming the request itself is greater than 63 chars.
# Default: Off
#SeeRequestTail On

<IfModule mod_proxy.c>
    # Show Proxy LoadBalancer status in mod_status
    ProxyStatus On
</IfModule>

</IfModule>

Or we can configure the default host like this when we are working with web

vim /etc/apache2/sites-available/default
<VirtualHost localhost:80>
    ServerAdmin webmaster@localhost
    ServerName localhost
    DocumentRoot /var/www
    <Directory />
        Options FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1 ::1
    </Directory>
    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1 ::1
    </Directory>

    #ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    #<Directory "/usr/lib/cgi-bin">
#        AllowOverride None
#        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
#        Order allow,deny
#        Allow from all
#    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Here we enable the access to the server-status only for the localhost.

Enable the virtual host

a2ensite default

Now need to restart the apache

/etc/init.d/apache2 restart

We can test with the follow command

lynx http://127.0.0.1/server-status

For CentOS 6.5

vim /etc/httpd/conf/httpd.conf
[...]
ExtendedStatus On
[...]
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost
</Location>

In some cases the server-status doesn't work properly in CentOS, therefore we need to create a virtualhost for localhost as follows

vim /etc/httpd/conf.d/localhost.conf 
<VirtualHost localhost:80>
    ServerAdmin webmaster@localhost
    ServerName localhost
    DocumentRoot /var/www
    <Directory />
        Options FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1 ::1
    </Directory>
    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1 ::1
    </Directory>
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1 ::1
</Location>
</VirtualHost>

Now we need to restart the apache server

/etc/init.d/httpd restart

We need to download the tarball for our Desktop client and import the template file the url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_apache_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

Now we can see the information about the lastest data from Zabbix Server, just expand the + icon and click in Graph to see the graph about the resource.

If we need to monitoring the PostgreSQL we need to do the follows intructions

We need to create the home directory to Zabbix

mkdir /var/lib/zabbix
chown -R zabbix:zabbix /var/lib/zabbix

Now we need to create the user for zabbix, here I'll use the password: secretP4ssw0rd

su postgres
createuser -s -P zabbix-monitor
exit

Now we need to create the file that will containg the password for zabbix

cd /var/lib/zabbix
echo "127.0.0.1:5432:*:zabbix-monitor:secretP4ssw0rd" > .pgpass

Now we need to configure the permission

chown zabbix:zabbix .pgpass
chmod 0600 .pgpass

Now we need to grant permission to zabbix to get information about the postgresql logs

chgrp zabbix /var/log/postgresql/postgresql-9.1-main.log

Now we need to configure the logrotate like this

vim /etc/logrotate.d/postgresql-common
/var/log/postgresql/*.log {
       weekly
       rotate 10
       copytruncate
       delaycompress
       compress
       notifempty
       missingok
       create 0640 postgres zabbix
       su root root
}

Now we need to create the configuration for postgre zabbix client like this

vim /etc/zabbix/zabbix_agentd.d/config-pgsql.conf
# PostgreSQL user parameter

#
# Server specific examples
#
# Get the total number of committed transactions
UserParameter=psql.tx_committed[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select sum(xact_commit) from pg_stat_database"
# Get the total number of rolled back transactions
UserParameter=psql.tx_rolledback[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select sum(xact_rollback) from pg_stat_database"
# Max Connections
UserParameter=psql.server_maxcon[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "show max_connections"
# PostgreSQL is running
UserParameter=psql.running[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select 1" > /dev/null 2>&1 ; echo $?

# Added by SRA OSS
# Get number of checkpoint count (by checkpoint_timeout)
UserParameter=psql.checkpoints_timed[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select checkpoints_timed from pg_stat_bgwriter"
# Get number of checkpoint count (by checkpoint_segments)
UserParameter=psql.checkpoints_req[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select checkpoints_req from pg_stat_bgwriter"
# Get the total number of connections
UserParameter=psql.server_connections[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(*) from pg_stat_activity;"
# Get the total number of active (on processing SQL) connections
UserParameter=psql.active_connections[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(current_query) from pg_stat_activity where current_query <> '<IDLE>'"
# Get the total number of idle connections
UserParameter=psql.idle_connections[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(current_query) from pg_stat_activity where current_query = '<IDLE>'"
# Get the total number of idle in transaction connections
UserParameter=psql.idle_tx_connections[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(current_query) from pg_stat_activity where current_query = 'idle in transaction'"
# Get the total number of lock-waiting connections
UserParameter=psql.locks_waiting[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(*) from pg_stat_activity where waiting = 't'"

# Get buffer information
UserParameter=psql.buffers_checkpoint[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select buffers_checkpoint from pg_stat_bgwriter"
UserParameter=psql.buffers_clean[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select buffers_clean from pg_stat_bgwriter"
UserParameter=psql.maxwritten_clean[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select maxwritten_clean from pg_stat_bgwriter"
UserParameter=psql.buffers_backend[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select buffers_backend from pg_stat_bgwriter"
UserParameter=psql.buffers_backend_fsync[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select buffers_backend_fsync from pg_stat_bgwriter"
UserParameter=psql.buffers_alloc[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select buffers_alloc from pg_stat_bgwriter"

# Get number of slow queries
UserParameter=psql.slow_queries[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(*) from pg_stat_activity where current_query <> '<IDLE>' and now() - query_start > '$5 sec'::interval"
UserParameter=psql.slow_select_queries[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(*) from pg_stat_activity where current_query <> '<IDLE>' and now() - query_start > '$5 sec'::interval and current_query ilike 'select%'"
UserParameter=psql.slow_dml_queries[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select count(*) from pg_stat_activity where current_query <> '<IDLE>' and now() - query_start > '$5 sec'::interval and current_query ~* '^(insert|update|delete)'"

#
# Database specific examples
#
# Get the size of a Database (in bytes)
UserParameter=psql.db_size[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select pg_database_size('$5') from pg_database where datname = '$5'"
# Get number of active connections for a specified database
UserParameter=psql.db_connections[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select numbackends from pg_stat_database where datname = '$5'"
# Get number of tuples returned for a specified database
UserParameter=psql.db_returned[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select tup_returned from pg_stat_database where datname = '$5'"
# Get number of tuples fetched for a specified database
UserParameter=psql.db_fetched[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select tup_fetched from pg_stat_database where datname = '$5'"
# Get number of tuples inserted for a specified database
UserParameter=psql.db_inserted[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select tup_inserted from pg_stat_database where datname = '$5'"
# Get number of tuples updated for a specified database
UserParameter=psql.db_updated[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select tup_updated from pg_stat_database where datname = '$5'"
# Get number of tuples deleted for a specified database
UserParameter=psql.db_deleted[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select tup_deleted from pg_stat_database where datname = '$5'"
# Get number of committed/rolled back transactions for a specified database
UserParameter=psql.db_tx_committed[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select xact_commit from pg_stat_database where datname = '$5'"
UserParameter=psql.db_tx_rolledback[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select xact_rollback from pg_stat_database where datname = '$5'"

# Cache Hit Ratio
UserParameter=psql.cachehit_ratio[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "SELECT round(blks_hit*100/(blks_hit+blks_read), 2) AS cache_hit_ratio FROM pg_stat_database WHERE datname = '$5' and blks_read > 0 union all select 0.00 AS cache_hit_ratio order by cache_hit_ratio desc limit 1"

# Added by SRA OSS
# Get number of temp files
UserParameter=psql.db_temp_files[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select temp_files from pg_stat_database where datname = '$5'"
# Get temp file size (in bytes)
UserParameter=psql.db_temp_bytes[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select temp_bytes from pg_stat_database where datname = '$5'"
# Get percentage of dead tuples of all tables for a specified database
UserParameter=psql.db_dead_tup_ratio[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select round(sum(n_dead_tup)*100/sum(n_live_tup+n_dead_tup), 2) as dead_tup_ratio from pg_stat_all_tables where n_live_tup > 0"
# Get number of deadlocks for a specified database (9.2 or later)
UserParameter=psql.db_deadlocks[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select deadlocks from pg_stat_database where datname = '$5'"

#
# Table specific examples
#
# Get table cache hit ratio of a specific table
UserParameter=psql.table_cachehit_ratio[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select round(heap_blks_hit*100/(heap_blks_hit+heap_blks_read), 2) as cache_hit_ratio from pg_statio_user_tables where schemaname = '$5' and relname = '$6' and heap_blks_read > 0 union all select 0.00 as cache_hit_ratio order by cache_hit_ratio desc limit 1"
# Get number of sequencial scan of a specific table
UserParameter=psql.table_seq_scan[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select seq_scan from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
# Get number of index scan of a specific table
UserParameter=psql.table_idx_scan[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select coalesce(idx_scan,0) from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
# Get number of vacuum count of a specific table
UserParameter=psql.table_vacuum_count[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select vacuum_count from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
# Get number of analyze count of a specific table
UserParameter=psql.table_analyze_count[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select analyze_count from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
# Get number of autovacuum count of a specific table
UserParameter=psql.table_autovacuum_count[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select autovacuum_count from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
# Get number of autoanalyze count of a specific table
UserParameter=psql.table_autoanalyze_count[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select autoanalyze_count from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"

# Get number of tuples of a specific table
UserParameter=psql.table_n_tup_ins[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select n_tup_ins from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_n_tup_upd[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select n_tup_upd from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_n_tup_del[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select n_tup_del from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_seq_tup_read[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select seq_tup_read from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_idx_tup_fetch[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select coalesce(idx_tup_fetch,0) from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_n_tup_hot_upd[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select n_tup_hot_upd from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_n_live_tup[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select n_live_tup from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"
UserParameter=psql.table_n_dead_tup[*],psql -h $1 -p $2 -U $3 -d $4 -t -c "select n_dead_tup from pg_stat_user_tables where schemaname = '$5' and relname = '$6'"

#
# Discovery Rule
#
# Database Discovery
UserParameter=db.list.discovery[*],$5/find_dbname.sh $1 $2 $3 $4
UserParameter=db_table.list.discovery[*],$5/find_dbname_table.sh $1 $2 $3 $4

Now we need to configure more two files the first one will get the database list

vim /usr/local/bin/find_dbname.sh
#!/bin/bash

# Get list of Database Name which you want to monitor.
# The default settings are excepted template databases(template0/template1).
#
# :Example
#
# If you want to monitor "foo" and "bar" databases, you set the GETDB as
# GETDB="select datname from pg_database where datname in ('foo','bar');"

GETDB="select datname from pg_database where datistemplate = 'f';"

for dbname in $(psql -h $1 -p $2 -U $3 -d $4 -t -c "${GETDB}"); do
    dblist="$dblist,"'{"{#DBNAME}":"'$dbname'"}'
done
echo '{"data":['${dblist#,}' ]}'

Now we need to configure the another that will get the tables

vim /usr/local/bin/find_dbname_table.sh
#!/bin/bash

# This low level discovery rules are disabled by deafult.
# For using this rules, you set the status to enable from
# [Configuration]->[Hosts]->[Discovery]->[DB and Table Name List]
# at Zabbix WEB.

# Get list of Database Name which you want to monitor.
# The default settings are excepted template databases(template0/template1).
#
# :Customize Example
#
# For "foo" and "bar" databases, set the GETDB as
# GETDB="select datname from pg_database where datname in ('foo','bar');"

GETDB="select datname from pg_database where datistemplate = 'f';"

# Get List of Table Name
# Using the default setting, Zabbix make a discovery "ALL" user tables.
# If you want to specify the tables, you can change the $GETTABLE query.
#
# :Customize Example
#
# For pgbench tables, set the GETTABLE as
#GETTABLE="select \
#            row_to_json(t) \
#          from (
#            select current_database() as "{#DBNAME}\",schemaname as \"{#SCHEMANAME}\",tablename as \"{#TABLENAME}\" \
#            from \
#              pg_tables \
#            where \
#              schemaname not in ('pg_catalog','information_schema') \
#            and \
#              tablename in ('pgbench_accounts','pgbench_branches','pgbench_history','pgbench_tellers') \
#           ) as t"

GETTABLE="select row_to_json(t) from (select current_database() as \"{#DBNAME}\",schemaname as \"{#SCHEMANAME}\",tablename as \"{#TABLENAME}\" from pg_tables where schemaname not in ('pg_catalog','information_schema')) as t"

for dbname in $(psql -h $1 -p $2 -U $3 -d $4 -t -c "${GETDB}"); do
    for tablename in $(psql -h $1 -p$2 -U $3 -d $dbname -t -c "${GETTABLE}"); do
    dblist="$dblist,"$tablename
    done
done
echo '{"data":['${dblist#,}' ]}'

Now we can restart the zabbix agent

/etc/init.d/zabbix-agent restart

Now we need to change the permission for those scripts

chmod +x /usr/local/bin/find_dbname*

Now let's run a test

zabbix_get -s127.0.0.1 -p10050 -kpsql.checkpoints_timed[127.0.0.1,5432,zabbix-monitor,postgres]
                 1

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_postgresql_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

To monitoring the Bind we need to enable the feature on the Bind, however the Bind comes without that feature therewith we'll enable it and install the bind9.

Installing the prerequisites for compile the Bind

aptitude install autopoint autotools-dev bison debhelper dh-apparmor geoip-bin gettext hardening-wrapper html2text intltool-debian \
libbison-dev libcap-dev libdb-dev libdb5.1-dev libgeoip-dev libgettextpo0 libltdl-dev libmail-sendmail-perl libsys-hostname-long-perl \
libtool libunistring0 libxml2-dev libxml2 po-debconf libxslt-dev  zlib1g-dev xml2 curl -y

Now we need to install the dependecies for Bind

apt-get build-dep bind9 -y

Now let's get the sources like this

cd /usr/src
apt-get source bind9

Now we need to access the directory

cd bind9-*

Now we need to add the new feature to Bind

vim debian/rules
[...]
                --with-gnu-ld \
                --with-geoip=/usr \
                --with-libxml2 \
                --enable-ipv6 \

Now we need to create the packet with the new feature

dpkg-buildpackage

Now let's install the packet

cd ..
dpkg -i *.deb

Now let's check the packet if it is ok

named -V
BIND 9.8.4-rpz2+rl005.12-P1 built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-geoip=/usr' '--enable-ipv6' '--with-libxml2' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2'
using OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013
using libxml2 version: 2.8.0

Now need to enable the statics only for the localhost and my machine to make sure that everything is ok.

vim /etc/bind/named.conf.options
[...]

#Put it out of the options directive
statistics-channels {
    inet 192.168.1.100 port 8053 allow { 192.168.1.254; };
    inet 127.0.0.1 port 8053 allow { 127.0.0.1; };
};

Now need to enable the monitoring in all zones that you want to get information like this

zone "douglasqsantos.com.br" {
        type master;
        file "/etc/bind/db.douglasqsantos.com.br.internal";
        zone-statistics yes;
};
[...]
zone "1.168.192.in-addr.arpa" {
        type master;
        file "/etc/bind/db.1.168.192.internal";
        zone-statistics yes;
};

Now let's create the python script to get the bind information liket this.

vim /usr/local/bin/z-bind-stats
#!/usr/bin/python

import time
import sys
import os
import argparse
import json

JSONFILE = '/tmp/bindstats.json'
CACHELIFE = 300

parser = argparse.ArgumentParser()
parser.add_argument("action", help="discoverzones | counter | zonecounter | zonemaintenancecounter | resolvercounter | socketcounter | incounter | outcounter")
parser.add_argument("-z", help="zone")
parser.add_argument("-c", help="counter name")
parser.add_argument("-p", help="bind stats port")
args = parser.parse_args()

# Configurable port
port = 8053
if args.p:
  port = args.p

# Read from the cache if it exists and is less than a minute old, so we don't hit Bind directly too often.
if os.path.exists(JSONFILE) and time.time() - os.path.getmtime(JSONFILE) <= CACHELIFE:
  f = open(JSONFILE)
  j = json.load(f)
  f.close()
else:
  import httplib
  conn = httplib.HTTPConnection('localhost:{0}'.format(port))
  conn.request('GET', '/')
  resp = conn.getresponse()
  if not resp.status == 200:
    print >> sys.stderr, "HTTP GET Failed"
    sys.exit(1)
  content = resp.read()
  conn.close()

  import xml.etree.ElementTree as ET
  root = ET.fromstring(content)

  # Build the JSON cache
  j = {
      'zones': {},
      'counter': {},
      'zonemaintenancecounter': {},
      'resolvercounter': {},
      'socketcounter': {},
      'incounter': {},
      'outcounter': {},
      }
  for view in root.findall('./bind/statistics/views/view'):
    if view.findtext('./name') in ('_default',):
      for zone in view.findall('./zones/zone'):
        if zone.find('./counters') is not None:
          counters = {}
          for counter in zone.findall('./counters/*'):
            counters[counter.tag] = counter.text
          j['zones'][zone.findtext('./name')] = counters
  for stat in root.findall('./bind/statistics/server/nsstat'):
    j['counter'][stat.findtext('./name')] = stat.findtext('./counter')
  for stat in root.findall('./bind/statistics/server/zonestat'):
    j['zonemaintenancecounter'][stat.findtext('./name')] = stat.findtext('./counter')
  for view in root.findall('./bind/statistics/views/view'):
    if view.findtext('./name') in ('_default',):
      for stat in view.findall('./resstat'):
        j['resolvercounter'][stat.findtext('./name')] = stat.findtext('./counter')
  for stat in root.findall('./bind/statistics/server/sockstat'):
    j['socketcounter'][stat.findtext('./name')] = stat.findtext('./counter')
  for stat in root.findall('./bind/statistics/server/queries-in/rdtype'):
    j['incounter'][stat.findtext('./name')] = stat.findtext('./counter')
  for stat in root.findall('./bind/statistics/views/view/rdtype'):
    j['outcounter'][stat.findtext('./name')] = stat.findtext('./counter')

  f = open(JSONFILE, 'w')
  json.dump(j, f)
  f.close()

if args.action == 'discoverzones':
  d = { 'data': [{'{#ZONE}': zone} for zone in j['zones'].keys()] }
  print json.dumps(d)
  sys.exit(0)

elif args.action == 'zonecounter':
  if not (args.z and args.c):
    print >> sys.stderr, "Missing argument"
    print "ZBX_NOTSUPPORTED"
    sys.exit(1)
  if j['zones'].has_key(args.z) and j['zones'][args.z].has_key(args.c):
    print j['zones'][args.z][args.c]
    sys.exit(0)
  else:
    print "ZBX_NOTSUPPORTED"
    sys.exit(1)

else:
  if not args.c:
    print >> sys.stderr, "Missing argument"
    print "ZBX_NOTSUPPORTED"
    sys.exit(1)
  if j[args.action].has_key(args.c):
    print j[args.action][args.c]
    sys.exit(0)
  else:
    print "ZBX_NOTSUPPORTED"
    sys.exit(1)

Now let's change the permissions like this

chmod +x /usr/local/bin/z-bind-stats

Now we need to create the configuration file for zabbix agent like this

vim /etc/zabbix/zabbix_agentd.d/config-bind.conf 
UserParameter=bind.discoverzones,/usr/local/bin/z-bind-stats discoverzones
UserParameter=bind.counter[*],/usr/local/bin/z-bind-stats counter -c $1
UserParameter=bind.zonecounter[*],/usr/local/bin/z-bind-stats zonecounter -z $1 -c $2
UserParameter=bind.zonemaintenancecounter[*],/usr/local/bin/z-bind-stats zonemaintenancecounter -c $1
UserParameter=bind.resolvercounter[*],/usr/local/bin/z-bind-stats resolvercounter -c $1
UserParameter=bind.socketcounter[*],/usr/local/bin/z-bind-stats socketcounter -c $1
UserParameter=bind.incounter[*],/usr/local/bin/z-bind-stats incounter -c $1
UserParameter=bind.outcounter[*],/usr/local/bin/z-bind-stats outcounter -c $1

Now we need to restart the zabbix Agent and the Bind

/etc/init.d/bind9 restart
/etc/init.d/zabbix-agent restart

Now let's run a test with the new template

zabbix_get -s127.0.0.1 -p10050 -kbind.discoverzones
{"data": [{"{#ZONE}": "1.168.192.in-addr.arpa/IN"}, {"{#ZONE}": "douglasqsantos.com.br/IN"}, {"{#ZONE}": "255.in-addr.arpa/IN"}, {"{#ZONE}": "localhost/IN"}]}

If you got something like this

zabbix_get -s127.0.0.1 -p10050 -kbind.discoverzones
Traceback (most recent call last):
  File "/usr/local/bin/z-bind-stats", line 32, in <module>
    conn.request('GET', '/')
  File "/usr/lib/python2.7/httplib.py", line 962, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 996, in _send_request
    self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 958, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 818, in _send_output
    self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 780, in send
    self.connect()
  File "/usr/lib/python2.7/httplib.py", line 761, in connect
    self.timeout, self.source_address)
  File "/usr/lib/python2.7/socket.py", line 571, in create_connection
    raise err
socket.error: [Errno 111] Connection refused

Need to restart the bind and test again.

zabbix_get -s127.0.0.1 -p10050 -kbind.discoverzones
{"data": [{"{#ZONE}": "255.in-addr.arpa/IN"}, {"{#ZONE}": "localhost/IN"}]}

It's working properly.

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_bind9_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

To monitoring the Bind we need to enable the feature on the Bind, however the Bind comes without that feature therewith we'll enable it and install the bind9.

Installing the prerequisites for compile the Bind

aptitude install autopoint autotools-dev bison debhelper dh-apparmor geoip-bin gettext hardening-wrapper html2text intltool-debian \
libbison-dev libcap-dev libdb-dev libdb5.1-dev libgeoip-dev libgettextpo0 libltdl-dev libmail-sendmail-perl libsys-hostname-long-perl \
libtool libunistring0 libxml2-dev libxml2 po-debconf libxslt-dev  zlib1g-dev xml2 curl -y

Now we need to install the dependecies for Bind

apt-get build-dep bind9 -y

Now let's get the sources like this

cd /usr/src
apt-get source bind9

Now we need to access the directory

cd bind9-*

Now we need to add the new feature to Bind

vim debian/rules
[...]
                --with-gnu-ld \
                --with-geoip=/usr \
                --with-libxml2 \
                --enable-ipv6 \

Now we need to create the packet with the new feature

dpkg-buildpackage

Now let's install the packet

cd ..
dpkg -i *.deb

Now let's check the packet if it is ok

named -V
BIND 9.8.4-rpz2+rl005.12-P1 built with '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc/bind' '--localstatedir=/var' '--enable-threads' '--enable-largefile' '--with-libtool' '--enable-shared' '--enable-static' '--with-openssl=/usr' '--with-gssapi=/usr' '--with-gnu-ld' '--with-geoip=/usr' '--enable-ipv6' '--with-libxml2' 'CFLAGS=-fno-strict-aliasing -DDIG_SIGCHASE -O2'
using OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013
using libxml2 version: 2.8.0

Now need to enable the statics only for the localhost and my machine to make sure that everything is ok.

vim /etc/bind/named.conf.options
[...]

#Put it out of the options directive
statistics-channels {
    inet 192.168.1.100 port 8053 allow { 192.168.1.254; };
    inet 127.0.0.1 port 8053 allow { 127.0.0.1; };
};

Now need to enable the monitoring in all zones that you want to get information like this

zone "douglasqsantos.com.br" {
        type master;
        file "/etc/bind/db.douglasqsantos.com.br.internal";
        zone-statistics yes;
};
[...]
zone "1.168.192.in-addr.arpa" {
        type master;
        file "/etc/bind/db.1.168.192.internal";
        zone-statistics yes;
};

Now we need to create the configuration file for zabbix agent like this

vim /etc/zabbix/zabbix_agentd.d/config-dns.conf 
UserParameter=bind.queries.in[*],curl http://localhost:8053/ 2>/dev/null | xml2 | grep -A1 "/isc/bind/statistics/server/queries-in/rdtype/name=$1$" | tail -1 | cut -d= -f2
UserParameter=bind.queries.out[*],curl http://localhost:8053/ 2>/dev/null | xml2 | grep -A1 "/isc/bind/statistics/views/view/rdtype/name=$1$" | tail -1 | cut -d= -f2

Now we need to restart the zabbix Agent and the Bind

/etc/init.d/bind9 restart
/etc/init.d/zabbix-agent restart

Now let's run a test with the new template

zabbix_get -s 127.0.0.1 -k bind.queries.out[A]
37

It's working properly.

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_bind9_simple_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

Now we need to install the depencies to the template

aptitude install pflogsumm logtail zabbix-sender -y

For CentOS 6

Installing the dependences

yum install perl-Date-Calc -y

Getting the sources files

cd /tmp 
wget -c http://mirror.centos.org/centos/5/centosplus/x86_64/RPMS/postfix-pflogsumm-2.3.3-7.0.1.el5.centos.x86_64.rpm
wget -c http://download.opensuse.org/distribution/13.2/repo/oss/suse/x86_64/logtail-0.2.4-18.1.2.x86_64.rpm

Now let's install the packets

rpm -ivh logtail-0.2.4-18.1.2.x86_64.rpm
rpm -ivh postfix-pflogsumm-2.3.3-7.0.1.el5.centos.x86_64.rpm

Now we need to create the zabbix client for postfix

vim /etc/zabbix/zabbix_agentd.d/config-postfix.conf
UserParameter=pfmailq,/usr/bin/mailq | grep -v "Mail queue is empty" | grep -c '^[0-9A-Z]'
UserParameter=pfversion,sudo /usr/sbin/postconf -d mail_version | awk '{print $3}'

Now we need to restart the zabbix-agent

/etc/init.d/zabbix-agent restart

Now we need to create the script that will delivery the information about the email to zabbix

vim /usr/local/sbin/zabbix-postfix.sh
#!/bin/bash
## Changed by Douglas Q. dos Santos
## Created the function conv and added variable ZABBIX_SERVER
 
MAILLOG=/var/log/mail.log
LOGTAIL=/usr/sbin/logtail
DAT1=/tmp/zabbix-postfix-offset.dat
DAT2=$(mktemp)
PFLOGSUMM=/usr/sbin/pflogsumm
ZABBIX_CONF=/etc/zabbix/zabbix_agentd.conf
ZABBIX_SERVER=172.17.0.117
 
function zsend {
 /usr/bin/zabbix_sender -c $ZABBIX_CONF -k $1 -o $2 -z $ZABBIX_SERVER
}

function conv {
VER=$1
MULT=$(echo $VER | egrep -io '[a-z]')

case $MULT in
  k)  
    CAL=$(echo $VER | tr 'a-z' ' ')
          RETR=$(($CAL * 1024))
          echo $RETR
  ;;
  m)
          CAL=$(echo $VER | tr 'a-z' ' ')
          RETR=$(($CAL * 1048576))
          echo $RETR
  ;;
  g)
    CAL=$(echo $VER | tr 'a-z' ' ')
          RETR=$(($CAL * 1073741824 ))
          echo $RETR
  ;;
  *)
  echo $VER
  ;;
esac
}
 
#${LOGTAIL} -f$MAILLOG -o$DAT1 | $PFLOGSUMM -h 0 -u 0 --bounce-detail=0 --deferral-detail=0 --reject-detail=0 --no_no_msg_size --smtpd-warning-detail=0 > $DAT2
${LOGTAIL} -f$MAILLOG -o$DAT1 | $PFLOGSUMM -h 0 -u 0 --no_bounce_detail --no_deferral_detail --no_reject_detail --no_no_msg_size --no_smtpd_warnings > $DAT2

NEEDS_CONV=$(grep -m 1 received $DAT2|cut -f1 -d"r")
CONV=$(conv $NEEDS_CONV)
zsend pfreceived $CONV
NEEDS_CONV=$(grep -m 1 delivered $DAT2|cut -f1 -d"d")
CONV=$(conv $NEEDS_CONV)
zsend pfdelivered $CONV
NEEDS_CONV=$(grep -m 1 forwarded $DAT2|cut -f1 -d"f")
CONV=$(conv $NEEDS_CONV)
zsend pfforwarded $CONV
NEEDS_CONV=$(grep -m 1 deferred $DAT2|cut -f1 -d"d")
CONV=$(conv $NEEDS_CONV)
zsend pfdeferred $CONV
NEEDS_CONV=$(grep -m 1 bounced $DAT2|cut -f1 -d"b")
CONV=$(conv $NEEDS_CONV)
zsend pfbounced $CONV
NEEDS_CONV=$(grep -m 1 rejected $DAT2|cut -f1 -d"r")
CONV=$(conv $NEEDS_CONV)
zsend pfrejected $CONV
NEEDS_CONV=$(grep -m 1 "reject warnings" $DAT2|cut -f1 -d"r")
CONV=$(conv $NEEDS_CONV)
zsend pfrejectwarnings $CONV
NEEDS_CONV=$(grep -m 1 held $DAT2|cut -f1 -d"h")
CONV=$(conv $NEEDS_CONV)
zsend pfheld $CONV
NEEDS_CONV=$(grep -m 1 discarded $DAT2|cut -f1 -d"d")
CONV=$(conv $NEEDS_CONV)
zsend pfdiscarded $CONV
NEEDS_CONV=$(grep -m 1 "bytes received" $DAT2|cut -f1 -d"b")
CONV=$(conv $NEEDS_CONV)
zsend pfbytesreceived $CONV
NEEDS_CONV=$(grep -m 1 "bytes delivered" $DAT2|cut -f1 -d"b")
CONV=$(conv $NEEDS_CONV)
zsend pfbytesdelivered $CONV
 
rm $DAT2

Now we need to change the permissions

chmod +x /usr/local/sbin/zabbix-postfix.sh

Now we need to create an schedule in the contrab like this

crontab -e
[...]
*/1 * * * * root   /usr/local/sbin/zabbix-postfix.sh

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_postfix_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

We need to install the squidclient that will be used by the zabbix client for squid

aptitude install squidclient -y

Now we need to create some entries for hosts like this

vim /etc/hosts
127.0.0.1    localhost
192.168.1.100    debian100.douglasqsantos.com.br    debian100

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Now need to reboot the server.

Issues:

Now we need to create the zabbix client file for squid like this

vim /etc/zabbix/zabbix_agentd.d/config-squid.conf
UserParameter=squid.http_requests,squidclient mgr:info 2> /dev/null |grep 'Number of HTTP requests received:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.clients,squidclient mgr:info 2> /dev/null |grep 'Number of clients accessing cache:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.icp_received,squidclient mgr:info 2> /dev/null |grep 'Number of ICP messages received:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.icp_sent,squidclient mgr:info 2> /dev/null |grep 'Number of ICP messages sent:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.icp_queued,squidclient mgr:info 2> /dev/null |grep 'Number of queued ICP replies:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.htcp_received,squidclient mgr:info 2> /dev/null |grep 'Number of HTCP messages received:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.htcp_sent,squidclient mgr:info 2> /dev/null |grep 'Number of HTCP messages sent:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.req_fail_ratio,squidclient mgr:info 2> /dev/null |grep 'Request failure ratio:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.avg_http_req_per_min,squidclient mgr:info 2> /dev/null |grep 'Average HTTP requests per minute since start:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.avg_icp_msg_per_min,squidclient mgr:info 2> /dev/null |grep 'Average ICP messages per minute since start:'|cut -d':' -f2| tr -d ' \t'
UserParameter=squid.request_hit_ratio,squidclient mgr:info 2> /dev/null | grep 'Hits as % of all requests:'| cut -d':' -f3 | cut -d',' -f1 | tr -d ' %'
UserParameter=squid.byte_hit_ratio,squidclient mgr:info 2> /dev/null |grep 'Hits as % of bytes sent:' |cut -d':' -f3|cut -d',' -f1|tr -d ' %'
UserParameter=squid.request_mem_hit_ratio,squidclient mgr:info 2> /dev/null  | grep 'Memory hits as % of hit requests:' | cut -d':' -f3|cut -d',' -f1|tr -d ' %'
UserParameter=squid.request_disk_hit_ratio,squidclient mgr:info 2> /dev/null  | grep 'Disk hits as % of hit requests:' | cut -d':' -f3|cut -d',' -f1|tr -d ' %'
UserParameter=squid.servicetime_httpreq,squidclient mgr:info 2> /dev/null |grep 'HTTP Requests (All):'|cut -d':' -f2|tr -s ' '|awk '{print $1}'
UserParameter=squid.process_mem,squidclient mgr:info 2> /dev/null |grep 'Process Data Segment Size via sbrk'|cut -d':' -f2|awk '{print $1}'
UserParameter=squid.cpu_usage,squidclient mgr:info 2> /dev/null |grep 'CPU Usage:'|cut -d':' -f2|tr -d '%'|tr -d ' \t'
UserParameter=squid.cache_size_disk,squidclient mgr:info 2> /dev/null |grep 'Storage Swap size:'|cut -d':' -f2|awk '{print $1}'
UserParameter=squid.cache_size_mem,squidclient mgr:info 2> /dev/null |grep 'Storage Mem size:'|cut -d':' -f2|awk '{print $1}'
UserParameter=squid.mean_obj_size,squidclient mgr:info 2> /dev/null |grep 'Mean Object Size:'|cut -d':' -f2|awk '{print $1}'
UserParameter=squid.filedescr_max,squidclient mgr:info 2> /dev/null |grep 'Maximum number of file descriptors:'|cut -d':' -f2|awk '{print $1}'
UserParameter=squid.filedescr_avail,squidclient mgr:info 2> /dev/null |grep 'Available number of file descriptors:'|cut -d':' -f2|awk '{print $1}'
UserParameter=squid.uptime,squidclient mgr:info 2> /dev/null |grep 'UP Time:' | awk '{print $3}'
UserParameter=squid.version,squidclient mgr:info 2> /dev/null  | grep -i 'server' | awk '{print $2}' | cut -d '/' -f 2

Now we need to restart the zabbix-agent

/etc/init.d/zabbix-agent restart

Let's run a test

zabbix_get -s 127.0.0.1 -k "squid.version"
3.1.6

For CentOS

vim /etc/squid/squid.conf
[...]
##withou the line below the squidclient does not work.
http_access allow manager
http_access allow manager localhost
http_access deny manager

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_squid_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

Here we will monitoring the disk performance, I'll use a python script to get the information you can use other one.

Let's create the zabbix client file like this

vim /etc/zabbix/zabbix_agentd.d/config-diskstats.conf 
UserParameter=custom.vfs.discover_disks,/usr/local/bin/check_disks.py
UserParameter=custom.vfs.dev.read.ops[*],cat /proc/diskstats | grep $1 | head -1         | awk '{print $$4}'
UserParameter=custom.vfs.dev.read.merged[*],cat /proc/diskstats | grep $1 | head -1      | awk '{print $$5}'
UserParameter=custom.vfs.dev.read.sectors[*],cat /proc/diskstats | grep $1 | head -1     | awk '{print $$6}'
UserParameter=custom.vfs.dev.read.ms[*],cat /proc/diskstats | grep $1 | head -1          | awk '{print $$7}'
UserParameter=custom.vfs.dev.write.ops[*],cat /proc/diskstats | grep $1 | head -1        | awk '{print $$8}'
UserParameter=custom.vfs.dev.write.merged[*],cat /proc/diskstats | grep $1 | head -1     | awk '{print $$9}'
UserParameter=custom.vfs.dev.write.sectors[*],cat /proc/diskstats | grep $1 | head -1    | awk '{print $$10}'
UserParameter=custom.vfs.dev.write.ms[*],cat /proc/diskstats | grep $1 | head -1         | awk '{print $$11}'
UserParameter=custom.vfs.dev.io.active[*],cat /proc/diskstats | grep $1 | head -1        | awk '{print $$12}'
UserParameter=custom.vfs.dev.io.ms[*],cat /proc/diskstats | grep $1 | head -1            | awk '{print $$13}'

Now we need to create the python script like this

vim /usr/local/bin/check_disks.py
#!/usr/bin/python

import json
import subprocess

def main():
    output = subprocess.check_output("cat /proc/diskstats | awk '{print $3}' | grep -v 'ram\|loop\|sr'", shell=True)
    data = list()
    for line in output.split("\n"):
        if line:
          data.append({"{#DEVICE}": line, "{#DEVICENAME}": line.replace("/dev/", "")})

    print(json.dumps({"data": data}, indent=4))

if __name__ == '__main__': main()

Now we need to change the permissions like this

chmod +x /usr/local/bin/check_disks.py

Now restart the zabbix agent like this

/etc/init.d/zabbix-agent restart

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_disk_performance_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

We need to create the zabbix client file like this

vim /etc/zabbix/zabbix_agentd.d/config-samba.conf 
UserParameter=samba_process,sudo /usr/bin/smbstatus -p -b 2> /dev/null  | egrep -v '^$' | egrep -v "^(PID|Samba|--)" | wc -l
UserParameter=samba_locked,sudo /usr/bin/smbstatus -L -b 2> /dev/null | egrep -v '^$' | egrep -v "^(Locked|Pid|--|No)"  | wc -l
UserParameter=samba_connected_shares,sudo /usr/bin/smbstatus -S 2> /dev/null | egrep -v '^$' | egrep -v "^(Service|--)" | wc -l
UserParameter=samba_shares,sudo /usr/bin/testparm -s 2> /dev/null  | egrep '^\[' | egrep -v '\[glo' | wc -l
UserParameter=sambaversion,sudo /usr/sbin/smbd -V | awk '{print $2}'

Now we need to create the sudo configuration like this

visudo
[...]
Cmnd_Alias ZCMD = /usr/bin/smbstatus, /usr/bin/testparm
zabbix ALL = NOPASSWD: ZCMD

Now we need to restart the zabbix agent like this

/etc/init.d/zabbix-agent restart

We can run a test like this

zabbix_get -s 127.0.0.1 -k "samba_shares"
3

Now we need to get the template to load on the Frontend we can get it in the follow url: http://wiki.douglasqsantos.com.br/Downloads/monitoring/zbx_named_templates.xml.zip

  • Now in Configuration/Templates
  • On the right corner click on Import
  • Click in Browse and Import the template-name.xml and click Open
  • Now click on Import
  • We shall get a warning about the file was imported with successfully

Now we need to add the Template to the Zabbix Server

  • Now in Configuration/Hosts
  • Click on Zabbix server
  • Now Click on Template
  • Now select the Template: Template Name
  • Click on Add
  • Click on Update

Now in the Frontend:

  • Monitoring/Latest Data
    • Click in the Show filter that is on the middle of the screen with two down arrows
    • Check the Show items without data
    • In Hosts: select the Zabbix Server
    • Click in Filter

Enabling Alerts

We need to configure the Postfix to send e-mail with an authenticated account therewith we need to use an account with user and password, here I'll configure with a Gmail Account.

Let's installs the prerequisites

aptitude install libsasl2-modules postfix -y

Now we need to configure the Postfix to send the e-mails like this

vim /etc/postfix/main.cf 
# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname = debian.douglasqsantos.com.br
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = debian.douglasqsantos.com.br, localhost.douglasqsantos.com.br, , localhost

## Need to set up the mail server and the port like this.
relayhost = [smtp.gmail.com]:587


mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

### Authentication on Gmail
smtp_use_tls=yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_sasl_security_options =
## Enable the follow lines with you need to debug the process
#debug_peer_list=smtp.gmail.com
#debug_peer_level=3

Now we need to create the file with the information needs to authenticate

vim /etc/postfix/sasl_passwd
[smtp.gmail.com]:587  email@gmail.com:AbkFJk7n5u59DS4

Now we need to convert the file like this

postmap /etc/postfix/sasl_passwd

Now we need to change the permissions like this

chown postfix /etc/postfix/sasl_passwd*

Now need to restart the postfix

/etc/init.d/postfix restart

Now we need to create the Media with the information about the email that will send the messages:

  • Click On Administration/Media types
    • Now click in Email
      • Name: Email
      • Type: Email
      • SMTP server: localhost
      • SMTP helo: localhost
      • SMTP email: email@gmail.com
      • Check the Enabled
      • Click on Update

Now we need to configure the profile of the administrator user to define what we want to receive from the Zabbix Alerts

  • Click on right Corner Profile
  • On Tab: Media
    • Click on Add
      • Type: Email
      • Send to: email@gmail.com
      • When active: 1-7,00:00-24:00
      • Use if severity: Check all of them
      • Status: Enabled
      • Click on Add
    • Click on Update

Now we need enable the Report problems

  • Click on Configuration/Actions
    • Click on Report problems to Zabbix administrators
    • Now check Enabled check box
  • Click on Update

Working with Items and Triggers

Let's create a file to test the new item

touch /tmp/test

Now we will take a look how to create a new Item

  • Configuration/Templates → choose what template you want to change (Templates OS Linux) → choose item.
  • Select Items
  • Select Create item
    • Name: Presence of /tmp/test
    • Type: Zabbix agent
    • Key: vfs.file.exists[/tmp/test]
    • Type of information: Numeric (unsigned)
    • Date type: Decimal
    • Update interval (in sec): 60
    • History storage period (in days): 7
    • Trend storage period (in days): 30
    • Applications: General
    • Enabled: Checked
  • Click on Add

Now we will take a look how to create a new Item

  • Configuration/Templates → choose what template you want to change (Templates OS Linux) → choose item.
  • Select Triggers
  • Select Create trigger
    • Name: File /tmp/test is missing
    • Expressions: {Template App Apache Service:vfs.file.exists[/tmp/test].last()}=0 → here I'm working the the template for Apache.
    • Severity: Warning
    • Enabled: Checked
  • Click in Update

Now we can test the trigger removing the /tmp/test therewith will be get a alert and an action Email to the administrator whether the configuration been enabled.

Discovering and Adding to monitoring

Now we will take a look how to discovery zabbix clients and adding them to the monitoring.

  • Configuration/Discovery
  • Create discovery rule
    • Name: My network
    • Discovery by proxy: No Proxy
    • IP range: 192.168.1.0/24
    • Delay (in sec): 300
    • Checks: New
      • ICMP ping click on Add and click on New and select Check type: Zabbix agent port range: 10050 and key: system.uname
    • Device uniqueness criteria: IP Address
    • Enabled: Checked
  • Click on Add

Now we need to create the action to add the new hosts

  • Configuration/Actions
  • Event source: Discovery
  • Auto dicovery.Linux servers → Enabled
  • Conditions:
    • And/Or
      • A: Conditions: Received value like linux
      • B: Discovery status = UP
      • C: Service type = Zabbix agent
  • Operations:
    • Details: Actions
    • Add to host groups: Linux servers
    • Link to templates: Template OS Linux

Now we can monitoring the new hosts on Monitoring/Discovery

Updating History and Trends

History and trends are the two ways of storing collected data in Zabbix.

Whereas history keeps each collected value, trends keep averaged information on hourly basis and therefore are less resource-hungry.

Let's update the informations

mysql -u root -p
USE zabbix;
SELECT name, history, trends FROM items;
UPDATE items SET history=15, trends=30;
quit;

Managing users and groups

It's better always to work with groups rather than user, because we can have many users with the same permissions.

Let's create a new Group:

  • Administration/users
    • Select: Create user group on the right upper corner
      • Group name: Development
    • Select Permissions Tab:
      • Select Add on upper read only:
        • Select the host groups that you want to grant permissions like: Development Servers.
        • Now select Add on the bottom of the page.

Let's create a new User:

  • Administration/users
  • On the select box choose: Users
  • Now select: Create user
    • Alias: Development's user
    • Name: Development
    • Groups: Add the Development
    • Password: put some password
    • Password (once again): put some password like the previous box.
    • Choose the language: English (US)
    • Now select Add

To grant more permissions try to work always with new groups and put the user in the groups with the permissions.

References