/*******************************************************************************************
** Name:mysqlmonitor.cpp
** show innodb status \G;
** Author:zhangjq
**Date:201006
** All rights reserved!
*******************************************************************************************/
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
void getReference(xmlDocPtr doc,xmlNodePtr cur);
void parseStroy(xmlDocPtr doc,xmlNodePtr cur);
char * getxmlnodevalue(char * xmlfilename,char * property);
char buf[102400];
//char buf1[102400];
char rev[1024];
char xml[102400];
char* str1;
char Finsert[20];
//记录日志
void runlog(char * e)
{
system("echo day>>run.log");
system("echo \"e\">>run.log");
}
//去掉空格
void ltrim(char * s)
{
int l=0,p=0,k=0;
l=strlen(s);
if(l==0)return;
p=0;
while(s[p]==' '||s[p]=='\t') p++;
if(p==0)return;
while(s[k]!='\0') s[k++]=s[p++];
return;
}
//转换<或>字符
int replace(char* str,char* str_src, char* str_des){
char *ptr=NULL;
char buff[20480];
char buff2[20480];
int i = 0;
if(str != NULL){
strcpy(buff2, str);
}else{
printf("str_replace err!\n");
return -1;
}
memset(buff, 0x00, sizeof(buff));
while((ptr = strstr( buff2, str_src)) !=0){
if(ptr-buff2 != 0) memcpy(&buff[i], buff2, ptr - buff2);
memcpy(&buff[i + ptr - buff2], str_des, strlen(str_des));
i += ptr - buff2 + strlen(str_des);
strcpy(buff2, ptr + strlen(str_src));
}
strcat(buff,buff2);
strcpy(str,buff);
return 0;
}
//执行系统命令返回值
char* cmdstring(char* cmdstr)
{
FILE *stream;
memset( buf, '\0', sizeof(buf) );
stream = popen( cmdstr, "r" );
fread( buf, sizeof(char), sizeof(buf), stream);
pclose( stream );
return buf;
}
//发送监控数据xml
char* senddata(char* msg)
{
//获取服务器IP和port
//printf (msg);
char* ip;
char* port;
char bufip[20];
char bufport[20];
memset(rev,'\0',sizeof(rev));
ip=cmdstring("/bin/cat ../agent.ini|/bin/grep \"^ip\" |/bin/awk -F\" \" '{print$3}'");
memset( bufip, '\0', sizeof(bufip));
memset( bufport, '\0', sizeof(bufport));
strncpy(bufip,ip,strlen(ip)-1);
port=cmdstring("/bin/cat ../agent.ini|/bin/grep \"^port\" |/bin/awk -F\" \" '{print$3}'");
strncpy(bufport,port,strlen(port)-1);
//新建socket
int socket_fd,socket_rev,bytes_send,bytes_rev;
struct sockaddr_in serv_addr;
struct hostent *hp;
hp=gethostbyname(bufip);
if((socket_fd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket创建出错");
exit(1);
}
if((socket_rev=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket创建出错");
exit(1);
}
//初始化连接参数
memset((void *)&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(atoi(bufport));
//serv_addr.sin_addr.s_addr=inet_addr(bufip);
serv_addr.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
bzero(&(serv_addr.sin_zero),8);
//连接
if(connect(socket_fd,(sockaddr *)&serv_addr,sizeof(sockaddr))==-1)
{
perror("connect出错");
exit(1);
}
if(connect(socket_rev,(sockaddr *)&serv_addr,sizeof(sockaddr))==-1)
{
perror("rev connect出错");
exit(1);
}
//发送数据
if(bytes_send=send(socket_fd,msg,strlen(msg),0)==-1)
{
perror("send出错");
exit(1);
}
//接收数据
if(bytes_rev=recv(socket_fd,rev,1024,0)==-1)
{
perror("recv出错");
exit(1);
}
close(socket_fd);
close(socket_rev);
return rev;
}
int main( void )
{
char* str;
char disktype[8];
char* recvdata;
char cmd[1024];
char i[5];
char slavestatus[5];
char slavebehind[20];
//初始化xml
memset( xml, '\0', sizeof(xml) );
//strcpy(xml,"1<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<monitor monitorgroup='mysqlmonitor' monitortype='mysql' servername=");
strcpy(xml,"1<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<monitor monitorgroup='");
str=getxmlnodevalue("mysql","monitorgroup");
//printf(str);
strcat(xml,str);
strcat(xml,"' monitortype='");
//memset(str,'\0',sizeof(str));
str=getxmlnodevalue("mysql","monitortype");
//printf(str);
strcat(xml,str);
//memset(str,'\0',sizeof(str));
strcat(xml,"' servername=");
//获取内网IP
str=cmdstring("/sbin/ifconfig |/bin/grep \"inet addr:19\\.2\" |/bin/awk -F\":\" '{print$2}' |/bin/awk -F\" \" '{print$1}'");
strcat(xml,"'");
strncat(xml,str,strlen(str)-1);
strcat(xml,"'");
strcat(xml," sn=");
strcat(xml,"'");
//获取服务器SN号,timeid
str=cmdstring("/bin/cat ../agent.ini|/bin/grep \"^sn\" |/bin/awk -F\" \" '{print$3}'");
strncat(xml,str,strlen(str)-1);
strcat(xml,"'");
strcat(xml," tablename='SQL_mysql' alarm='1' timeid=");
strcat(xml,"'");
str=cmdstring("/bin/cat ../agent.ini|/bin/grep \"^timeid\" |/bin/awk -F \" \" '{print$3}'");
strncat(xml,str,strlen(str)-1);
strcat(xml,"'");
strcat(xml,">\n");
//查锁
try{
memset( i, '\0', sizeof(i) );
memset( cmd, '\0', sizeof(cmd) );
str=cmdstring("/data/mysql/bin/mysql -umysqlmonitoruser -pUserpassword -e\"show engine innodb status \\G;\">status.txt");
str=cmdstring("/bin/cat status.txt |/bin/grep \"locked 1\"|wc -l");
strcpy(i,str);
strcpy(cmd,"/bin/cat status.txt |/bin/grep \"^[Ss][Ee][Ll][Ee][Cc][Tt]\\|^[Uu][Pp][Dd][Aa][Tt][Ee]\\|^[Ii][Nn][Ss][Ee][Rr][Tt]\\|^[Dd][Ee][Ll][Ee][Tt][Ee]\\|^[Aa][Ll][Tt][Ee][Rr]\\|^[Dd][Rr][Oo][Pp]\" |/bin/awk 'NR>=1 && NR<=");
strncat(cmd,i,strlen(i)-1);
strcat(cmd,"{print}'");
//printf("deadlock number:%s",i);
strcat(xml,"<deadlock_number compare='2'>");
strncat(xml,i,strlen(i)-1);
strcat(xml,"</deadlock_number>\n");
//printf(i);
if(strcmp(i,"0\n")!=0)
{
//满足条件则存在死锁,提交死锁SQL
str=cmdstring(cmd);
//printf(str);
strcat(xml,"<deadlock_SQL TableName='deadlocksql'><deadlocksql compare='0'>");
replace(str,"<","<");
replace(str,">",">");
replace(str,"&","&");
//printf(str);
strncat(xml,str,strlen(str)-1);
strcat(xml,"</deadlocksql></deadlock_SQL>\n");
}
}
catch(...){runlog("查锁出错");}
//printf(xml);
try{
/*获取每秒insert,update,delete,read*/
memset( cmd, '\0', sizeof(cmd) );
cmdstring("/data/mysql/bin/mysql -umysqlmonitoruser -pUserpassword -e\"show global status;\">status2.txt");
sleep(20);
cmdstring("/data/mysql/bin/mysql -umysqlmonitoruser -pUserpassword -e\"show global status;\">status3.txt");
char uptime[20];
str=cmdstring("/bin/cat status2.txt |/bin/grep \"\\bUptime\\b\" |/bin/awk -F \" \" '{print$2}'");
memset(uptime,'\0',sizeof(uptime));
strncpy(uptime,str,strlen(str)-1);
//str=cmdstring("/bin/cat status.txt |/bin/grep \"reads/s$\" |/bin/awk -F \",\" '{print$1}' |/bin/awk -F \" \" '{print$1}'");
//strcpy(cmd,"/bin/cat status2.txt |/bin/grep \"\\bCom_insert\\b\" |/bin/awk -F \" \" '{print$2/");
memset(Finsert,'\0',sizeof(Finsert));
memset(cmd,'\0',sizeof(cmd));
str=cmdstring("/bin/cat status2.txt |/bin/grep \"\\bCom_insert\\b\" |/bin/awk -F \" \" '{print$2}'");
strncat(Finsert,str,strlen(str)-1);
strcpy(cmd,"/bin/cat status3.txt |/bin/grep \"\\bCom_insert\\b\" |/bin/awk -F \" \" '{print$2/20-");
strcat(cmd,Finsert);
strcat(cmd,"/20'}");
//printf("%s\n",cmd);
str=cmdstring(cmd);
strcat(xml,"<insert compare='0'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</insert>\n");
//str=cmdstring("/bin/cat status.txt |/bin/grep \"reads/s$\" |/bin/awk -F \",\" '{print$2}' |/bin/awk -F \" \" '{print$1}'");
memset(Finsert,'\0',sizeof(Finsert));
memset(cmd,'\0',sizeof(cmd));
str=cmdstring("/bin/cat status2.txt |/bin/grep \"\\bCom_update\\b\" |/bin/awk -F \" \" '{print$2}'");
strncat(Finsert,str,strlen(str)-1);
strcpy(cmd,"/bin/cat status3.txt |/bin/grep \"\\bCom_update\\b\" |/bin/awk -F \" \" '{print$2/20-");
strcat(cmd,Finsert);
strcat(cmd,"/20'}");
//printf("%s\n",cmd);
str=cmdstring(cmd);
strcat(xml,"<update compare='0'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</update>\n");
//str=cmdstring("/bin/cat status.txt |/bin/grep \"reads/s$\" |/bin/awk -F \",\" '{print$3}' |/bin/awk -F \" \" '{print$1}'");
memset(Finsert,'\0',sizeof(Finsert));
memset(cmd,'\0',sizeof(cmd));
str=cmdstring("/bin/cat status2.txt |/bin/grep \"\\bCom_delete\\b\" |/bin/awk -F \" \" '{print$2}'");
strncat(Finsert,str,strlen(str)-1);
strcpy(cmd,"/bin/cat status3.txt |/bin/grep \"\\bCom_delete\\b\" |/bin/awk -F \" \" '{print$2/20-");
strcat(cmd,Finsert);
strcat(cmd,"/20'}");
//printf("%s\n",cmd);
str=cmdstring(cmd);
strcat(xml,"<delete compare='0'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</delete>\n");
//str=cmdstring("/bin/cat status.txt |/bin/grep \"reads/s$\" |/bin/awk -F \",\" '{print$4}' |/bin/awk -F \" \" '{print$1}'");
memset(Finsert,'\0',sizeof(Finsert));
memset(cmd,'\0',sizeof(cmd));
str=cmdstring("/bin/cat status2.txt |/bin/grep \"\\bCom_select\\b\" |/bin/awk -F \" \" '{print$2}'");
strncat(Finsert,str,strlen(str)-1);
strcpy(cmd,"/bin/cat status3.txt |/bin/grep \"\\bCom_select\\b\" |/bin/awk -F \" \" '{print$2/20-");
strcat(cmd,Finsert);
strcat(cmd,"/20'}");
//printf("%s\n",cmd);
str=cmdstring(cmd);
strcat(xml,"<read compare='0'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</read>\n");
}
catch(...){runlog("出错:获取每秒insert,update,delete,read");}
//获取连接数
try{
//str=cmdstring("/data/mysql/bin/mysql -umysqlmonitoruser -pUserpassword -e\"show full processlist;\">processlist.txt");
//str=cmdstring("cat processlist.txt |wc -l");
str=cmdstring("/bin/cat status2.txt |/bin/grep \"\\bThreads_connected\\b\" |/bin/awk -F \" \" '{print$2}'");
strcat(xml,"<conns compare='1'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</conns>\n");
//获取active SQL
str=cmdstring("/data/mysql/bin/mysql -umysqlmonitoruser -pUserpassword -e\"show full processlist;\">processlist.txt");
str=cmdstring("/bin/cat processlist.txt |/bin/grep \"[Ss][Ee][Ll][Ee][Cc][Tt]\\|[Uu][Pp][Dd][Aa][Tt][Ee]\\|[Ii][Nn][Ss][Ee][Rr][Tt]\\|^[Dd][Ee][Ll][Ee][Tt][Ee]\\|^[Aa][Ll][Tt][Ee][Rr]\\|^[Dd][Rr][Oo][Pp]\" |/bin/grep \"[^NULL]$\" |wc -l");
strcat(xml,"<actives compare='2'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</actives>\n");
if(strcmp(str,"0\n")!=0)
{
//printf("if通过");
str=cmdstring("/bin/cat processlist.txt |/bin/grep \"[Ss][Ee][Ll][Ee][Cc][Tt]\\|[Uu][Pp][Dd][Aa][Tt][Ee]\\|[Ii][Nn][Ss][Ee][Rr][Tt]\\|^[Dd][Ee][Ll][Ee][Tt][Ee]\\|^[Aa][Ll][Tt][Ee][Rr]\\|^[Dd][Rr][Oo][Pp]\" |/bin/grep \"[^NULL]$\" |/bin/awk -F\"\t\" '{print $3\"\t\"$6\"\t\"$8}'");
strcat(xml,"<active_SQL TableName='activesql'><activesql compare='0'>");
replace(str,"<","<");
replace(str,">",">");
replace(str,"&","&");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</activesql></active_SQL>\n");
}
}
catch(...){runlog("出错:获取连接数");}
/*获取iostat cpu,rrqm/s,wrqm/s,util*/
try{
memset(disktype,'\0',sizeof(disktype));
str=cmdstring("iostat -xt 1 2 >iostat.txt");
str=cmdstring("/bin/cat iostat.txt |/bin/grep \"^ \" |/bin/awk 'NR==2{print$1}'");//获取CPU
strcat(xml,"<cpu compare='1'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</cpu>\n");
str=cmdstring("cat iostat.txt |/bin/awk -F\" \" 'NR==8{print$1}'");//获取磁盘型号
strncat(disktype,str,strlen(str)-1);
//printf(disktype);
memset(cmd,'\0',sizeof(cmd));
strcat(cmd,"/bin/cat iostat.txt |/bin/grep \"^");
strcat(cmd,disktype);
strcat(cmd," \" |/bin/awk 'NR==2{print$4}'");
//printf(cmd);
str=cmdstring(cmd);
strcat(xml,"<rrqms compare='1'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</rrqms>\n");
//printf(disktype);
memset(cmd,'\0',sizeof(cmd));
strcat(cmd,"/bin/cat iostat.txt |/bin/grep \"^");
strcat(cmd,disktype);
strcat(cmd," \" |/bin/awk 'NR==2{print$5}'");
//printf(cmd);
str=cmdstring(cmd);
strcat(xml,"<wrqms compare='1'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</wrqms>\n");
memset(cmd,'\0',sizeof(cmd));
strcat(cmd,"/bin/cat iostat.txt |/bin/grep \"^");
strcat(cmd,disktype);
strcat(cmd," \" |/bin/awk 'NR==2{print$NF}'");
str=cmdstring(cmd);
strcat(xml,"<ioutil compare='1'>");
strncat(xml,str,strlen(str)-1);
strcat(xml,"</ioutil>\n");
}
catch(...){runlog("出错:获取iostat cpu,rrqm/s,wrqm/s,util");}
//获取Swap的使用
try{
str=cmdstring("/bin/cat /proc/swaps |/bin/grep \"partition\" |/bin/awk -F \" \" '{print $4}'");
strcat(xml,"<Swapuse compare='1'>");
strncat(xml,str,strlen(str)-2);
strcat(xml,"</Swapuse>\n");
}
catch(...){runlog("出错:获取Swap的使用");}
//获取同步状态
try{
memset( slavestatus, '\0', sizeof(slavestatus) );
memset( slavebehind, '\0', sizeof(slavebehind) );
str=cmdstring("/bin/cat /etc/my.cnf |/bin/grep \"^#I am slave\" -|wc -l");//是否是master
ltrim(str);
//printf (str);
if(str[0]=='0')
{
strcat(slavestatus,"Master");
strcat(slavebehind,"0");
}
str=cmdstring("/bin/cat /etc/my.cnf |/bin/grep \"^master_host\" -|wc -l");//是否是master
ltrim(str);
//printf (str);
if(str[0]!='0')
{
strcat(slavestatus,"Master");
strcat(slavebehind,"0");
}
else
{
strcat(slavestatus,"0");
cmdstring("/data/mysql/bin/mysql -umysqlmonitoruser -pUserpassword -e\"show slave status \\G;\" > slavestatus.txt");
str=cmdstring("/bin/cat slavestatus.txt |/bin/grep \"Slave_IO_Running\" |/bin/awk -F\":\" '{print$2}'");;
ltrim(str);
//printf(str);
if(strcmp(str,"Yes\n")!=0)
{
memset( slavestatus, '\0', sizeof(slavestatus) );
strcat(slavestatus,"1");
}
str=cmdstring("/bin/cat slavestatus.txt |/bin/grep \"Slave_SQL_Running\" |/bin/awk -F\":\" '{print$2}'");;
ltrim(str);
if(strcmp(str,"Yes\n")!=0)
{
memset( slavestatus, '\0', sizeof(slavestatus) );
strcat(slavestatus,"1");
}
//同步延迟
str=cmdstring("/bin/cat slavestatus.txt |/bin/grep \"Seconds_Behind_Master\" |/bin/awk -F\":\" '{print$2}'");
ltrim(str);
memset( slavebehind, '\0', sizeof(slavebehind) );
strncat(slavebehind,str,strlen(str)-1);
}
strcat(xml,"<slavestatus compare='2'>");
strcat(xml,slavestatus);
strcat(xml,"</slavestatus>\n");
strcat(xml,"<slavebehind compare='1'>");
strcat(xml,slavebehind);
strcat(xml,"</slavebehind>\n");
}
catch(...){runlog("出错:获取同步状态");}
//xml结尾
try{
strcat(xml,"</monitor>");
strcat(xml,"\r\n***end***end");
//printf(xml);
recvdata=senddata(xml);
}
catch(...){runlog("错误:发送数据");}
printf("recvdata:\n%s\n",recvdata);
//str=getxmlnodevalue("mysql","monitorgroup");
//printf("monitorgroup: %s\n",str);
//replace(xml,"<","<");
//replace(xml,">",">");
printf(xml);
return 0;
}
char * getxmlnodevalue(char * xmlfilename,char * property)
{
xmlDocPtr doc;
xmlNodePtr curNode;
xmlNodePtr cur;
char * resu;
xmlChar * p;
//char p[1024];
//memset(p,'\0',sizeof(p));
doc = xmlParseFile(xmlfilename);
curNode = xmlDocGetRootElement(doc);
if((!xmlStrcmp(curNode->name,(const xmlChar*)"monitor"))){
p = xmlGetProp(curNode,BAD_CAST property);
//p=xmlNodeGetContent(curNode);
resu=reinterpret_cast<char*>(p);
//xmlFree(doc);
}
return resu;
}