/****************************************************************************** * * * Function: lld_condition_free * * * * Purpose: release resources allocated by filter condition * * * * Parameters: condition - [IN] the filter condition * * * ******************************************************************************/ static void lld_condition_free(lld_condition_t *condition) { zbx_regexp_clean_expressions(&condition->regexps); zbx_vector_ptr_destroy(&condition->regexps); zbx_free(condition->macro); zbx_free(condition->regexp); zbx_free(condition); }
static void free_active_metrics(void) { int i; zabbix_log(LOG_LEVEL_DEBUG, "In free_active_metrics()"); for (i = 0; NULL != active_metrics[i].key; i++) zbx_free(active_metrics[i].key); zbx_free(active_metrics); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); }
/****************************************************************************** * * * Function: process_trap_for_interface * * * * Purpose: add trap to all matching items for the specified interface * * * * Return value: SUCCEED - a matching item was found * * FAIL - no matching item was found (including fallback items) * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ static int process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_timespec_t *ts) { DC_ITEM *items = NULL; const char *regex; char error[ITEM_ERROR_LEN_MAX]; size_t num, i; int ret = FAIL, fb = -1, *lastclocks = NULL, *errcodes = NULL; zbx_uint64_t *itemids = NULL; unsigned char *states = NULL; AGENT_RESULT *results = NULL; AGENT_REQUEST request; zbx_vector_ptr_t regexps; zbx_vector_ptr_create(®exps); num = DCconfig_get_snmp_items_by_interfaceid(interfaceid, &items); itemids = zbx_malloc(itemids, sizeof(zbx_uint64_t) * num); states = zbx_malloc(states, sizeof(unsigned char) * num); lastclocks = zbx_malloc(lastclocks, sizeof(int) * num); errcodes = zbx_malloc(errcodes, sizeof(int) * num); results = zbx_malloc(results, sizeof(AGENT_RESULT) * num); for (i = 0; i < num; i++) { init_result(&results[i]); errcodes[i] = FAIL; items[i].key = zbx_strdup(items[i].key, items[i].key_orig); if (SUCCEED != substitute_key_macros(&items[i].key, NULL, &items[i], NULL, MACRO_TYPE_ITEM_KEY, error, sizeof(error))) { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error)); errcodes[i] = NOTSUPPORTED; continue; } if (0 == strcmp(items[i].key, "snmptrap.fallback")) { fb = i; continue; } init_request(&request); if (SUCCEED != parse_item_key(items[i].key, &request)) goto next; if (0 != strcmp(get_rkey(&request), "snmptrap")) goto next; if (1 < get_rparams_num(&request)) goto next; if (NULL != (regex = get_rparam(&request, 0))) { if ('@' == *regex) { DCget_expressions_by_name(®exps, regex + 1); if (0 == regexps.values_num) { SET_MSG_RESULT(&results[i], zbx_dsprintf(NULL, "Global regular expression \"%s\" does not exist.", regex + 1)); errcodes[i] = NOTSUPPORTED; goto next; } } if (SUCCEED != regexp_match_ex(®exps, trap, regex, ZBX_CASE_SENSITIVE)) goto next; } if (SUCCEED == set_result_type(&results[i], items[i].value_type, items[i].data_type, trap)) errcodes[i] = SUCCEED; else errcodes[i] = NOTSUPPORTED; ret = SUCCEED; next: free_request(&request); } if (FAIL == ret && -1 != fb) { if (SUCCEED == set_result_type(&results[fb], items[fb].value_type, items[fb].data_type, trap)) errcodes[fb] = SUCCEED; else errcodes[fb] = NOTSUPPORTED; ret = SUCCEED; } for (i = 0; i < num; i++) { switch (errcodes[i]) { case SUCCEED: if (ITEM_VALUE_TYPE_LOG == items[i].value_type) { calc_timestamp(results[i].log->value, &results[i].log->timestamp, items[i].logtimefmt); } items[i].state = ITEM_STATE_NORMAL; dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, &results[i], ts, items[i].state, NULL); itemids[i] = items[i].itemid; states[i] = items[i].state; lastclocks[i] = ts->sec; break; case NOTSUPPORTED: items[i].state = ITEM_STATE_NOTSUPPORTED; dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL, ts, items[i].state, results[i].msg); itemids[i] = items[i].itemid; states[i] = items[i].state; lastclocks[i] = ts->sec; break; } zbx_free(items[i].key); free_result(&results[i]); } zbx_free(results); DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num); zbx_free(errcodes); zbx_free(lastclocks); zbx_free(states); zbx_free(itemids); DCconfig_clean_items(items, NULL, num); zbx_free(items); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); dc_flush_history(); return ret; }
static int lld_rows_get(char *value, char *filter, zbx_vector_ptr_t *lld_rows, char **error) { const char *__function_name = "lld_rows_get"; struct zbx_json_parse jp, jp_data, jp_row; char *f_macro = NULL, *f_regexp = NULL; const char *p; zbx_vector_ptr_t regexps; zbx_lld_row_t *lld_row; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != zbx_json_open(value, &jp)) { *error = zbx_strdup(*error, "Value should be a JSON object."); goto out; } /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^-------------------------------------------^ */ if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { *error = zbx_dsprintf(*error, "Cannot find the \"%s\" array in the received JSON object.", ZBX_PROTO_TAG_DATA); goto out; } zbx_vector_ptr_create(®exps); if (NULL != (f_regexp = strchr(filter, ':'))) { f_macro = filter; *f_regexp++ = '\0'; if ('@' == *f_regexp) DCget_expressions_by_name(®exps, f_regexp + 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() f_macro:'%s' f_regexp:'%s'", __function_name, f_macro, f_regexp); } p = NULL; /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^ */ while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^------------------^ */ if (FAIL == zbx_json_brackets_open(p, &jp_row)) continue; if (NULL != f_macro && SUCCEED != lld_check_record(&jp_row, f_macro, f_regexp, ®exps)) continue; lld_row = zbx_malloc(NULL, sizeof(zbx_lld_row_t)); memcpy(&lld_row->jp_row, &jp_row, sizeof(struct zbx_json_parse)); zbx_vector_ptr_create(&lld_row->item_links); zbx_vector_ptr_append(lld_rows, lld_row); } zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: send_list_of_active_checks_json * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * json - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], tmp[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX], error[MAX_STRING_LEN], *host_metadata = NULL; struct zbx_json json; int ret = FAIL, i; zbx_uint64_t hostid; size_t host_metadata_alloc = 1; /* for at least NUL-termination char */ unsigned short port; zbx_vector_uint64_t itemids; zbx_vector_ptr_t regexps; zbx_vector_str_t names; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(®exps); zbx_vector_str_create(&names); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror()); goto error; } host_metadata = zbx_malloc(host_metadata, host_metadata_alloc); if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_HOST_METADATA, &host_metadata, &host_metadata_alloc)) { *host_metadata = '\0'; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, sock->peer); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp))) *tmp = '\0'; if (FAIL == is_ushort(tmp, &port)) port = ZBX_DEFAULT_AGENT_PORT; if (FAIL == get_hostid_by_host(sock, host, ip, port, host_metadata, &hostid, error)) goto error; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, now; zbx_config_t cfg; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == cfg.refresh_unsupported) continue; if (dc_items[i].lastclock + cfg.refresh_unsupported > now) continue; } dc_items[i].key = zbx_strdup(dc_items[i].key, dc_items[i].key_orig); substitute_key_macros(&dc_items[i].key, NULL, &dc_items[i], NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig)) { zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, dc_items[i].key_orig, ZBX_JSON_TYPE_STRING); } zbx_json_adduint64(&json, ZBX_PROTO_TAG_DELAY, dc_items[i].delay); /* The agent expects ALWAYS to have lastlogsize and mtime tags. */ /* Removing those would cause older agents to fail. */ zbx_json_adduint64(&json, ZBX_PROTO_TAG_LASTLOGSIZE, dc_items[i].lastlogsize); zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime); zbx_json_close(&json); zbx_itemkey_extract_global_regexps(dc_items[i].key, &names); zbx_free(dc_items[i].key); } zbx_config_clean(&cfg); DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_json_close(&json); DCget_expressions_by_names(®exps, (const char * const *)names.values, names.values_num); if (0 < regexps.values_num) { char buffer[32]; zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); for (i = 0; i < regexps.values_num; i++) { zbx_expression_t *regexp = regexps.values[i]; zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", regexp->name, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", regexp->expression, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->expression_type); zbx_json_addstring(&json, "expression_type", buffer, ZBX_JSON_TYPE_INT); zbx_snprintf(buffer, sizeof(buffer), "%c", regexp->exp_delimiter); zbx_json_addstring(&json, "exp_delimiter", buffer, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->case_sensitive); zbx_json_addstring(&json, "case_sensitive", buffer, ZBX_JSON_TYPE_INT); zbx_json_close(&json); } zbx_json_close(&json); } zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_socket_strerror()); else ret = SUCCEED; zbx_alarm_off(); zbx_json_free(&json); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); ret = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: for (i = 0; i < names.values_num; i++) zbx_free(names.values[i]); zbx_vector_str_destroy(&names); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); zbx_free(host_metadata); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: parse_list_of_checks * * * * Purpose: Parse list of active checks received from server * * * * Parameters: str - NULL terminated string received from server * * host - address of host * * port - port number on host * * * * Return value: returns SUCCEED on successful parsing, * * FAIL on an incorrect format of string * * * * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol) * * * * Comments: * * String represented as "ZBX_EOF" termination list * * With '\n' delimiter between elements. * * Each element represented as: * * <key>:<refresh time>:<last log size>:<modification time> * * * ******************************************************************************/ static int parse_list_of_checks(char *str, const char *host, unsigned short port) { const char *p; char name[MAX_STRING_LEN], key_orig[MAX_STRING_LEN], expression[MAX_STRING_LEN], tmp[MAX_STRING_LEN], exp_delimiter; int delay, mtime, expression_type, case_sensitive; zbx_uint64_t lastlogsize; struct zbx_json_parse jp; struct zbx_json_parse jp_data, jp_row; zabbix_log(LOG_LEVEL_DEBUG, "In parse_list_of_checks()"); disable_all_metrics(); if (SUCCEED != zbx_json_open(str, &jp)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_RESPONSE, tmp, sizeof(tmp))) goto json_error; if (0 != strcmp(tmp, ZBX_PROTO_VALUE_SUCCESS)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_INFO, tmp, sizeof(tmp))) zabbix_log(LOG_LEVEL_WARNING, "no active checks on server [%s:%hu]: %s", host, port, tmp); else zabbix_log(LOG_LEVEL_WARNING, "no active checks on server"); return FAIL; } if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) goto json_error; p = NULL; while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------^ */ if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, name, sizeof(name)) || '\0' == *name) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_KEY); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY_ORIG, key_orig, sizeof(key_orig)) || '\0' == *key_orig) { zbx_strlcpy(key_orig, name, sizeof(key_orig)); } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_DELAY, tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_DELAY); continue; } delay = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp)) || SUCCEED != is_uint64(tmp, &lastlogsize)) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_LOGLASTSIZE); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_MTIME, tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", ZBX_PROTO_TAG_MTIME); mtime = 0; } else mtime = atoi(tmp); add_check(name, key_orig, delay, lastlogsize, mtime); } zbx_regexp_clean_expressions(®exps); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_REGEXP, &jp_data)) { p = NULL; while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"regexp":[{"name":"regexp1",...,...},{...},...]} * ^------------------------^ */ if (SUCCEED != zbx_json_brackets_open(p, &jp_row)) goto json_error; if (SUCCEED != zbx_json_value_by_name(&jp_row, "name", name, sizeof(name))) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "name"); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression", expression, sizeof(expression)) || '\0' == *expression) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "expression"); continue; } if (SUCCEED != zbx_json_value_by_name(&jp_row, "expression_type", tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "expression_type"); continue; } expression_type = atoi(tmp); if (SUCCEED != zbx_json_value_by_name(&jp_row, "exp_delimiter", tmp, sizeof(tmp))) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "exp_delimiter"); continue; } exp_delimiter = tmp[0]; if (SUCCEED != zbx_json_value_by_name(&jp_row, "case_sensitive", tmp, sizeof(tmp)) || '\0' == *tmp) { zabbix_log(LOG_LEVEL_WARNING, "cannot retrieve value of tag \"%s\"", "case_sensitive"); continue; } case_sensitive = atoi(tmp); add_regexp_ex(®exps, name, expression, expression_type, exp_delimiter, case_sensitive); } } return SUCCEED; json_error: zabbix_log(LOG_LEVEL_ERR, "cannot parse list of active checks: %s", zbx_json_strerror()); return FAIL; }