Zabbix: моніторинг бази даних Oracle через ODBC c використанням low level discovery

    У статті буде розглянуто можливість моніторингу база динячих за коштами вбудованої в Zabbix підтримки ODBC, c використанням автовизначення об'єктів.
 
Для початку розглянемо доступні для Zabbix методи моніторингу БД, які використовувалися до підтримки ODBC.
Так як стаття про моніторинг Oracle, то і будемо дивитися в цьому розрізі.
 
1. Використання скрипта zabora
 
В принципі спкріпт всім хороший, але головне, що мене не влаштовувало: скрипт лежить на кожній машині з БД, і при додавання запиту доводилося йти на цю машину і редагувати конфіг.
 
Підтримує параметри запитів, тобто можна передавати параметр в ключ і на основі його робити запит до БД.
Тобто один і той же запит може бути використаний для збору метрик різних об'єктів.
 
2. Orabbix або DBforBIX
 
Теж хороший продукт, є демоном на java, створює кілька з'єднань і підтримує автоматичне додавання нових запитів в конфіг без перезавантаження. Працює як Zabbix trapper, тобто сам з певною періодичністю посилає дані в Zabbix сервер.
 
Недоліки:
 - Не підтримує параметри, тобто на кожну метрику створюється окремий запит. Уявіть у вас 10 tablespace'ов і вам потрібно знімати з кожного 4 параметра — виходить 40 запитів у файлі. Інтервал запиту отримання метрики, так само виставляється в конфіги, що не дуже зручно.
 
Спробувавши всі ці рішення вирішив використати підтримку ODBC в Zabbix, і ось чому:
 
     
  • запит до БД — стандартний ключ Zabbix, з цього випливає, що ми налаштовуємо такі параметри як частота опитування в самому інтерфейсі
  •  
  • редагування запитів в інтерфейсі Zabbix
  •  
  • дозволяє використовувати макроси
  •  
  • найголовніше дозволяє автоматизувати процес додавання нових об'єктів на моніторинг
  •  
 
Спочатку опишу, що є в господарстві:
 
1. 6 баз даних Oracle — 1 БД — 1 сервер + 1 резервний сервер під БД разом: виходить 12 серверів.
2. Сервера для кожної БД об'єднані в кластер — разом 6 кластерів
3. На кожному сервера встановлений Zabbix agent для AIX
4. На кожному сервері по скрипту zabora
 
Конфігурація Zabbix моніторингу:
 
     
  1. Zabbix сервер на CentOS 6.5 + TokuDB — 20 000 елементів — 380 nps (нових значень в секунду)
  2.  
  3. Спеціально для моніторингу БД, було піднято Zabbix Proxy, оскільки запити можуть виконаються досить довго, то не хотілося б з-них підвішувати процеси збору даних основного Zabbix'a — теж CentOS 6.5 + TokuDB
  4.  
 
У цій статті я не буду торкатися налаштування TokuDB, так як планую ще одну статтю чому ми перейшли з InnoDB на TokuDB, і що нам це дало.
 
 

Установка Oracle Instant Client

 
Спочатку необхідно встановити Oracle Instant Client на машину з Zabbix Proxy:
 
У нас використовується Oracle 11g, тому викачуємо RMP пакети відповідної версії з сайту Oracle .
Нам необхідні:
 
     
  • oracle-instantclient11.2-basic-11.2.0.4.0-1.x86_64.rpm — основні бібліотеки
  •  
  • oracle-instantclient11.2-jdbc-11.2.0.4.0-1.x86_64.rpm — драйвера для java, для нашої задачі не потрібні, але в господарстві в нагоді :)
  •  
  • oracle-instantclient11.2-sqlplus-11.2.0.4.0-1.x86_64.rpm — клієнт sqlplus
  •  
  • oracle-instantclient11.2-odbc-11.2.0.4.0-1.x86_64.rpm — бібліотека для роботи через ODBC
  •  
  • можна ще до купи: oracle-instantclient11.2-devel-11.2.0.4.0-1.x86_64.rpm :)
  •  
 
в тій папці в яку завантажили всі ці файли робимо:
 
# rpm -i oracle-*.rpm

 
 

Налаштування SQLplus для доступу до БД Oracle.

 
Для того щоб клієнт працював, необхідно в параметри оточення виставити необхідні змінні, для початку виставимо їх у своєму профілі, прописавши в файл
$HOME/.bash_profile
:
 
ORACLE_HOME=/usr/lib/oracle/11.2/client64
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:$LD_LIBRARY_PATH
TNS_ADMIN=$ORACLE_HOME/network/admin>

PATH=$PATH:$ORACLE_HOME/bin:$HOME/bin

export ORACLE_HOME
export LD_LIBRARY_PATH
export TNS_ADMIN
export PATH

 
Перелогініваемся і дивимося чи наші змінні в
# env

Звернемо увагу на змінну
TNS_ADMIN=$ORACLE_HOME/network/admin

Цей шлях необхідно створити, туди ми покладемо файл tnsnames.ora який використовується бібліотеками клієнта для підключення до БД.
 
Створимо підключення до БД з ім'ям DOCSDB наприклад.
 
#cat $ORACLE_HOME/network/admin/tnsnames.ora

 
DOCSDB =
  (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = oradocs)(PORT = 1521))
      (CONNECT_DATA =
        (SERVER = DEDICATED)
        (SERVICE_NAME = docsdb)
      )
)

 
Необхідно підставити потрібні значення в HOST і SERVICE_NAME.
HOST — можна прописувати IP або DNS ім'я (перевірте тільки, що воно ресолвітся в IP)
 
Перевіримо настройку клієнта, попередньо створіть обліковий запис zabbix в Oracle:
 
# sqlplus zabbix/zabbix@DOCSDB

 
SQL*Plus: Release 11.2.0.4.0 Production on Sat May 24 10:47:09 2014

Copyright © 1982, 2013, Oracle.  All rights reserved.


Connected to:</code>
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

 
Бачимо, що клієнт видав запрошення, значить з'єднання пройшло успішно, ну і зовсім щоб бути впевненими зробимо простенький запит:
 
SQL> select banner from v$version where rownum=1;

 
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production

SQL>

 
 

Конфігурація ODBC.

 
Офіційні пакети Zabbix Server і Zabbix Proxy в СentoOS скомпільовані з підтримкою unixODBC, тому після їх установки у вас повинен бути встановлений пакет unixODBC, перевіряємо:
# yum info *ODBC

Висновок повинен містити такі пакети:
unixODBC
і
oracle-instantclient11.2-odbc
.
 
Правимо файли:
 
# cat /etc/odbcinst.ini

 
[OracleDriver]
Description=Oracle ODBC driver for Oracle 11g
Driver=/usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1

І відразу робимо таку перевірку:
 
# ldd /usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1

 
ldd: warning: you do not have execution permission for `/usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1`
      linux-vdso.so.1 =>  (0x00007fff1a58f000)
      libdl.so.2 => /lib64/libdl.so.2 (0x00007f89d6d4d000)
      libm.so.6 => /lib64/libm.so.6 (0x00007f89d6ac8000)
      libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f89d68ab000)
      libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f89d6692000)
      libclntsh.so.11.1 => /usr/lib/oracle/11.2/client64/lib/libclntsh.so.11.1 (0x00007f89d3d22000)
      libodbcinst.so.1 => /lib64/libodbcinst.so.1 (0x00007f89d3b11000)
      libc.so.6 => /lib64/libc.so.6 (0x00007f89d377d000)
      /lib64/ld-linux-x86-64.so.2 (0x00007f89d711c000)
      libnnz11.so => /usr/lib/oracle/11.2/client64/lib/libnnz11.so (0x00007f89d33af000)
      libaio.so.1 => /lib64/libaio.so.1 (0x00007f89d31ae000)
      libltdl.so.7 => /usr/lib64/libltdl.so.7 (0x00007f89d2fa5000)

 
C великою часткою ймовірністю, ви отримаєте
libodbcinst.so.1 => not found
, тому потрібно зробити сім-лінк:
 
# ls -lah /lib64 | grep odbc 

 
lrwxrwxrwx.  1 root root    31 May 18 00:45 libodbcinst.so.1 -> /usr/lib64/libodbcinst.so.2.0.0 
lrwxrwxrwx.  1 root root    16 May 20 11:41 libodbcinst.so.2 -> libodbcinst.so.1 

 
Далі редагуємо файл:
  
# cat /etc/odbc.ini

 
[ORA_DOCSDB]
Driver= OracleDriver
DSN= DOCSDB
ServerName= DOCSDB
UserID= zabbix
Password= zabbix

 
Після цього у нас має вийде підключиться до БД Oracle через клієнт ODBC (завжди використовуйте параметр-v, якщо буде помилка підключення, скаже детально в чому проблема):
 
# isql -v ORA_DOCSDB

 
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  
|                                       |
+---------------------------------------+
SQL>

 
Так само для очищення совісті, що у нас все працює, робимо запит:
 
SQL> select banner from v$version where rownum=1;
+---------------------------------------------------------------------------------+
| BANNER                                                                          |
+---------------------------------------------------------------------------------+
| Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production    |
+---------------------------------------------------------------------------------+
SQLRowCount returns -1
1 rows fetched
SQL>

 
Вітаю, Ви налаштували ODBC.
 
Тепер нам необхідно домогтися, щоб Zabbix Proxy так само міг робити запити через ODBC.
 
Для цього необхідно, щоб в оточення процесу zabbix_proxy були доступні змінні, зазначені вище, для це додамо в файл:
 
# cat /etc/init.d/functions

 
# Set up a default search path.
PATH="/sbin:/usr/sbin:/bin:/usr/bin"

ORACLE_HOME=/usr/lib/oracle/11.2/client64
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:$LD_LIBRARY_PATH
TNS_ADMIN=$ORACLE_HOME/network/admin</code>

PATH=$PATH:$ORACLE_HOME/bin:$HOME/bin</code>

export ORACLE_HOME
export LD_LIBRARY_PATH
export TNS_ADMIN
export PATH

 
Після цього обов'язково перезапускаємо zabbix_proxy:
# service zabbix-proxy restart

 
Тепер ми одразу перейдемо до налаштування правил автовизначення в термінології Zabbix — це low level discovery rule.
 
Що таке LLD?
У принципі це будь-який елемент в Zabbix який може повернути дані в JSON форматі.
Так вбудований моніторинг баз даних в Zabbix завжди повертає тільки 1 колонку і 1 рядок, і до того ж у команді Zabbix чомусь ix ніяк не напишуть для БД генератор LLD, тобто запит повертає кілька колонок і рядків, то автоматично видавати в JSON форматі.
 
Кому потрібна ця фіча, прохання проголосувати .
 
Доведеться написати скрипт який видаватиме нам список об'єктів в JSON форматі.
 
Шаблон і скрипт можна взяти на GitHub
 
Скрипт написаний на php, тому любителям bash прошу відвернутися убік :)
Коментувати сам скрипт не буду, думаю за кодом все зрозуміло, скажу тільки, що його потрібно покласти в папку яка задана в конфіги zabbix_proxy.conf (або zabbix_server.conf):
ExternalScripts=/usr/lib/zabbix/externalscripts

 Скрипт oracle.odbc.discovery
#!/usr/bin/php
<?php

  if(!isset($argv[1]) && !isset($argv[2])) exit("ZBX_NOTSUPPORTED");

  $connected_dsn = odbc_connect($argv[1],"","");

  if(!$connected_dsn) exit('SQL connection erorr | ZBX_NOTSUPPORTED');

  switch ($argv[2]) {
      case "tablespaces":
          $result=odbc_exec($connected_dsn,"SELECT tablespace_name FROM dba_tablespaces;");
          $tablespaces = array("data"=>array());

          while(odbc_fetch_row($result)){
               $tablespaces['data'][]=array('{#TBSNAME}'=>odbc_result($result,1));
          }

          echo json_encode($tablespaces);
          break;

      case "jobs":
          $result=odbc_exec($connected_dsn,"SELECT job_name, owner FROM dba_scheduler_jobs WHERE state != 'DISABLED';");

          $jobs = array("data"=>array());

          while(odbc_fetch_row($result)){
               $jobs['data'][]=array(
                                        '{#JOBNAME}'=>odbc_result($result,1),
                                        '{#JOBOWNER}'=>odbc_result($result,2));
          }

          echo json_encode($jobs);
          break;
  }

exit();
?>

 
 
Скрипту передаються два параметри:
1. DSN — який ви вказали у файлі / etc / odbc.ini в квадратних дужках, у разі прикладу це ORA_DOCSDB
2. Тип об'єктів, список яких потрібно повернути: tablespaces або jobs
 
У разі jobs, скрипт поверне так само і {# JOBOWNER}, тобто власника job'a.
 
Додайте права на виконання на скрипт і спробуйте його запустити:
 
# /usr/lib/zabbix/externalscripts/oracle.odbc.discovery ORA_DOCSDB tablespaces
, скрипт поверне приблизно ось такий масив:
 
{
    "data": [
        {
            "{#TBSNAME}": "SYSTEM"
        },
        {
            "{#TBSNAME}": "SYSAUX"
        },
        {
            "{#TBSNAME}": "UNDOTBS1"
        },
        {
            "{#TBSNAME}": "TEMP"
        },
        {
            "{#TBSNAME}": "USERS"
        }
    ]
}

 
 
# /usr/lib/zabbix/externalscripts/oracle.odbc.discovery ORA_DOCSDB jobs

 
{
    "data": [
        {
            "{#JOBNAME}": "PURGE_LOG",
            "{#JOBOWNER}": "SYS"
        },
        {
            "{#JOBNAME}": "ORA$AUTOTASK_CLEAN",
            "{#JOBOWNER}": "SYS"
        },
        {
            "{#JOBNAME}": "DRA_REEVALUATE_OPEN_FAILURES",
            "{#JOBOWNER}": "SYS"
        },
        {
            "{#JOBNAME}": "BSLN_MAINTAIN_STATS_JOB",
            "{#JOBOWNER}": "SYS"
        },
        {
            "{#JOBNAME}": "RSE$CLEAN_RECOVERABLE_SCRIPT",
            "{#JOBOWNER}": "SYS"
        },
        {
            "{#JOBNAME}": "SM$CLEAN_AUTO_SPLIT_MERGE",
            "{#JOBOWNER}": "SYS"
        },
        {
            "{#JOBNAME}": "RLM$EVTCLEANUP",
            "{#JOBOWNER}": "EXFSYS"
        },
        {
            "{#JOBNAME}": "RLM$SCHDNEGACTION",
            "{#JOBOWNER}": "EXFSYS"
        }
    ]
}

 
Нарешті переходимо до додавання моніторингу БД Oracle в Zabbix.
 
Для початку пару слів про шаблон:
1. Загальні ключі моніторингу Oracle взяті з скрипта zabora
2. Щоб шаблону заробив необхідно у внеску Макроси самого хоста, додати 3 користувальницьких макросу:
 - {$ DSN1} — DSN який прописаний в квадратних дужках файлу / etc / odbc.ini (у прикладі ORA_DOCSDB)
 - {$ ORA_USER} — користувач з правами якого буде підключення до БД Oracle
 - {$ ORA_PASSWORD} — пароль для підключення до БД Oracle
 
 
 
 
 
Отже список правил LLD:
 
 
Щоб правила відпрацювали в перший раз, виставите в самих правила інтервал, припустимо 300 секунд, і через 5 хвилин у вас в елементах даних повинні створитися нові.
 
Розглянь самі правила і почнемо з Tablespaces.
 
 
В принципі тут все зрозуміло, хочу звернути увагу на поле «Фільтр».
За допомогою цього поля можна робити фільтрацію списку який повертає нам сам елемент, у нашому прикладі нам не потрібно додавати на моніторинг системні tablespaces. Фільтрація відбувається на основі правила regexp. Як видно на картинки поле {# TBSNAME} має відповідати правилу regexp Oracle System Excluded Tablespaces. Загальні правила regexp описуються в
Администрирование > Общие > Регулярные выражения 
і викликаються у фільтрі через символ @.
 
 
 
Аналогічно все і для job'ов:
 
 
 
Нові зміни до прототипів даних
 
 
 
Сам прототип
 
 
Картинка говорить сама за себе, але хочу звернути на один нюанс, а саме на полі «Одиниця виміру», за умовчанням в Zabbix використовується 10-тичная система обчислення, що і слід було очікувати, тому всі приставки Кіло, Мега, Гіга і т.д. це поділ на 1000, що з точки зору ісчесленіі обсягу даних не зовсім коректно, тому щоб ви отримували у вкладці «Останні дані» адекватні значення в Zabbix використовується «спеціальні» одиниці виміру: B і Bps — байт і байт в секунду (докладніше ).
Але є забавний момент (баг), в останніх даних приставки K (ilo), M (ega), G (iga) переводяться в K, М, Г, а от сама одиниця немає, тому у випадку з гігабайтами у ваc буде ГB.
 
Прототипи тригерів для tablespaces:
  
 
Діапазони наступні:
 
     
  • при розмірі менше 3Тб обмеження у відсотках
  •  
  • від 3Тб до 10ТБ в гігабайтах
  •  
  • від 10ТБ в гігабайтах
  •  
 
Звернути увагу, що значення в умовах використовується в байтах, а також звернути на порядок і використовуваних значень.
На перший взляд може здатися зайвим умова «Максимальний розмір> 0 »
 
Але це зроблено для того щоб приходило більше інформативне лист для DBA.
У діях ви вказуєте:
 
1. {ITEM.NAME1} ({HOSTNAME1}:{TRIGGER.KEY1}): {ITEM.VALUE1}
2. {ITEM.NAME2} ({HOSTNAME1}:{TRIGGER.KEY2}): {ITEM.VALUE2}
3. {ITEM.NAME3} ({HOSTNAME1}:{TRIGGER.KEY3}): {ITEM.VALUE3}

 
У дію ми не можемо отримати значення ключа який був створений автоматично, не те щоб ми не можемо його отримати просто ми не знаємо його назва, для це там потрібно виокремити з ключа назва tablespace, але таких функцій Zabbix немає.
 
При таких налаштуваннях дії, Вам буде приходити щось подібне:
 
1. Текущий размер tablespace BG_Z_LOB_TBS (FKSODBb.odbc.select[tbs_size_BG_Z_LOB_TBS,ORA_FKSODB]): 2 GB 
2. Осталось свободного места в процентах в tablespace BG_Z_LOB_TBS (FKSODBb.odbc.select[tbs_used_percent_BG_Z_LOB_TBS,ORA_FKSODB]): 99 %
3. Максимально возможный размер tablespace BG_Z_LOB_TBS (FKSODBb.odbc.select[tbs_maxsize_BG_Z_LOB_TBS,ORA_FKSODB]): 32 GB

 
Прототипи даних для job'ов:
 
 
Прототипи тригерів для job'ов:
 
 
Тригери спрацьовують якщо:
 
     
  • час виконання job'a більше 720 хвилин
  •  
  • якщо job завершився з статусом не рівним «SUCCEEDED»
  •  
 
Приємних Вам виявлень в БД Oracle :)
    
Джерело: Хабрахабр

0 коментарів

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