/****************************************************************************** * * * Function: parse_item_key * * * * Purpose: parse item command (key) and fill AGENT_REQUEST structure * * * * Parameters: itemkey - complete item key * * * * Return value: request - structure filled with data from item key * * * ******************************************************************************/ int parse_item_key(const char *itemkey, AGENT_REQUEST *request) { int i, ret = FAIL; char *key = NULL, *params = NULL; switch (parse_command_dyn(itemkey, &key, ¶ms)) { case ZBX_COMMAND_WITH_PARAMS: if (0 == (request->nparam = num_param(params))) goto out; /* key is badly formatted */ request->params = zbx_malloc(request->params, request->nparam * sizeof(char *)); for (i = 0; i < request->nparam; i++) request->params[i] = get_param_dyn(params, i + 1); break; case ZBX_COMMAND_ERROR: goto out; /* key is badly formatted */ } request->key = zbx_strdup(NULL, key); ret = SUCCEED; out: zbx_free(params); zbx_free(key); return ret; }
/****************************************************************************** * * * Function: aggregate_get_items * * * * Purpose: get array of items specified by key for selected groups * * * * Parameters: itemids - [OUT] list of item ids * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * * ******************************************************************************/ static void aggregate_get_items(zbx_vector_uint64_t *itemids, const char *groups, const char *itemkey) { const char *__function_name = "aggregate_get_items"; char *group, *esc; DB_RESULT result; DB_ROW row; zbx_uint64_t itemid; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset = 0; int num, n; zabbix_log(LOG_LEVEL_DEBUG, "In %s() groups:'%s' itemkey:'%s'", __function_name, groups, itemkey); sql = zbx_malloc(sql, sql_alloc); esc = DBdyn_escape_string(itemkey); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select distinct i.itemid" " from items i,hosts h,hosts_groups hg,groups g" " where i.hostid=h.hostid" " and h.hostid=hg.hostid" " and hg.groupid=g.groupid" " and i.key_='%s'" " and i.status=%d" " and h.status=%d", esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED); zbx_free(esc); num = num_param(groups); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in ("); for (n = 1; n <= num; n++) { if (NULL == (group = get_param_dyn(groups, n))) continue; esc = DBdyn_escape_string(group); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc); if (n != num) zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ','); zbx_free(esc); zbx_free(group); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ")" DB_NODE, DBnode_local("h.hostid")); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); zbx_vector_uint64_append(itemids, itemid); } DBfree_result(result); zbx_vector_uint64_sort(itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static int calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp, char *error, int max_error_len) { const char *__function_name = "calcitem_evaluate_expression"; function_t *f = NULL; char *buf, replace[16], *errstr = NULL; int i, ret = SUCCEED; time_t now; zbx_host_key_t *keys = NULL; DC_ITEM *items = NULL; int *errcodes = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (0 == exp->functions_num) return ret; keys = zbx_malloc(keys, sizeof(zbx_host_key_t) * exp->functions_num); items = zbx_malloc(items, sizeof(DC_ITEM) * exp->functions_num); errcodes = zbx_malloc(errcodes, sizeof(int) * exp->functions_num); for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; buf = get_param_dyn(f->params, 1); /* for first parameter result is not NULL */ if (SUCCEED != parse_host_key(buf, &f->host, &f->key)) { zbx_snprintf(error, max_error_len, "Invalid first parameter in function [%s(%s)].", f->func, f->params); ret = NOTSUPPORTED; } zbx_free(buf); if (SUCCEED != ret) goto out; if (NULL == f->host) f->host = strdup(dc_item->host.host); keys[i].host = f->host; keys[i].key = f->key; remove_param(f->params, 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'", __function_name, f->host, f->key, f->func, f->params); } DCconfig_get_items_by_keys(items, keys, errcodes, exp->functions_num); now = time(NULL); for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; if (SUCCEED != errcodes[i]) { zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\":" " item \"%s:%s\" does not exist.", f->func, f->params, f->host, f->key); ret = NOTSUPPORTED; break; } if (ITEM_STATUS_ACTIVE != items[i].status) { zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\":" " item \"%s:%s\" is disabled.", f->func, f->params, f->host, f->key); ret = NOTSUPPORTED; break; } if (HOST_STATUS_MONITORED != items[i].host.status) { zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\":" " item \"%s:%s\" belongs to a disabled host.", f->func, f->params, f->host, f->key); ret = NOTSUPPORTED; break; } if (ITEM_STATE_NOTSUPPORTED == items[i].state) { zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\": item \"%s:%s\" not supported.", f->func, f->params, f->host, f->key); ret = NOTSUPPORTED; break; } f->value = zbx_malloc(f->value, MAX_BUFFER_LEN); if (SUCCEED != evaluate_function(f->value, &items[i], f->func, f->params, now, &errstr)) { if (NULL != errstr) { zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\": %s.", f->func, f->params, errstr); zbx_free(errstr); } else { zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\".", f->func, f->params); } ret = NOTSUPPORTED; break; } if (SUCCEED != is_double_suffix(f->value) || '-' == *f->value) { char *wrapped; wrapped = zbx_dsprintf(NULL, "(%s)", f->value); zbx_free(f->value); f->value = wrapped; } else f->value = zbx_realloc(f->value, strlen(f->value) + 1); zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid); buf = string_replace(exp->exp, replace, f->value); zbx_free(exp->exp); exp->exp = buf; } DCconfig_clean_items(items, errcodes, exp->functions_num); out: zbx_free(errcodes); zbx_free(items); zbx_free(keys); return ret; }
static int calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp, char *error, int max_error_len) { const char *__function_name = "calcitem_evaluate_expression"; function_t *f = NULL; char *sql = NULL, *host_esc, *key_esc, *buf, replace[16]; int sql_alloc = 1024, sql_offset = 0, i, ret = SUCCEED; time_t now; DB_RESULT db_result; DB_ROW db_row; DB_ITEM item; zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __function_name, exp->exp); if (0 == exp->functions_num) return ret; for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; buf = get_param_dyn(f->params, 1); /* for first parameter result is not NULL */ if (SUCCEED != parse_host_key(buf, &f->host, &f->key)) { zbx_snprintf(error, max_error_len, "Invalid first parameter in function [%s(%s)]", f->func, f->params); ret = NOTSUPPORTED; } zbx_free(buf); if (SUCCEED != ret) break; if (NULL == f->host) f->host = strdup(dc_item->host.host); remove_param(f->params, 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'", __function_name, f->host, f->key, f->func, f->params); } if (SUCCEED != ret) return ret; now = time(NULL); sql = zbx_malloc(sql, sql_alloc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "select %s" " where h.hostid=i.hostid" " and h.status=%d" " and i.status=%d" " and (", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE); for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; if (i != 0) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, " or "); host_esc = DBdyn_escape_string(f->host); key_esc = DBdyn_escape_string(f->key); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 32 + strlen(host_esc) + strlen(key_esc), "(h.host='%s' and i.key_='%s')", host_esc, key_esc); zbx_free(key_esc); zbx_free(host_esc); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 130, ")" DB_NODE, DBnode_local("h.hostid")); db_result = DBselect("%s", sql); zbx_free(sql); while (NULL != (db_row = DBfetch(db_result))) { DBget_item_from_db(&item, db_row); for (i = 0; i < exp->functions_num; i++) { f = &exp->functions[i]; if (0 != strcmp(f->key, item.key_orig)) continue; if (0 != strcmp(f->host, item.host_name)) continue; f->found = 1; f->value = zbx_malloc(f->value, MAX_BUFFER_LEN); if (SUCCEED != evaluate_function(f->value, &item, f->func, f->params, now)) { zbx_snprintf(error, max_error_len, "Cannot evaluate function [%s(%s)]", f->func, f->params); ret = NOTSUPPORTED; break; } else f->value = zbx_realloc(f->value, strlen(f->value) + 1); } if (SUCCEED != ret) break; } DBfree_result(db_result); if (SUCCEED != ret) return ret; for (i = 0; i < exp->functions_num; i ++) { f = &exp->functions[i]; if (0 == f->found) { zbx_snprintf(error, max_error_len, "Cannot evaluate function [%s(%s)]" ": item [%s:%s] not found", f->func, f->params, f->host, f->key); ret = NOTSUPPORTED; break; } zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid); buf = string_replace(exp->exp, replace, f->value); zbx_free(exp->exp); exp->exp = buf; } return ret; }
/****************************************************************************** * * * Function: aggregate_get_items * * * * Purpose: get array of items specified by key for selected groups * * * * Parameters: ids - result, list of items * * groups - list of comma-separated host groups * * itemkey - item key to aggregate * * * ******************************************************************************/ static void aggregate_get_items(zbx_uint64_t **ids, int *ids_alloc, int *ids_num, const char *groups, const char *itemkey) { char *group, *esc; DB_RESULT result; DB_ROW row; zbx_uint64_t itemid; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset = 0; int num, n; sql = zbx_malloc(sql, sql_alloc); esc = DBdyn_escape_string(itemkey); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "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 i.key_='%s'" " and i.status=%d" " and h.status=%d", esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED); zbx_free(esc); num = num_param(groups); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in ("); for (n = 1; n <= num; n++) { if (NULL == (group = get_param_dyn(groups, n))) continue; esc = DBdyn_escape_string(group); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc); if (n != num) zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ','); zbx_free(esc); zbx_free(group); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ")" DB_NODE, DBnode_local("h.hostid")); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); uint64_array_add(ids, ids_alloc, ids_num, itemid, 64); } DBfree_result(result); }