/****************************************************************************** * * * Function: collect_selfmon_stats * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void collect_selfmon_stats() { const char *__function_name = "collect_selfmon_stats"; zbx_stat_process_t *process; clock_t ticks; struct tms buf; unsigned char process_type, state; int process_num, process_forks, index; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); ticks = times(&buf); LOCK_SM; if (MAX_HISTORY <= (index = collector->first + collector->count)) index -= MAX_HISTORY; if (collector->count < MAX_HISTORY) collector->count++; else if (++collector->first == MAX_HISTORY) collector->first = 0; for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++) { process_forks = get_process_type_forks(process_type); for (process_num = 0; process_num < process_forks; process_num++) { process = &collector->process[process_type][process_num]; for (state = 0; state < ZBX_PROCESS_STATE_COUNT; state++) process->h_counter[state][index] = process->counter[state]; if (ticks > process->last_ticks) process->h_counter[process->last_state][index] += ticks - process->last_ticks; } } UNLOCK_SM; zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: get_selfmon_stats * * * * Purpose: calculate statistics for selected process * * * * Parameters: process_type - [IN] type of process; ZBX_PROCESS_TYPE_* * * aggr_func - [IN] one of ZBX_AGGR_FUNC_* * * process_num - [IN] process number; 1 - first process; * * 0 - all processes * * state - [IN] process state; ZBX_PROCESS_STATE_* * * value - [OUT] a pointer to a variable that receives * * requested statistics * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void get_selfmon_stats(unsigned char process_type, unsigned char aggr_func, int process_num, unsigned char state, double *value) { const char *__function_name = "get_selfmon_stats"; unsigned int total = 0, counter = 0; unsigned char s; int process_forks, current; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); process_forks = get_process_type_forks(process_type); switch (aggr_func) { case ZBX_AGGR_FUNC_ONE: assert(0 < process_num && process_num <= process_forks); process_forks = process_num--; break; case ZBX_AGGR_FUNC_AVG: case ZBX_AGGR_FUNC_MAX: case ZBX_AGGR_FUNC_MIN: assert(0 == process_num && 0 < process_forks); break; default: assert(0); } LOCK_SM; if (collector->count <= 1) goto unlock; if (MAX_HISTORY <= (current = (collector->first + collector->count - 1))) current -= MAX_HISTORY; for (; process_num < process_forks; process_num++) { zbx_stat_process_t *process; unsigned short one_total = 0, one_counter; process = &collector->process[process_type][process_num]; for (s = 0; s < ZBX_PROCESS_STATE_COUNT; s++) one_total += process->h_counter[s][current] - process->h_counter[s][collector->first]; one_counter = process->h_counter[state][current] - process->h_counter[state][collector->first]; switch (aggr_func) { case ZBX_AGGR_FUNC_ONE: case ZBX_AGGR_FUNC_AVG: total += one_total; counter += one_counter; break; case ZBX_AGGR_FUNC_MAX: if (0 == process_num || one_counter > counter) { counter = one_counter; total = one_total; } break; case ZBX_AGGR_FUNC_MIN: if (0 == process_num || one_counter < counter) { counter = one_counter; total = one_total; } break; } } unlock: UNLOCK_SM; *value = (0 == total ? 0 : 100. * (double)counter / (double)total); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: get_value_internal * * * * Purpose: retrieve data from Zabbix server (internally supported items) * * * * Parameters: item - item we are interested in * * * * Return value: SUCCEED - data successfully retrieved and stored in result * * NOTSUPPORTED - requested item is not supported * * * * Author: Alexei Vladishev * * * ******************************************************************************/ int get_value_internal(DC_ITEM *item, AGENT_RESULT *result) { int nparams; char params[MAX_STRING_LEN], *error = NULL; char tmp[MAX_STRING_LEN], tmp1[HOST_HOST_LEN_MAX]; init_result(result); if (0 != strncmp(item->key, "zabbix[", 7)) goto notsupported; if (2 != parse_command(item->key, NULL, 0, params, sizeof(params))) goto notsupported; if (0 != get_param(params, 1, tmp, sizeof(tmp))) goto notsupported; nparams = num_param(params); if (0 == strcmp(tmp, "triggers")) /* zabbix["triggers"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, DBget_row_count("triggers")); } else if (0 == strcmp(tmp, "items")) /* zabbix["items"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, DBget_row_count("items")); } else if (0 == strcmp(tmp, "items_unsupported")) /* zabbix["items_unsupported"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, DBget_items_unsupported_count()); } else if (0 == strcmp(tmp, "history") || /* zabbix["history"] */ 0 == strcmp(tmp, "history_log") || /* zabbix["history_log"] */ 0 == strcmp(tmp, "history_str") || /* zabbix["history_str"] */ 0 == strcmp(tmp, "history_text") || /* zabbix["history_text"] */ 0 == strcmp(tmp, "history_uint")) /* zabbix["history_uint"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, DBget_row_count(tmp)); } else if (0 == strcmp(tmp, "trends") || /* zabbix["trends"] */ 0 == strcmp(tmp, "trends_uint")) /* zabbix["trends_uint"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, DBget_row_count(tmp)); } else if (0 == strcmp(tmp, "queue")) /* zabbix["queue",<from>,<to>] */ { unsigned int from = 6, to = (unsigned int)-1; if (3 < nparams) { error = zbx_strdup(error, "Invalid number of parameters"); goto notsupported; } if (2 <= nparams) { if (0 != get_param(params, 2, tmp, sizeof(tmp))) goto notsupported; if ('\0' != *tmp && FAIL == is_uint_suffix(tmp, &from)) { error = zbx_strdup(error, "Invalid second parameter"); goto notsupported; } } if (3 <= nparams) { if (0 != get_param(params, 3, tmp, sizeof(tmp))) goto notsupported; if ('\0' != *tmp && FAIL == is_uint_suffix(tmp, &to)) { error = zbx_strdup(error, "Invalid third parameter"); goto notsupported; } } if ((unsigned int)-1 != to && from > to) { error = zbx_strdup(error, "Parameters represent an invalid interval"); goto notsupported; } SET_UI64_RESULT(result, DBget_queue_count((int)from, (int)to)); } else if (0 == strcmp(tmp, "requiredperformance")) /* zabbix["requiredperformance"] */ { if (1 != nparams) goto notsupported; SET_DBL_RESULT(result, DBget_requiredperformance()); } else if (0 == strcmp(tmp, "uptime")) /* zabbix["uptime"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, time(NULL) - CONFIG_SERVER_STARTUP_TIME); } else if (0 == strcmp(tmp, "boottime")) /* zabbix["boottime"] */ { if (1 != nparams) goto notsupported; SET_UI64_RESULT(result, CONFIG_SERVER_STARTUP_TIME); } else if (0 == strcmp(tmp, "host")) /* zabbix["host",<type>,"available"] */ { if (3 != nparams) goto notsupported; if (0 != get_param(params, 3, tmp, sizeof(tmp)) || 0 != strcmp(tmp, "available")) goto notsupported; if (0 != get_param(params, 2, tmp, sizeof(tmp))) goto notsupported; if (0 == strcmp(tmp, "agent")) SET_UI64_RESULT(result, item->host.available); else if (0 == strcmp(tmp, "snmp")) SET_UI64_RESULT(result, item->host.snmp_available); else if (0 == strcmp(tmp, "ipmi")) SET_UI64_RESULT(result, item->host.ipmi_available); else if (0 == strcmp(tmp, "jmx")) SET_UI64_RESULT(result, item->host.jmx_available); else goto notsupported; result->ui64 = 2 - result->ui64; } else if (0 == strcmp(tmp, "proxy")) /* zabbix["proxy",<hostname>,"lastaccess"] */ { int lastaccess; if (3 != nparams) goto notsupported; if (0 != get_param(params, 2, tmp1, sizeof(tmp1))) goto notsupported; if (0 != get_param(params, 3, tmp, sizeof(tmp)) || 0 != strcmp(tmp, "lastaccess")) goto notsupported; if (FAIL == DBget_proxy_lastaccess(tmp1, &lastaccess, &error)) goto notsupported; SET_UI64_RESULT(result, lastaccess); } else if (0 == strcmp(tmp, "java")) /* zabbix["java",...] */ { int res; alarm(CONFIG_TIMEOUT); res = get_value_java(ZBX_JAVA_GATEWAY_REQUEST_INTERNAL, item, result); alarm(0); if (SUCCEED != res) goto notsupported; } else if (0 == strcmp(tmp, "process")) /* zabbix["process",<type>,<mode>,<state>] */ { unsigned char process_type; int process_forks; double value; if (4 < nparams) { error = zbx_strdup(error, "Invalid number of parameters"); goto notsupported; } if (0 != get_param(params, 2, tmp, sizeof(tmp))) { error = zbx_strdup(error, "Required second parameter missing"); goto notsupported; } for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++) if (0 == strcmp(tmp, get_process_type_string(process_type))) break; if (ZBX_PROCESS_TYPE_COUNT == process_type) { error = zbx_strdup(error, "Invalid second parameter"); goto notsupported; } process_forks = get_process_type_forks(process_type); if (0 != get_param(params, 3, tmp, sizeof(tmp))) *tmp = '\0'; if (0 == strcmp(tmp, "count")) { if (3 < nparams) { error = zbx_strdup(error, "Invalid number of parameters"); goto notsupported; } SET_UI64_RESULT(result, process_forks); } else { unsigned char aggr_func, state; unsigned short process_num = 0; if ('\0' == *tmp || 0 == strcmp(tmp, "avg")) aggr_func = ZBX_AGGR_FUNC_AVG; else if (0 == strcmp(tmp, "max")) aggr_func = ZBX_AGGR_FUNC_MAX; else if (0 == strcmp(tmp, "min")) aggr_func = ZBX_AGGR_FUNC_MIN; else if (SUCCEED == is_ushort(tmp, &process_num) && 0 < process_num) aggr_func = ZBX_AGGR_FUNC_ONE; else { error = zbx_strdup(error, "Invalid third parameter"); goto notsupported; } if (0 == process_forks) { error = zbx_dsprintf(error, "No \"%s\" processes started", get_process_type_string(process_type)); goto notsupported; } else if (process_num > process_forks) { error = zbx_dsprintf(error, "\"%s\" #%d is not started", get_process_type_string(process_type), process_num); goto notsupported; } if (0 != get_param(params, 4, tmp, sizeof(tmp))) *tmp = '\0'; if ('\0' == *tmp || 0 == strcmp(tmp, "busy")) state = ZBX_PROCESS_STATE_BUSY; else if (0 == strcmp(tmp, "idle")) state = ZBX_PROCESS_STATE_IDLE; else { error = zbx_strdup(error, "Invalid fourth parameter"); goto notsupported; } get_selfmon_stats(process_type, aggr_func, process_num, state, &value); SET_DBL_RESULT(result, value); } } else if (0 == strcmp(tmp, "wcache")) /* zabbix[wcache,<cache>,<mode>] */ { if (3 < nparams) goto notsupported; if (0 != get_param(params, 2, tmp, sizeof(tmp))) goto notsupported; if (0 != get_param(params, 3, tmp1, sizeof(tmp1))) *tmp1 = '\0'; if (0 == strcmp(tmp, "values")) { if ('\0' == *tmp1 || 0 == strcmp(tmp1, "all")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_COUNTER)); else if (0 == strcmp(tmp1, "float")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FLOAT_COUNTER)); else if (0 == strcmp(tmp1, "uint")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_UINT_COUNTER)); else if (0 == strcmp(tmp1, "str")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_STR_COUNTER)); else if (0 == strcmp(tmp1, "log")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_LOG_COUNTER)); else if (0 == strcmp(tmp1, "text")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TEXT_COUNTER)); else if (0 == strcmp(tmp1, "not supported")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_NOTSUPPORTED_COUNTER)); else goto notsupported; } else if (0 == strcmp(tmp, "history")) { if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_HISTORY_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_HISTORY_FREE)); else goto notsupported; } else if (0 == strcmp(tmp, "trend")) { if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TREND_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TREND_FREE)); else goto notsupported; } else if (0 == strcmp(tmp, "text")) { if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCget_stats(ZBX_STATS_TEXT_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TEXT_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TEXT_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCget_stats(ZBX_STATS_TEXT_FREE)); else goto notsupported; } else goto notsupported; } else if (0 == strcmp(tmp, "rcache")) /* zabbix[rcache,<cache>,<mode>] */ { if (3 < nparams) goto notsupported; if (0 != get_param(params, 2, tmp, sizeof(tmp))) goto notsupported; if (0 != get_param(params, 3, tmp1, sizeof(tmp1))) *tmp1 = '\0'; if (0 == strcmp(tmp, "buffer")) { if ('\0' == *tmp1 || 0 == strcmp(tmp1, "pfree")) SET_DBL_RESULT(result, *(double *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_PFREE)); else if (0 == strcmp(tmp1, "total")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_TOTAL)); else if (0 == strcmp(tmp1, "used")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_USED)); else if (0 == strcmp(tmp1, "free")) SET_UI64_RESULT(result, *(zbx_uint64_t *)DCconfig_get_stats(ZBX_CONFSTATS_BUFFER_FREE)); else goto notsupported; } else goto notsupported; } else goto notsupported; return SUCCEED; notsupported: if (!ISSET_MSG(result)) { if (NULL == error) error = zbx_strdup(error, "Internal check is not supported"); SET_MSG_RESULT(result, error); } return NOTSUPPORTED; }
/****************************************************************************** * * * Function: init_selfmon_collector * * * * Purpose: Initialize structures and prepare state * * for self-monitoring collector * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void init_selfmon_collector() { const char *__function_name = "init_selfmon_collector"; size_t sz, sz_array, sz_process[ZBX_PROCESS_TYPE_COUNT], sz_total; key_t shm_key; char *p; clock_t ticks; struct tms buf; unsigned char process_type; int process_num, process_forks; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sz_total = sz = sizeof(zbx_selfmon_collector_t); sz_total += sz_array = sizeof(zbx_stat_process_t *) * ZBX_PROCESS_TYPE_COUNT; for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++) sz_total += sz_process[process_type] = sizeof(zbx_stat_process_t) * get_process_type_forks(process_type); zabbix_log(LOG_LEVEL_DEBUG, "%s() size:%d", __function_name, (int)sz_total); if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, ZBX_IPC_SELFMON_ID))) { zabbix_log(LOG_LEVEL_CRIT, "Cannot create IPC key for a self-monitoring collector"); exit(FAIL); } if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&sm_lock, ZBX_MUTEX_SELFMON)) { zbx_error("Unable to create mutex for a self-monitoring collector"); exit(FAIL); } if (-1 == (shm_id = zbx_shmget(shm_key, sz_total))) { zabbix_log(LOG_LEVEL_CRIT, "Cannot allocate shared memory for a self-monitoring collector"); exit(FAIL); } if ((void *)(-1) == (p = shmat(shm_id, NULL, 0))) { zabbix_log(LOG_LEVEL_CRIT, "Cannot attach shared memory for a self-monitoring collector [%s]", strerror(errno)); exit(FAIL); } collector = (zbx_selfmon_collector_t *)p; p += sz; collector->process = (zbx_stat_process_t **)p; p += sz_array; ticks = times(&buf); for (process_type = 0; process_type < ZBX_PROCESS_TYPE_COUNT; process_type++) { collector->process[process_type] = (zbx_stat_process_t *)p; p += sz_process[process_type]; memset(collector->process[process_type], 0, sz_process[process_type]); process_forks = get_process_type_forks(process_type); for (process_num = 0; process_num < process_forks; process_num++) { collector->process[process_type][process_num].last_ticks = ticks; collector->process[process_type][process_num].last_state = ZBX_PROCESS_STATE_BUSY; } } zabbix_log(LOG_LEVEL_DEBUG, "End of %s() collector:%p", __function_name, collector); }
int get_value_simple(DC_ITEM *item, AGENT_RESULT *result, zbx_vector_ptr_t *add_results) { AGENT_REQUEST request; vmfunc_t vmfunc; int ret = NOTSUPPORTED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key_orig:'%s' addr:'%s'", __func__, item->key_orig, item->interface.addr); init_request(&request); if (SUCCEED != parse_item_key(item->key, &request)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid item key format.")); goto out; } request.lastlogsize = item->lastlogsize; if (0 == strcmp(request.key, "net.tcp.service") || 0 == strcmp(request.key, "net.udp.service")) { if (SYSINFO_RET_OK == check_service(&request, item->interface.addr, result, 0)) ret = SUCCEED; } else if (0 == strcmp(request.key, "net.tcp.service.perf") || 0 == strcmp(request.key, "net.udp.service.perf")) { if (SYSINFO_RET_OK == check_service(&request, item->interface.addr, result, 1)) ret = SUCCEED; } else if (SUCCEED == get_vmware_function(request.key, &vmfunc)) { if (NULL != vmfunc) { if (0 == get_process_type_forks(ZBX_PROCESS_TYPE_VMWARE)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "No \"vmware collector\" processes started.")); goto out; } if (SYSINFO_RET_OK == vmfunc(&request, item->username, item->password, result)) ret = SUCCEED; } else SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for VMware checks was not compiled in.")); } else if (0 == strcmp(request.key, ZBX_VMWARE_PREFIX "eventlog")) { #if defined(HAVE_LIBXML2) && defined(HAVE_LIBCURL) if (SYSINFO_RET_OK == check_vcenter_eventlog(&request, item, result, add_results)) ret = SUCCEED; #else ZBX_UNUSED(add_results); SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for VMware checks was not compiled in.")); #endif } else { /* it will execute item from a loadable module if any */ if (SUCCEED == process(item->key, PROCESS_MODULE_COMMAND, result)) ret = SUCCEED; } if (NOTSUPPORTED == ret && !ISSET_MSG(result)) SET_MSG_RESULT(result, zbx_strdup(NULL, "Simple check is not supported.")); out: free_request(&request); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); return ret; }