/****************************************************************************** * * * Function: host_availability_sender * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void host_availability_sender(struct zbx_json *j) { const char *__function_name = "host_availability_sender"; zbx_sock_t sock; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_json_clean(j); zbx_json_addstring(j, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_HOST_AVAILABILITY, ZBX_JSON_TYPE_STRING); zbx_json_addstring(j, ZBX_PROTO_TAG_HOST, CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING); if (SUCCEED == get_host_availability_data(j)) { char *error = NULL; connect_to_server(&sock, 600, CONFIG_PROXYDATA_FREQUENCY); /* retry till have a connection */ if (SUCCEED != put_data_to_server(&sock, j, &error)) zabbix_log(LOG_LEVEL_WARNING, "sending host availability data to server failed: %s", error); zbx_free(error); disconnect_server(&sock); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: history_sender * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void history_sender(struct zbx_json *j, int *records, const char *tag, int (*f_get_data)(), void (*f_set_lastid)()) { const char *__function_name = "history_sender"; zbx_sock_t sock; zbx_uint64_t lastid; zbx_timespec_t ts; int ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_json_clean(j); zbx_json_addstring(j, ZBX_PROTO_TAG_REQUEST, tag, ZBX_JSON_TYPE_STRING); zbx_json_addstring(j, ZBX_PROTO_TAG_HOST, CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING); zbx_json_addarray(j, ZBX_PROTO_TAG_DATA); *records = f_get_data(j, &lastid); zbx_json_close(j); if (*records > 0) { char *error = NULL; connect_to_server(&sock, 600, CONFIG_PROXYDATA_FREQUENCY); /* retry till have a connection */ zbx_timespec(&ts); zbx_json_adduint64(j, ZBX_PROTO_TAG_CLOCK, ts.sec); zbx_json_adduint64(j, ZBX_PROTO_TAG_NS, ts.ns); if (SUCCEED != (ret = put_data_to_server(&sock, j, &error))) { *records = 0; zabbix_log(LOG_LEVEL_WARNING, "sending data to server failed: %s", error); } zbx_free(error); disconnect_server(&sock); } if (SUCCEED == ret && 0 != lastid) { DBbegin(); f_set_lastid(lastid); DBcommit(); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
int main(int argc, char **argv) { FILE *in; char in_line[MAX_BUFFER_LEN], hostname[MAX_STRING_LEN], key[MAX_STRING_LEN], key_value[MAX_BUFFER_LEN], clock[32]; int total_count = 0, succeed_count = 0, buffer_count = 0, read_more = 0, ret = SUCCEED; double last_send = 0; const char *p; zbx_thread_args_t thread_args; ZBX_THREAD_SENDVAL_ARGS sentdval_args; progname = get_program_name(argv[0]); parse_commandline(argc, argv); zbx_load_config(CONFIG_FILE); zabbix_open_log(LOG_TYPE_UNDEFINED, CONFIG_LOG_LEVEL, NULL); if (NULL == ZABBIX_SERVER) { zabbix_log(LOG_LEVEL_WARNING, "'Server' parameter required"); goto exit; } if (0 == ZABBIX_SERVER_PORT) ZABBIX_SERVER_PORT = ZBX_DEFAULT_SERVER_PORT; if (MIN_ZABBIX_PORT > ZABBIX_SERVER_PORT) { zabbix_log(LOG_LEVEL_WARNING, "Incorrect port number [%d]. Allowed [%d:%d]", (int)ZABBIX_SERVER_PORT, (int)MIN_ZABBIX_PORT, (int)MAX_ZABBIX_PORT); goto exit; } thread_args.thread_num = 0; thread_args.args = &sentdval_args; sentdval_args.server = ZABBIX_SERVER; sentdval_args.port = ZABBIX_SERVER_PORT; zbx_json_init(&sentdval_args.json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_SENDER_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&sentdval_args.json, ZBX_PROTO_TAG_DATA); if (INPUT_FILE) { if (0 == strcmp(INPUT_FILE, "-")) { in = stdin; if (1 == REAL_TIME) { /* set line buffering on stdin */ setvbuf(stdin, (char *)NULL, _IOLBF, 0); } } else if (NULL == (in = fopen(INPUT_FILE, "r")) ) { zabbix_log(LOG_LEVEL_WARNING, "cannot open [%s]: %s", INPUT_FILE, zbx_strerror(errno)); ret = FAIL; goto exit; } while (NULL != fgets(in_line, sizeof(in_line), in) && SUCCEED == ret) /* <hostname> <key> [<timestamp>] <value> */ { total_count++; /* also used as inputline */ zbx_rtrim(in_line, "\r\n"); p = in_line; if ('\0' == *p || NULL == (p = get_string(p, hostname, sizeof(hostname))) || '\0' == *hostname) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Hostname' required", total_count); continue; } if (0 == strcmp(hostname, "-")) { if (NULL == ZABBIX_HOSTNAME) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] '-' encountered as 'Hostname', " "but no default hostname was specified", total_count); continue; } else zbx_strlcpy(hostname, ZABBIX_HOSTNAME, sizeof(hostname)); } if ('\0' == *p || NULL == (p = get_string(p, key, sizeof(key))) || '\0' == *key) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Key' required", total_count); continue; } if (1 == WITH_TIMESTAMPS) { if ('\0' == *p || NULL == (p = get_string(p, clock, sizeof(clock))) || '\0' == *clock) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Timestamp' required", total_count); continue; } } if ('\0' != *p && '"' != *p) zbx_strlcpy(key_value, p, sizeof(key_value)); else if ('\0' == *p || NULL == (p = get_string(p, key_value, sizeof(key_value))) || '\0' == *key_value) { zabbix_log(LOG_LEVEL_WARNING, "[line %d] 'Key value' required", total_count); continue; } zbx_rtrim(key_value, "\r\n"); zbx_json_addobject(&sentdval_args.json, NULL); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_HOST, hostname, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_VALUE, key_value, ZBX_JSON_TYPE_STRING); if (1 == WITH_TIMESTAMPS) zbx_json_adduint64(&sentdval_args.json, ZBX_PROTO_TAG_CLOCK, atoi(clock)); zbx_json_close(&sentdval_args.json); succeed_count++; buffer_count++; if (stdin == in && 1 == REAL_TIME) { /* if there is nothing on standard input after 1/5 seconds, we send what we have */ /* otherwise, we keep reading, but we should send data at least once per second */ struct timeval tv; fd_set read_set; tv.tv_sec = 0; tv.tv_usec = 200000; FD_ZERO(&read_set); FD_SET(0, &read_set); /* stdin is file descriptor 0 */ if (-1 == (read_more = select(1, &read_set, NULL, NULL, &tv))) { zabbix_log(LOG_LEVEL_WARNING, "select() failed: %s", zbx_strerror(errno)); } else if (1 <= read_more) { if (0 == last_send) last_send = zbx_time(); else if (zbx_time() - last_send >= 1) read_more = 0; } } if (VALUES_MAX == buffer_count || (stdin == in && 1 == REAL_TIME && 0 >= read_more)) { zbx_json_close(&sentdval_args.json); if (1 == WITH_TIMESTAMPS) zbx_json_adduint64(&sentdval_args.json, ZBX_PROTO_TAG_CLOCK, (int)time(NULL)); last_send = zbx_time(); ret = zbx_thread_wait(zbx_thread_start(send_value, &thread_args)); buffer_count = 0; zbx_json_clean(&sentdval_args.json); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_SENDER_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&sentdval_args.json, ZBX_PROTO_TAG_DATA); } } zbx_json_close(&sentdval_args.json); if (0 != buffer_count) { if (1 == WITH_TIMESTAMPS) zbx_json_adduint64(&sentdval_args.json, ZBX_PROTO_TAG_CLOCK, (int)time(NULL)); ret = zbx_thread_wait(zbx_thread_start(send_value, &thread_args)); } if (in != stdin) fclose(in); } else { total_count++; do /* try block simulation */ { if (NULL == ZABBIX_HOSTNAME) { zabbix_log(LOG_LEVEL_WARNING, "'Hostname' parameter required"); break; } if (NULL == ZABBIX_KEY) { zabbix_log(LOG_LEVEL_WARNING, "Key required"); break; } if (NULL == ZABBIX_KEY_VALUE) { zabbix_log(LOG_LEVEL_WARNING, "Key value required"); break; } zbx_json_addobject(&sentdval_args.json, NULL); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_HOST, ZABBIX_HOSTNAME, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_KEY, ZABBIX_KEY, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&sentdval_args.json, ZBX_PROTO_TAG_VALUE, ZABBIX_KEY_VALUE, ZBX_JSON_TYPE_STRING); zbx_json_close(&sentdval_args.json); succeed_count++; ret = zbx_thread_wait(zbx_thread_start(send_value, &thread_args)); } while(0); /* try block simulation */ } zbx_json_free(&sentdval_args.json); if (SUCCEED == ret) printf("sent: %d; skipped: %d; total: %d\n", succeed_count, (total_count - succeed_count), total_count); else printf("Sending failed. Use option -vv for more detailed output.\n"); exit: zabbix_close_log(); return ret; }
/****************************************************************************** * * * Function: process_proxy * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_proxy(void) { const char *__function_name = "process_proxy"; DC_PROXY proxy; int num, i, ret; struct zbx_json j; struct zbx_json_parse jp, jp_data; zbx_socket_t s; char *answer = NULL, *port = NULL; time_t now; unsigned char update_nextcheck; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (0 == (num = DCconfig_get_proxypoller_hosts(&proxy, 1))) goto exit; now = time(NULL); zbx_json_init(&j, 512 * 1024); for (i = 0; i < num; i++) { update_nextcheck = 0; if (proxy.proxy_config_nextcheck <= now) update_nextcheck |= 0x01; if (proxy.proxy_data_nextcheck <= now) update_nextcheck |= 0x02; proxy.addr = proxy.addr_orig; port = zbx_strdup(port, proxy.port_orig); substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &port, MACRO_TYPE_COMMON, NULL, 0); if (FAIL == is_ushort(port, &proxy.port)) { zabbix_log(LOG_LEVEL_ERR, "invalid proxy \"%s\" port: \"%s\"", proxy.host, port); goto network_error; } if (proxy.proxy_config_nextcheck <= now) { char *error = NULL; zbx_json_clean(&j); zbx_json_addstring(&j, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_PROXY_CONFIG, ZBX_JSON_TYPE_STRING); zbx_json_addobject(&j, ZBX_PROTO_TAG_DATA); if (SUCCEED != (ret = get_proxyconfig_data(proxy.hostid, &j, &error))) { zabbix_log(LOG_LEVEL_ERR, "cannot collect configuration data for proxy \"%s\": %s", proxy.host, error); zbx_free(error); goto network_error; } if (SUCCEED == (ret = connect_to_proxy(&proxy, &s, CONFIG_TRAPPER_TIMEOUT))) { zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\" at \"%s\"," " datalen " ZBX_FS_SIZE_T, proxy.host, get_ip_by_socket(&s), (zbx_fs_size_t)j.buffer_size); if (SUCCEED == (ret = send_data_to_proxy(&proxy, &s, j.buffer))) { char *error = NULL; if (SUCCEED != (ret = zbx_recv_response(&s, 0, &error))) { zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration data to proxy" " \"%s\" at \"%s\": %s", proxy.host, get_ip_by_socket(&s), error); } zbx_free(error); } disconnect_proxy(&s); } if (SUCCEED != ret) goto network_error; } if (proxy.proxy_data_nextcheck <= now) { if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_HOST_AVAILABILITY, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) process_host_availability(&jp); zbx_free(answer); } else goto network_error; retry_history: if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_HISTORY_DATA, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) { process_hist_data(NULL, &jp, proxy.hostid, NULL, 0); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data)) { zbx_free(answer); goto retry_history; } } } zbx_free(answer); } else goto network_error; retry_dhistory: if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_DISCOVERY_DATA, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) { process_dhis_data(&jp); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data)) { zbx_free(answer); goto retry_dhistory; } } } zbx_free(answer); } else goto network_error; retry_autoreg_host: if (SUCCEED == get_data_from_proxy(&proxy, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA, &answer)) { if (SUCCEED == zbx_json_open(answer, &jp)) { process_areg_data(&jp, proxy.hostid); if (SUCCEED == zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { if (ZBX_MAX_HRECORDS <= zbx_json_count(&jp_data)) { zbx_free(answer); goto retry_autoreg_host; } } } zbx_free(answer); } else goto network_error; } DBbegin(); update_proxy_lastaccess(proxy.hostid); DBcommit(); network_error: DCrequeue_proxy(proxy.hostid, update_nextcheck); } zbx_free(port); zbx_json_free(&j); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return num; }