您的位置:首页 > 数据库 > MySQL

使用Linux C开发Nagios监控插件系列——监控MySQL状态的插件开发

2013-05-17 23:59 627 查看
由于工作上的需要,最近被分派到公司的系统运维部混了一段时间,也就是在这期间让我遇到了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 compiler
CC = gcc

#Options for release
CFLAGS = -O2 -Wall -c -fmessage-length=0

check_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 -lmysqlclient

check_mysql_health.o: check_mysql_health.c check_mysql_health.h
$(CC) -I/usr/include/mysql $(CFLAGS) check_mysql_health.c

main.o: main.c check_mysql_health.h
$(CC) -I/usr/include/mysql $(CFLAGS) main.c

clean:
-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.zip
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: