/* ** ZABBIX ** Copyright (C) 2000-2005 SIA Zabbix ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **/ #include "common.h" #include "log.h" #include "checks_aggregate.h" static int evaluate_one(double *result, int *num, char *grpfunc, char const *value_str, int valuetype) { int ret = SUCCEED; double value = 0; if(valuetype == ITEM_VALUE_TYPE_FLOAT) { value = zbx_atod(value_str); } else if(valuetype == ITEM_VALUE_TYPE_UINT64) { value = (double)zbx_atoui64(value_str); } if(strcmp(grpfunc,"grpsum") == 0) { *result+=value; *num+=1; } else if(strcmp(grpfunc,"grpavg") == 0) { *result+=value; *num+=1; } else if(strcmp(grpfunc,"grpmin") == 0) { if(*num==0) { *result=value; } else if(value<*result) { *result=value; } *num+=1; } else if(strcmp(grpfunc,"grpmax") == 0) { if(*num==0) { *result=value; } else if(value>*result) { *result=value; } *num+=1; } else { ret = FAIL; } return ret; } /* * grpfunc: grpmax, grpmin, grpsum, grpavg * itemfunc: last, min, max, avg, sum,count */ static int evaluate_aggregate(AGENT_RESULT *res,char *grpfunc, char *hostgroup, char *itemkey, char *itemfunc, char *param) { char sql[MAX_STRING_LEN]; char sql2[MAX_STRING_LEN]; char hostgroup_esc[MAX_STRING_LEN],itemkey_esc[MAX_STRING_LEN]; DB_RESULT result; DB_ROW row; int valuetype; double d = 0; const char *value; int num = 0; int now; char items[MAX_STRING_LEN],items2[MAX_STRING_LEN]; now=time(NULL); zabbix_log( LOG_LEVEL_DEBUG, "In evaluate_aggregate('%s','%s','%s','%s','%s')", grpfunc, hostgroup, itemkey, itemfunc, param); init_result(res); DBescape_string(itemkey,itemkey_esc,MAX_STRING_LEN); DBescape_string(hostgroup,hostgroup_esc,MAX_STRING_LEN); /* Get list of affected item IDs */ strscpy(items,"0"); result = DBselect("select i.itemid from items i,hosts_groups hg,hosts h,groups g" " where hg.groupid=g.groupid and i.hostid=h.hostid and hg.hostid=h.hostid" " and g.name='%s' and i.key_='%s' and i.status=%d and h.status=%d" DB_NODE, hostgroup_esc, itemkey_esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED, DBnode_local("h.hostid")); while((row=DBfetch(result))) { zbx_snprintf(items2,sizeof(items2),"%s,%s", items, row[0]); /* zabbix_log( LOG_LEVEL_WARNING, "ItemIDs items2[%s])",items2);*/ strscpy(items,items2); /* zabbix_log( LOG_LEVEL_WARNING, "ItemIDs items[%s])",items2);*/ } DBfree_result(result); if(strcmp(itemfunc,"last") == 0) { zbx_snprintf(sql,sizeof(sql),"select itemid,value_type,lastvalue from items where lastvalue is not NULL and items.itemid in (%s)", items); zbx_snprintf(sql2,sizeof(sql2),"select itemid,value_type,lastvalue from items where 0=1"); } /* The SQL works very very slow on MySQL 4.0. That's why it has been split into two. */ /* zbx_snprintf(sql,sizeof(sql),"select items.itemid,items.value_type,min(history.value) from items,hosts_groups,hosts,groups,history where history.itemid=items.itemid and hosts_groups.groupid=groups.groupid and items.hostid=hosts.hostid and hosts_groups.hostid=hosts.hostid and groups.name='%s' and items.key_='%s' and history.clock>%d group by 1,2",hostgroup_esc, itemkey_esc, now - atoi(param));*/ else if( (strcmp(itemfunc,"min") == 0) || (strcmp(itemfunc,"max") == 0) || (strcmp(itemfunc,"avg") == 0) || (strcmp(itemfunc,"count") == 0) || (strcmp(itemfunc,"sum") == 0) ) { zbx_snprintf(sql,sizeof(sql),"select h.itemid,i.value_type,%s(h.value) from items i,history h where h.itemid=i.itemid and h.itemid in (%s) and h.clock>%d group by h.itemid,i.value_type", itemfunc, items, now - atoi(param)); zbx_snprintf(sql2,sizeof(sql),"select h.itemid,i.value_type,%s(h.value) from items i,history_uint h where h.itemid=i.itemid and h.itemid in (%s) and h.clock>%d group by h.itemid,i.value_type", itemfunc, items, now - atoi(param)); } else { SET_MSG_RESULT(res, strdup("Unsupported item function")); zabbix_log( LOG_LEVEL_WARNING, "Unsupported item function [%s])", itemfunc); return FAIL; } zabbix_log( LOG_LEVEL_DEBUG, "SQL [%s]",sql); zabbix_log( LOG_LEVEL_DEBUG, "SQL2 [%s]",sql2); result = DBselect("%s",sql); while((row=DBfetch(result))) { valuetype = atoi(row[1]); value = row[2]; if(FAIL == evaluate_one(&d, &num, grpfunc, value, valuetype)) { SET_MSG_RESULT(res, strdup("Unsupported group function")); zabbix_log( LOG_LEVEL_WARNING, "Unsupported group function [%s])", grpfunc); DBfree_result(result); return FAIL; } } DBfree_result(result); result = DBselect("%s",sql2); while((row=DBfetch(result))) { valuetype = atoi(row[1]); value = row[2]; if(FAIL == evaluate_one(&d, &num, grpfunc, value, valuetype)) { SET_MSG_RESULT(res, strdup("Unsupported group function")); zabbix_log( LOG_LEVEL_WARNING, "Unsupported group function [%s])", grpfunc); DBfree_result(result); return FAIL; } } DBfree_result(result); if(num==0) { SET_MSG_RESULT(res, strdup("No values")); zabbix_log( LOG_LEVEL_WARNING, "No values for group[%s] key[%s])", hostgroup, itemkey); return FAIL; } if(strcmp(grpfunc,"grpavg") == 0) { SET_DBL_RESULT(res, d/num); } else { SET_DBL_RESULT(res, d); } zabbix_log( LOG_LEVEL_DEBUG, "End evaluate_aggregate(result:" ZBX_FS_DBL ")", d); return SUCCEED; } /****************************************************************************** * * * Function: get_value_aggregate * * * * Purpose: retrieve data from ZABBIX server (aggregate items) * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data succesfully retrieved and stored in result * * and result_str (as string) * * NOTSUPPORTED - requested item is not supported * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int get_value_aggregate(DB_ITEM *item, AGENT_RESULT *result) { char function_grp[MAX_STRING_LEN]; char key[MAX_STRING_LEN]; char group[MAX_STRING_LEN]; char itemkey[MAX_STRING_LEN]; char function_item[MAX_STRING_LEN]; char parameter[MAX_STRING_LEN]; char *p,*p2; int ret = SUCCEED; zabbix_log( LOG_LEVEL_DEBUG, "In get_value_aggregate([%s])", item->key); init_result(result); strscpy(key, item->key); if((p=strchr(key,'[')) != NULL) { *p=0; strscpy(function_grp,key); *p='['; p++; } else ret = NOTSUPPORTED; if(ret == SUCCEED) { if((p2=strchr(p,'"')) != NULL) { p2++; } else ret = NOTSUPPORTED; if((ret == SUCCEED) && (p=strchr(p2,'"')) != NULL) { *p=0; strscpy(group,p2); *p='"'; p++; } else ret = NOTSUPPORTED; } if(ret == SUCCEED) { if(*p != ',') ret = NOTSUPPORTED; } if(ret == SUCCEED) { if((p2=strchr(p,'"')) != NULL) { p2++; } else ret = NOTSUPPORTED; if((ret == SUCCEED) && (p=strchr(p2,'"')) != NULL) { *p=0; strscpy(itemkey,p2); *p='"'; p++; } else ret = NOTSUPPORTED; } if(ret == SUCCEED) { if(*p != ',') ret = NOTSUPPORTED; } if(ret == SUCCEED) { if((p2=strchr(p,'"')) != NULL) { p2++; } else ret = NOTSUPPORTED; if((ret == SUCCEED) && (p=strchr(p2,'"')) != NULL) { *p=0; strscpy(function_item,p2); *p='"'; p++; } else ret = NOTSUPPORTED; } if(ret == SUCCEED) { if(*p != ',') ret = NOTSUPPORTED; } if(ret == SUCCEED) { if((p2=strchr(p,'"')) != NULL) { p2++; } else ret = NOTSUPPORTED; if((ret == SUCCEED) && (p=strchr(p2,'"')) != NULL) { *p=0; strscpy(parameter,p2); *p='"'; p++; } else ret = NOTSUPPORTED; } zabbix_log( LOG_LEVEL_DEBUG, "Evaluating aggregate[%s] grpfunc[%s] group[%s] itemkey[%s] itemfunc [%s] parameter [%s]", item->key, function_grp, group, itemkey, function_item, parameter); if( (ret == SUCCEED) && (evaluate_aggregate(result,function_grp, group, itemkey, function_item, parameter) != SUCCEED) ) { ret = NOTSUPPORTED; } return ret; }