由於工作上的需要,最近被指派到公司的系統營運部混了一段時間,也就是在這期間讓我遇到了Nagios——一款開源的系統監視軟體。不過在我接觸系統營運工作之前我還真的不知道Nagios這個名字,也不知道它是何方神聖,作為一名資深的碼農竟然不知有如此神器,還真是羞愧不已!不過羞愧管羞愧,日子還是照樣要過,拿人錢財與人消災,既然被派到系統營運部,怎麼說也要找點事情做做。於是乎就想編寫幾個監控外掛程式,能讓領導在監控大屏上看看即時監控圖表,那也算得上是一個亮點。關於Nagios的強大功能這裡就不多介紹了,相關的安裝和配置也不是本文的關注重點,我們主要講解如何寫Nagios的監控外掛程式。
Nagios本身並沒有什麼特別的功能,所有的監控功能均來自各種外掛程式,Nagios只是一個平台並制定了一套統一的標準,外掛程式只要按照標準開發就能相互協作並形成生產力,這點上與Maven倒有點類似。本次我們開發的是一個MySQL資料庫的監控外掛程式,該外掛程式能監控MySQL的當前串連數和長時間執行的SQL語句數並形成統計圖形。首先介紹一下我們的開發環境:
作業系統:Redhat Linux AS 5.8 64位元據庫:作業系統內建的MySQL伺服器Nagios:3.5版本,使用被動監控模式圖形展現:pnp4nagios外掛程式外掛程式開發語言:Linux C編譯器:Linux下的GCC 4.1.2外部函數庫:MySQL官方提供的mysqlclient庫
關於mysqlclient函數庫其實在Linux的安裝光碟片上就能找到,沒必要一定要去下載,以下是我機器上安裝的RPM包:
圖上紅色框中的就是RPM安裝包,它們可以在你的Linux安裝光碟片中找到。
接下來我們來介紹一下Nagios的資料格式,下面是一個例子:
OK: MySQL alive: Threads_connected=1 | 'Threads_connected'=1;25;30;
Nagios的資料格式分成2部分,中間用管道符分割,前半部分會被Nagios顯示在監控前台頁面上,後半部分則用於圖形的展現。我們主要關注後半部分,我們可以看到用分號間隔的3個數字,1表示當前值,即MySQL當前的串連數,25表示圖形上的警告線,在圖形上會用一條黃色線表示,30表示圖形上的危險線,在圖形上會用紅色線表示。我們先來看看圖形的展示效果,如所示(有些網上下載的外掛程式並沒有提供後半部分的資料,我們稱之為prefdata,故而在顯示圖形時會報找不到xxxx.xml檔案的錯誤資訊,這時你就應該看看你使用的外掛程式是否支援prefdata的輸出):
接著我們來看一下資料的前半部分是如何在Nagios前台頁面上被展示的,如:
紅色框中的就是被展現的資料前半部分。
當我們瞭解了Nagios採集的資料格式之後,就可以著手編寫監控外掛程式了。其實我們的MySQL監控外掛程式非常的簡單,首先通過mysqlclient庫提供的函數串連上指定的MySQL伺服器,然後執行“show status like '%xxxx%'”語句,該SQL語句用於查詢MySQL伺服器當前的狀態資訊,其中XXXX就是要查詢的狀態屬性變數名稱。例如,我們上例中的Threads_Connected變數名,用於查詢MySQL伺服器當前的串連數。當然還有其他很多的狀態變數名,可以通過查詢MySQL的使用手冊擷取更多的資訊。最後將查詢結果按照Nagios規定的資料格式輸出就可以了。另外外掛程式程式需要返回3個整形數告訴Nagios的最終狀態,在接下去的內容中會加以說明。
終於到了展示代碼的時候了,由於我們的外掛程式程式非常的簡單,所以我只提供了標頭檔的展示,實現代碼可以下載附件查看。標頭檔定義如下:
#ifndef MYSQL_HEALTH_CHECK_H_#define MYSQL_HEALTH_CHECK_H_//nagios return status value#define OK 0#define WARNING 1#define CRITICAL 2#define UNKNOWN 3#ifdef WINNT#include <winsock2.h>#endif#include "mysql.h"/** * define data struct to mysql status values */typedef struct{int success;char *variable_name;int variable_value;} MysqlStatus;/** * define data struct to connection mysql parameters */typedef struct{char *host_name;char *user_name;char *password;char *db_name;} MysqlParameter;/** * print this plugin help message */void usage();/** * check mysql status then return nagios prefdata format string */int check_mysql_health(const MysqlStatus *, int, int);/** * query mysql current status, return NULL is occur errors */MysqlStatus query_mysql_status(const MysqlParameter, char *);#endif /* MYSQL_HEALTH_CHECK_H_ */
我定義了2個結構體,MysqlStatus用於儲存查詢結果,MysqlParameter用於存放資料庫連接參數資料(主機IP、使用者名稱、密碼等資訊)。還定義了4個常量宏,用於向Nagios返回檢查的結果,它們分別是:
OK - 0:檢查狀態為正常時返回;
WARNING - 1:檢查狀態為警告時返回;
CRITICAL - 2:檢查狀態為危險時返回;
UNKNOWN - 3:檢查狀態為未知時返回;
Nagios會根據外掛程式程式的傳回值進行不同狀態的顯示,如發生警告時會顯示黃色,發生危險時會顯示紅色。除此之外還定義了3個函數,usage函數用於使用者提供-h參數時顯示外掛程式的使用方法。作為慣例,每個外掛程式都應該實現協助方法,並提供-h參數選項,告知使用者你外掛程式的調用方法和參數含義。query_mysql_status函數會根據傳提的參數進行資料庫連接和執行“show status”語句,並將查詢狀態結果賦值給MysqlStatus結構體並返回。check_mysql_health函數根據query_mysql_status函數返回的結構體並與使用者提供的-w和-c參數進行比較,如果大於-w參數值,且小於-c參數值,則該函數返回1(WARNING),如果大於-c參數值,則該函數返回2(CRITICAL),否則返回0(OK),如果該函數在執行過程中發生錯誤,則返回3(UNKNOWN) 。
好了,大致的程式實現演算法就是這些,的確非常的簡單。最後,我們要寫一個Makefile檔案,用於在linux環境中編譯並產生可執行檔,Makefile檔案的內容如下:
all: check_mysql_health# Which compilerCC = gcc#Options for releaseCFLAGS = -O2 -Wall -c -fmessage-length=0check_mysql_health: main.o check_mysql_health.o$(CC) -L/usr/lib/mysql -L/usr/lib64/mysql -o check_mysql_health main.o check_mysql_health.o -lmysqlclientcheck_mysql_health.o: check_mysql_health.c check_mysql_health.h$(CC) -I/usr/include/mysql $(CFLAGS) check_mysql_health.cmain.o: main.c check_mysql_health.h$(CC) -I/usr/include/mysql $(CFLAGS) main.cclean:-rm -Rf main.o check_mysql_health.o check_mysql_health
將所有檔案上傳到linux的某個目錄中,然後在該目錄中執行make命令,如果串連庫時發生錯誤,則需要檢查系統中是否安裝了mysqlclient庫。如果編譯完成,則會在目前的目錄下產生check_mysql_health檔案。使用chmod +x命令給該檔案添加執行屬性,最後輸入如下命令進行測試:
./check_mysql_health -h
該命令會調用usage函數,顯示外掛程式的調用方法和參數說明:
從中我們可以看到,該外掛程式一共有8個參數選項,各個參數的含義可以查看說明。下面是一個實際的使用例子:
./check_mysql_health -H xxx.xxx.xxx.xxx -u root -p password -d test -w 30 -c 40
最後將該外掛程式複製到Nagios的libexe目錄中,這樣就可以像Nagios內建的外掛程式一樣使用它了。
結束語:
Nagios就像一個舞台,讓形形色色的演員盡情的發揮自己的表演才能。Nagios的外掛程式除了可以用C/C++編寫外,還可以用shell和perl,當然Java也可以,不過我對於perl編寫的外掛程式就不那麼喜歡,因為要讓perl外掛程式run起來著實是一件不太容易的事情,你必須為安裝各種依賴的perl模組而被折磨的筋疲力竭。最後附上完整的外掛程式原始碼,以供各位同學參考學習和交流。
附件:check_mysql_health.tar.gz