/****************************************************************************** * * * Function: send_proxyconfig * * * * Purpose: send configuration tables to the proxy * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_proxyconfig(zbx_sock_t *sock, struct zbx_json_parse *jp) { zbx_uint64_t proxy_hostid; struct zbx_json j; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In send_proxyconfig()"); if (FAIL == get_proxy_id(jp, &proxy_hostid)) goto exit; update_proxy_lastaccess(proxy_hostid); zbx_json_init(&j, 512*1024); if (SUCCEED == (res = get_proxyconfig_data(proxy_hostid, &j))) { zabbix_log(LOG_LEVEL_WARNING, "Sending configuration data to proxy. Datalen %d", (int)j.buffer_size); zabbix_log(LOG_LEVEL_DEBUG, "%s", j.buffer); if (FAIL == (res = zbx_tcp_send(sock, j.buffer))) zabbix_log(LOG_LEVEL_WARNING, "Error while sending configuration. %s", zbx_tcp_strerror()); } zbx_json_free(&j); exit: return res; }
static void process_listener(zbx_sock_t *s) { AGENT_RESULT result; char *command; char **value = NULL; int ret; if( SUCCEED == (ret = zbx_tcp_recv(s, &command)) ) { zbx_rtrim(command, "\r\n\0"); zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", command); init_result(&result); process(command, 0, &result); if( NULL == (value = GET_TEXT_RESULT(&result)) ) value = GET_MSG_RESULT(&result); if(value) { zabbix_log(LOG_LEVEL_DEBUG, "Sending back [%s]", *value); ret = zbx_tcp_send(s, *value); } free_result(&result); } if( FAIL == ret ) { zabbix_log(LOG_LEVEL_DEBUG, "Process listener error: %s", zbx_tcp_strerror()); } }
/****************************************************************************** * * * Function: send_to_node * * * * Purpose: send configuration changes to required node * * * * Parameters: * * * * Return value: SUCCESS - processed succesfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int send_to_node(char *name, int dest_nodeid, int nodeid, char *data) { char ip[MAX_STRING_LEN]; int port; int ret = FAIL; DB_RESULT result; DB_ROW row; zbx_sock_t sock; char *answer; zabbix_log( LOG_LEVEL_WARNING, "NODE: Sending %s to node %s:%d datalen %d", name, CONFIG_MASTER_IP, CONFIG_MASTER_PORT, strlen(data)); /* zabbix_log( LOG_LEVEL_WARNING, "Data [%s]", data);*/ if( FAIL == zbx_tcp_connect(&sock, CONFIG_MASTER_IP, CONFIG_MASTER_PORT, 0, NULL)) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to connect to Node [%s:%d] error: %s", CONFIG_MASTER_IP, CONFIG_MASTER_PORT, zbx_tcp_strerror()); return FAIL; } if( FAIL == zbx_tcp_send(&sock, data)) { zabbix_log( LOG_LEVEL_WARNING, "Error while sending data to Node [%s:%d]", CONFIG_MASTER_IP, CONFIG_MASTER_PORT); zbx_tcp_close(&sock); return FAIL; } if( FAIL == zbx_tcp_recv(&sock, &answer)) { zabbix_log( LOG_LEVEL_WARNING, "Error while receiving answer from Node [%s:%d]", CONFIG_MASTER_IP, CONFIG_MASTER_PORT); zbx_tcp_close(&sock); return FAIL; } zabbix_log( LOG_LEVEL_DEBUG, "Answer [%s]", answer); if(strcmp(answer,"OK") == 0) { zabbix_log( LOG_LEVEL_DEBUG, "OK"); ret = SUCCEED; } else { zabbix_log( LOG_LEVEL_WARNING, "NOT OK"); } zbx_tcp_close(&sock); return ret; }
static int send_data_to_server(zbx_sock_t *sock, const char *data) { int res; zabbix_log(LOG_LEVEL_DEBUG, "In send_data_to_server() [%s]", data); if (FAIL == (res = zbx_tcp_send(sock, data))) zabbix_log(LOG_LEVEL_ERR, "Error while sending data to the server [%s]", zbx_tcp_strerror()); return res; }
/****************************************************************************** * * * Function: send_script * * * * Purpose: sending command to slave node * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * ******************************************************************************/ static int send_script(int nodeid, const char *data, char **result) { DB_RESULT db_result; DB_ROW db_row; int ret = FAIL; zbx_sock_t sock; char *answer; zabbix_log(LOG_LEVEL_DEBUG, "In send_script(nodeid:%d)", nodeid); db_result = DBselect( "select ip,port" " from nodes" " where nodeid=%d", nodeid); if (NULL != (db_row = DBfetch(db_result))) { if (SUCCEED == (ret = zbx_tcp_connect(&sock, CONFIG_SOURCE_IP, db_row[0], atoi(db_row[1]), CONFIG_TRAPPER_TIMEOUT))) { if (FAIL == (ret = zbx_tcp_send(&sock, data))) { *result = zbx_dsprintf(*result, "NODE %d: Error while sending data to Node [%d]: %s.", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); goto exit_sock; } if (SUCCEED == (ret = zbx_tcp_recv(&sock, &answer))) *result = zbx_dsprintf(*result, "%s", answer); else *result = zbx_dsprintf(*result, "NODE %d: Error while receiving data from Node [%d]: %s.", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); exit_sock: zbx_tcp_close(&sock); } else *result = zbx_dsprintf(*result, "NODE %d: Unable to connect to Node [%d]: %s.", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); } else *result = zbx_dsprintf(*result, "NODE %d: Unknown Node ID [%d].", CONFIG_NODEID, nodeid); DBfree_result(db_result); return ret; }
int send_data_to_node(int nodeid, zbx_sock_t *sock, const char *data) { int res; if (FAIL == (res = zbx_tcp_send(sock, data))) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Error while sending data to Node [%d] error: %s", CONFIG_NODEID, nodeid, zbx_tcp_strerror()); } else zabbix_log(LOG_LEVEL_DEBUG, "NODE %d: Sending [%s] to Node [%d]", CONFIG_NODEID, data, nodeid); return res; }
/****************************************************************************** * * * Function: send_proxyconfig * * * * Purpose: send configuration tables to the proxy from server * * (for active proxies) * * * * Author: Alexander Vladishev * * * ******************************************************************************/ void send_proxyconfig(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_proxyconfig"; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], *error = NULL; struct zbx_json j; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != get_active_proxy_id(jp, &proxy_hostid, host, &error)) { zbx_send_response(sock, FAIL, error, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_WARNING, "proxy configuration request from active proxy on \"%s\" failed: %s", get_ip_by_socket(sock), error); goto out; } update_proxy_lastaccess(proxy_hostid); zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); if (SUCCEED != get_proxyconfig_data(proxy_hostid, &j, &error)) { zbx_send_response(sock, FAIL, error, CONFIG_TIMEOUT); zabbix_log(LOG_LEVEL_WARNING, "cannot collect proxy configuration: %s", error); goto clean; } zabbix_log(LOG_LEVEL_WARNING, "sending configuration data to proxy \"%s\", datalen " ZBX_FS_SIZE_T, host, (zbx_fs_size_t)j.buffer_size); zabbix_log(LOG_LEVEL_DEBUG, "%s", j.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, j.buffer)) zabbix_log(LOG_LEVEL_WARNING, "cannot send configuration: %s", zbx_tcp_strerror()); alarm(0); clean: zbx_json_free(&j); out: zbx_free(error); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: send_result * * * * Purpose: send json SUCCEED or FAIL to socket along with an info message * * * * Parameters: result SUCCEED or FAIL * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int send_result(zbx_sock_t *sock, int result, char *info) { int ret = SUCCEED; struct zbx_json json; zbx_json_init(&json, 1024); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, SUCCEED == result ? ZBX_PROTO_VALUE_SUCCESS : ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); if(info != NULL && info[0]!='\0') { zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, info, ZBX_JSON_TYPE_STRING); } ret = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); return ret; }
static int send_data_to_proxy(DC_PROXY *proxy, zbx_socket_t *sock, const char *data) { const char *__function_name = "send_data_to_proxy"; int ret; zabbix_log(LOG_LEVEL_DEBUG, "In %s() data:'%s'", __function_name, data); if (FAIL == (ret = zbx_tcp_send(sock, data))) { zabbix_log(LOG_LEVEL_ERR, "cannot send data to proxy \"%s\": %s", proxy->host, zbx_socket_strerror()); ret = NETWORK_ERROR; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static ZBX_THREAD_ENTRY(send_value, args) { ZBX_THREAD_SENDVAL_ARGS *sentdval_args; zbx_sock_t sock; char *answer = NULL; int tcp_ret, ret = FAIL; assert(args); assert(((zbx_thread_args_t *)args)->args); sentdval_args = (ZBX_THREAD_SENDVAL_ARGS *)((zbx_thread_args_t *)args)->args; #if !defined(_WINDOWS) signal(SIGINT, send_signal_handler); signal(SIGTERM, send_signal_handler); signal(SIGQUIT, send_signal_handler); signal(SIGALRM, send_signal_handler); #endif if (SUCCEED == (tcp_ret = zbx_tcp_connect(&sock, CONFIG_SOURCE_IP, sentdval_args->server, sentdval_args->port, GET_SENDER_TIMEOUT))) { if (SUCCEED == (tcp_ret = zbx_tcp_send(&sock, sentdval_args->json.buffer))) { if (SUCCEED == (tcp_ret = zbx_tcp_recv(&sock, &answer))) { zabbix_log(LOG_LEVEL_DEBUG, "answer [%s]", answer); if (NULL == answer || SUCCEED != check_response(answer)) zabbix_log(LOG_LEVEL_WARNING, "incorrect answer from server [%s]", answer); else ret = SUCCEED; } } zbx_tcp_close(&sock); } if (FAIL == tcp_ret) zabbix_log(LOG_LEVEL_DEBUG, "send value error: %s", zbx_tcp_strerror()); zbx_thread_exit(ret); }
/****************************************************************************** * * * Function: send_proxyconfig * * * * Purpose: send configuration tables to the proxy from server * * (for active proxies) * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void send_proxyconfig(zbx_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_proxyconfig"; zbx_uint64_t proxy_hostid; char host[HOST_HOST_LEN_MAX], error[256]; struct zbx_json j; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == get_proxy_id(jp, &proxy_hostid, host, error, sizeof(error))) { zabbix_log(LOG_LEVEL_WARNING, "Proxy config request from active proxy on [%s] failed: %s", get_ip_by_socket(sock), error); return; } update_proxy_lastaccess(proxy_hostid); zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); get_proxyconfig_data(proxy_hostid, &j); zabbix_log(LOG_LEVEL_WARNING, "Sending configuration data to proxy '%s'. Datalen " ZBX_FS_SIZE_T, host, (zbx_fs_size_t)j.buffer_size); zabbix_log(LOG_LEVEL_DEBUG, "%s", j.buffer); alarm(CONFIG_TIMEOUT); if (FAIL == zbx_tcp_send(sock, j.buffer)) zabbix_log(LOG_LEVEL_WARNING, "Error while sending configuration. %s", zbx_tcp_strerror()); alarm(0); zbx_json_free(&j); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: refresh_active_checks * * * * Purpose: Retrive from ZABBIX server list of active checks * * * * Parameters: host - IP or Hostname of ZABBIX server * * port - port of ZABBIX server * * * * Return value: returns SUCCEED on succesfull parsing, * * FAIL on other cases * * * * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol) * * * * Comments: * * * ******************************************************************************/ static int refresh_active_checks(const char *host, unsigned short port) { zbx_sock_t s; char *buf; int ret; struct zbx_json json; zabbix_log( LOG_LEVEL_DEBUG, "refresh_active_checks('%s',%u)", host, port); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST, CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, CONFIG_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", json.buffer); if (SUCCEED == (ret = zbx_tcp_send(&s, json.buffer))) { zabbix_log(LOG_LEVEL_DEBUG, "Before read"); if (SUCCEED == (ret = zbx_tcp_recv_ext(&s, &buf, ZBX_TCP_READ_UNTIL_CLOSE))) { zabbix_log(LOG_LEVEL_DEBUG, "Got [%s]", buf); parse_list_of_checks(buf); } } zbx_tcp_close(&s); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "Get active checks error: %s", zbx_tcp_strerror()); zbx_json_free(&json); return ret; }
/****************************************************************************** * * * Function: send_buffer * * * * Purpose: Send value stored in the buffer to Zabbix server * * * * Parameters: host - IP or Hostname of Zabbix server * * port - port number * * * * Return value: returns SUCCEED on successful parsing, * * FAIL on other cases * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int send_buffer(const char *host, unsigned short port) { const char *__function_name = "send_buffer"; struct zbx_json json; ZBX_ACTIVE_BUFFER_ELEMENT *el; zbx_sock_t s; char *buf = NULL; int ret = SUCCEED, i, now; zbx_timespec_t ts; const char *err_send_step = ""; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' port:%d values:%d/%d", __function_name, host, port, buffer.count, CONFIG_BUFFER_SIZE); if (0 == buffer.count) goto ret; now = (int)time(NULL); if (CONFIG_BUFFER_SIZE / 2 > buffer.pcount && CONFIG_BUFFER_SIZE > buffer.count && CONFIG_BUFFER_SEND > now - buffer.lastsent) { zabbix_log(LOG_LEVEL_DEBUG, "Will not send now. Now %d lastsent %d < %d", now, buffer.lastsent, CONFIG_BUFFER_SEND); goto ret; } zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_AGENT_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for (i = 0; i < buffer.count; i++) { el = &buffer.data[i]; zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST, el->host, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, el->key, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_VALUE, el->value, ZBX_JSON_TYPE_STRING); if (0 != el->lastlogsize) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGLASTSIZE, el->lastlogsize); if (el->mtime) zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, el->mtime); if (el->timestamp) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGTIMESTAMP, el->timestamp); if (el->source) zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGSOURCE, el->source, ZBX_JSON_TYPE_STRING); if (el->severity) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGSEVERITY, el->severity); if (el->logeventid) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGEVENTID, el->logeventid); zbx_json_adduint64(&json, ZBX_PROTO_TAG_CLOCK, el->ts.sec); zbx_json_adduint64(&json, ZBX_PROTO_TAG_NS, el->ts.ns); zbx_json_close(&json); } zbx_json_close(&json); zbx_timespec(&ts); zbx_json_adduint64(&json, ZBX_PROTO_TAG_CLOCK, ts.sec); zbx_json_adduint64(&json, ZBX_PROTO_TAG_NS, ts.ns); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, MIN(buffer.count * CONFIG_TIMEOUT, 60)))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON before sending [%s]", json.buffer); if (SUCCEED == (ret = zbx_tcp_send(&s, json.buffer))) { if (SUCCEED == zbx_tcp_recv(&s, &buf)) { zabbix_log(LOG_LEVEL_DEBUG, "JSON back [%s]", buf); if (NULL == buf || SUCCEED != check_response(buf)) zabbix_log(LOG_LEVEL_DEBUG, "NOT OK"); else zabbix_log(LOG_LEVEL_DEBUG, "OK"); } else err_send_step = "[recv] "; } else err_send_step = "[send] "; zbx_tcp_close(&s); } else err_send_step = "[connect] "; zbx_json_free(&json); if (SUCCEED == ret) { /* free buffer */ for (i = 0; i < buffer.count; i++) { el = &buffer.data[i]; zbx_free(el->host); zbx_free(el->key); zbx_free(el->value); zbx_free(el->source); } buffer.count = 0; buffer.pcount = 0; buffer.lastsent = now; if (0 != buffer.first_error) { zabbix_log(LOG_LEVEL_WARNING, "active check data upload to [%s:%hu] is working again", host, port); buffer.first_error = 0; } } else { if (0 == buffer.first_error) { zabbix_log(LOG_LEVEL_WARNING, "active check data upload to [%s:%hu] started to fail (%s%s)", host, port, err_send_step, zbx_tcp_strerror()); buffer.first_error = now; } zabbix_log(LOG_LEVEL_DEBUG, "send value error: %s %s", err_send_step, zbx_tcp_strerror()); } ret: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: get_value * * * * Purpose: connect to Zabbix agent, receive and print value * * * * Parameters: host - server name or IP address * * port - port number * * key - item's key * * * ******************************************************************************/ static int get_value(const char *source_ip, const char *host, unsigned short port, const char *key) { zbx_socket_t s; int ret; ssize_t bytes_received = -1; char *tls_arg1, *tls_arg2; switch (configured_tls_connect_mode) { case ZBX_TCP_SEC_UNENCRYPTED: tls_arg1 = NULL; tls_arg2 = NULL; break; #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) case ZBX_TCP_SEC_TLS_CERT: tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER; tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT; break; case ZBX_TCP_SEC_TLS_PSK: tls_arg1 = CONFIG_TLS_PSK_IDENTITY; tls_arg2 = NULL; /* zbx_tls_connect() will find PSK */ break; #endif default: THIS_SHOULD_NEVER_HAPPEN; return FAIL; } if (SUCCEED == (ret = zbx_tcp_connect(&s, source_ip, host, port, GET_SENDER_TIMEOUT, configured_tls_connect_mode, tls_arg1, tls_arg2))) { if (SUCCEED == (ret = zbx_tcp_send(&s, key))) { if (0 < (bytes_received = zbx_tcp_recv_ext(&s, 0))) { if (0 == strcmp(s.buffer, ZBX_NOTSUPPORTED) && sizeof(ZBX_NOTSUPPORTED) < s.read_bytes) { zbx_rtrim(s.buffer + sizeof(ZBX_NOTSUPPORTED), "\r\n"); printf("%s: %s\n", s.buffer, s.buffer + sizeof(ZBX_NOTSUPPORTED)); } else { zbx_rtrim(s.buffer, "\r\n"); printf("%s\n", s.buffer); } } else { if (0 == bytes_received) zbx_error("Check access restrictions in Zabbix agent configuration"); ret = FAIL; } } zbx_tcp_close(&s); if (SUCCEED != ret && 0 != bytes_received) { zbx_error("Get value error: %s", zbx_socket_strerror()); zbx_error("Check access restrictions in Zabbix agent configuration"); } } else zbx_error("Get value error: %s", zbx_socket_strerror()); return ret; }
int main(int argc, char **argv) { char ch; int task = ZBX_TASK_START; char *TEST_METRIC = NULL; zbx_sock_t s_in; zbx_sock_t s_out; int ret; char **value, *command; AGENT_RESULT result; memset(&result, 0, sizeof(AGENT_RESULT)); progname = get_program_name(argv[0]); /* Parse the command-line. */ while ((ch = (char)zbx_getopt_long(argc, argv, "c:hVpt:", longopts, NULL)) != (char)EOF) switch (ch) { case 'c': CONFIG_FILE = strdup(zbx_optarg); break; case 'h': help(); exit(-1); break; case 'V': version(); #ifdef _AIX tl_version(); #endif /* _AIX */ exit(-1); break; case 'p': if (task == ZBX_TASK_START) task = ZBX_TASK_PRINT_SUPPORTED; break; case 't': if (task == ZBX_TASK_START) { task = ZBX_TASK_TEST_METRIC; TEST_METRIC = strdup(zbx_optarg); } break; default: task = ZBX_TASK_SHOW_USAGE; break; } if (CONFIG_FILE == NULL) CONFIG_FILE = DEFAULT_CONFIG_FILE; init_metrics(); if (ZBX_TASK_START == task) { load_config(); load_user_parameters(0); } /* Do not create debug files */ zabbix_open_log(LOG_TYPE_SYSLOG, LOG_LEVEL_EMPTY, NULL); switch (task) { case ZBX_TASK_PRINT_SUPPORTED: load_user_parameters(1); test_parameters(); exit(-1); break; case ZBX_TASK_TEST_METRIC: load_user_parameters(1); test_parameter(TEST_METRIC, PROCESS_TEST); exit(-1); break; case ZBX_TASK_SHOW_USAGE: usage(); exit(-1); break; } signal(SIGINT, child_signal_handler); signal(SIGTERM, child_signal_handler); signal(SIGQUIT, child_signal_handler); signal(SIGALRM, child_signal_handler); alarm(CONFIG_TIMEOUT); zbx_tcp_init(&s_in, (ZBX_SOCKET)fileno(stdin)); zbx_tcp_init(&s_out, (ZBX_SOCKET)fileno(stdout)); if( SUCCEED == (ret = zbx_tcp_check_security(&s_in, CONFIG_HOSTS_ALLOWED, 0)) ) { if( SUCCEED == (ret = zbx_tcp_recv(&s_in, &command)) ) { zbx_rtrim(command, "\r\n"); zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", command); init_result(&result); process(command, 0, &result); if( NULL == (value = GET_TEXT_RESULT(&result)) ) value = GET_MSG_RESULT(&result); if(value) { zabbix_log(LOG_LEVEL_DEBUG, "Sending back [%s]", *value); ret = zbx_tcp_send(&s_out, *value); } free_result(&result); } if( FAIL == ret ) { zabbix_log(LOG_LEVEL_DEBUG, "Processing error: %s", zbx_tcp_strerror()); } } fflush(stdout); free_metrics(); alias_list_free(); alarm(0); zabbix_close_log(); return SUCCEED; }
/****************************************************************************** * * * Function: refresh_active_checks * * * * Purpose: Retrieve from Zabbix server list of active checks * * * * Parameters: host - IP or Hostname of Zabbix server * * port - port of Zabbix server * * * * Return value: returns SUCCEED on successful parsing, * * FAIL on other cases * * * * Author: Eugene Grigorjev, Alexei Vladishev (new json protocol) * * * * Comments: * * * ******************************************************************************/ static int refresh_active_checks(const char *host, unsigned short port) { const char *__function_name = "refresh_active_checks"; zbx_sock_t s; char *buf; int ret; struct zbx_json json; static int last_ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' port:%hu", __function_name, host, port); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST, CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING); if (NULL != CONFIG_HOST_METADATA) { zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST_METADATA, CONFIG_HOST_METADATA, ZBX_JSON_TYPE_STRING); } else if (NULL != CONFIG_HOST_METADATA_ITEM) { char **value; AGENT_RESULT result; init_result(&result); if (SUCCEED == process(CONFIG_HOST_METADATA_ITEM, PROCESS_LOCAL_COMMAND, &result) && NULL != (value = GET_STR_RESULT(&result)) && NULL != *value) { if (SUCCEED != zbx_is_utf8(*value)) { zabbix_log(LOG_LEVEL_WARNING, "cannot get host metadata using \"%s\" item specified by" " \"HostMetadataItem\" configuration parameter: returned value is not" " an UTF-8 string", CONFIG_HOST_METADATA_ITEM); } else { if (HOST_METADATA_LEN < zbx_strlen_utf8(*value)) { size_t bytes; zabbix_log(LOG_LEVEL_WARNING, "the returned value of \"%s\" item specified by" " \"HostMetadataItem\" configuration parameter is too long," " using first %d characters", CONFIG_HOST_METADATA_ITEM, HOST_METADATA_LEN); bytes = zbx_strlen_utf8_n(*value, HOST_METADATA_LEN); (*value)[bytes] = '\0'; } zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST_METADATA, *value, ZBX_JSON_TYPE_STRING); } } else zabbix_log(LOG_LEVEL_WARNING, "cannot get host metadata using \"%s\" item specified by" " \"HostMetadataItem\" configuration parameter", CONFIG_HOST_METADATA_ITEM); free_result(&result); } if (NULL != CONFIG_LISTEN_IP) { char *p; if (NULL != (p = strchr(CONFIG_LISTEN_IP, ','))) *p = '\0'; zbx_json_addstring(&json, ZBX_PROTO_TAG_IP, CONFIG_LISTEN_IP, ZBX_JSON_TYPE_STRING); if (NULL != p) *p = ','; } if (ZBX_DEFAULT_AGENT_PORT != CONFIG_LISTEN_PORT) zbx_json_adduint64(&json, ZBX_PROTO_TAG_PORT, CONFIG_LISTEN_PORT); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, CONFIG_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "sending [%s]", json.buffer); if (SUCCEED == (ret = zbx_tcp_send(&s, json.buffer))) { zabbix_log(LOG_LEVEL_DEBUG, "before read"); if (SUCCEED == (ret = SUCCEED_OR_FAIL(zbx_tcp_recv_ext(&s, &buf, ZBX_TCP_READ_UNTIL_CLOSE, 0)))) { zabbix_log(LOG_LEVEL_DEBUG, "got [%s]", buf); if (SUCCEED != last_ret) { zabbix_log(LOG_LEVEL_WARNING, "active check configuration update from [%s:%hu]" " is working again", host, port); } parse_list_of_checks(buf, host, port); } } zbx_tcp_close(&s); } if (SUCCEED != ret && SUCCEED == last_ret) { zabbix_log(LOG_LEVEL_WARNING, "active check configuration update from [%s:%hu] started to fail (%s)", host, port, zbx_tcp_strerror()); } last_ret = ret; zbx_json_free(&json); 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_sock_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32], key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX]; DB_RESULT result; DB_ROW row; struct zbx_json json; int res = FAIL, refresh_unsupported, now; zbx_uint64_t hostid; char error[MAX_STRING_LEN], *key = NULL; DC_ITEM dc_item; unsigned short port; char **regexp = NULL; int regexp_alloc = 0; int regexp_num = 0, n; char *sql = NULL; size_t sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); 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; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, get_ip_by_socket(sock)); 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(host, ip, port, &hostid, error)) goto error; DCconfig_get_config_data(&refresh_unsupported, CONFIG_REFRESH_UNSUPPORTED); now = time(NULL); sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select i.key_,i.delay,i.lastlogsize,i.mtime" " from items i,hosts h" " where i.hostid=h.hostid" " and h.status=%d" " and i.type=%d" " and i.flags<>%d" " and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid is null", HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, ZBX_FLAG_DISCOVERY_CHILD, hostid); zbx_free(name_esc); 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); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[0])) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was not found in the server cache. Not sending now.", __function_name, row[0]); continue; } if (ITEM_STATUS_NOTSUPPORTED == dc_item.status) { if (0 == refresh_unsupported || dc_item.lastclock + refresh_unsupported > now) { DCconfig_clean_items(&dc_item, NULL, 1); continue; } } zabbix_log(LOG_LEVEL_DEBUG, "%s() Item '%s' was successfully found in the server cache. Sending.", __function_name, row[0]); ZBX_STRDUP(key, row[0]); substitute_key_macros(&key, NULL, &dc_item, NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); DCconfig_clean_items(&dc_item, NULL, 1); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(key, row[0])) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, row[1], ZBX_JSON_TYPE_INT); /* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */ zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, row[3], ZBX_JSON_TYPE_INT); zbx_json_close(&json); /* special processing for log[] and logrt[] items */ do { /* simple try realization */ /* log[filename,pattern,encoding,maxlinespersec] */ /* logrt[filename_format,pattern,encoding,maxlinespersec] */ if (0 != strncmp(key, "log[", 4) && 0 != strncmp(key, "logrt[", 6)) break; if (2 != parse_command(key, NULL, 0, params, sizeof(params))) break; /* dealing with `pattern' parameter */ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); } while (0); /* simple try realization */ /* special processing for eventlog[] items */ do { /* simple try realization */ /* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */ if (0 != strncmp(key, "eventlog[", 9)) break; if (2 != parse_command(key, NULL, 0, params, sizeof(params))) break; /* dealing with `pattern' parameter */ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); /* dealing with `severity' parameter */ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /* dealing with `logeventid' parameter */ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_logeventid + 1); } while (0); /* simple try realization */ zbx_free(key); } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e" " where r.regexpid=e.regexpid" " and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')'); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, DB_NODE, DBnode_local("r.regexpid")); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_json_free(&json); zbx_free(sql); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to [%s]: %s", get_ip_by_socket(sock), 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); res = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
void get_values_java(unsigned char request, DC_ITEM *items, AGENT_RESULT *results, int *errcodes, int num) { const char *__function_name = "get_values_java"; zbx_sock_t s; struct zbx_json json; char error[MAX_STRING_LEN]; char *buffer = NULL; int i, j, err = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s' addr:'%s' num:%d", __function_name, items[0].host.host, items[0].interface.addr, num); for (j = 0; j < num; j++) /* locate first supported item */ { if (SUCCEED == errcodes[j]) break; } if (j == num) /* all items already NOTSUPPORTED (with invalid key or port) */ goto out; zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); if (NULL == CONFIG_JAVA_GATEWAY || '\0' == *CONFIG_JAVA_GATEWAY) { err = GATEWAY_ERROR; strscpy(error, "JavaGateway configuration parameter not set or empty"); goto exit; } if (ZBX_JAVA_GATEWAY_REQUEST_INTERNAL == request) { zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_JAVA_GATEWAY_INTERNAL, ZBX_JSON_TYPE_STRING); } else if (ZBX_JAVA_GATEWAY_REQUEST_JMX == request) { for (i = j + 1; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (0 != strcmp(items[j].interface.addr, items[i].interface.addr) || items[j].interface.port != items[i].interface.port || 0 != strcmp(items[j].username, items[i].username) || 0 != strcmp(items[j].password, items[i].password)) { err = GATEWAY_ERROR; strscpy(error, "Java poller received items with different connection parameters"); goto exit; } } zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_JAVA_GATEWAY_JMX, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_CONN, items[j].interface.addr, ZBX_JSON_TYPE_STRING); zbx_json_adduint64(&json, ZBX_PROTO_TAG_PORT, items[j].interface.port); if ('\0' != *items[j].username) zbx_json_addstring(&json, ZBX_PROTO_TAG_USERNAME, items[j].username, ZBX_JSON_TYPE_STRING); if ('\0' != *items[j].password) zbx_json_addstring(&json, ZBX_PROTO_TAG_PASSWORD, items[j].password, ZBX_JSON_TYPE_STRING); } else assert(0); zbx_json_addarray(&json, ZBX_PROTO_TAG_KEYS); for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; zbx_json_addstring(&json, NULL, items[i].key, ZBX_JSON_TYPE_STRING); } zbx_json_close(&json); if (SUCCEED == (err = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, CONFIG_JAVA_GATEWAY, CONFIG_JAVA_GATEWAY_PORT, CONFIG_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON before sending [%s]", json.buffer); if (SUCCEED == (err = zbx_tcp_send(&s, json.buffer))) { if (SUCCEED == (err = zbx_tcp_recv(&s, &buffer))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON back [%s]", buffer); err = parse_response(items, results, errcodes, num, buffer, error, sizeof(error)); } } zbx_tcp_close(&s); } zbx_json_free(&json); if (FAIL == err) { strscpy(error, zbx_tcp_strerror()); err = GATEWAY_ERROR; } exit: if (NETWORK_ERROR == err || GATEWAY_ERROR == err) { zabbix_log(LOG_LEVEL_DEBUG, "Getting Java values failed: %s", error); for (i = 0; i < num; i++) { if (SUCCEED != errcodes[i]) continue; if (!ISSET_MSG(&results[i])) { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error)); errcodes[i] = err; } } } out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: send_buffer * * * * Purpose: Send value stgored in the buffer to ZABBIX server * * * * Parameters: host - IP or Hostname of ZABBIX server * * port - port number * * * * Return value: returns SUCCEED on succesfull parsing, * * FAIL on other cases * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int send_buffer( const char *host, unsigned short port ) { zbx_sock_t s; char *buf = NULL; int ret = SUCCEED; struct zbx_json json; int i; static int lastsent = 0; int now; zabbix_log( LOG_LEVEL_DEBUG, "In send_buffer('%s','%d')", host, port); zabbix_log( LOG_LEVEL_DEBUG, "Values in the buffer %d Max %d", buffer.count, CONFIG_BUFFER_SIZE); now = (int)time(NULL); if(buffer.count < CONFIG_BUFFER_SIZE && now-lastsent < CONFIG_BUFFER_SEND) { zabbix_log( LOG_LEVEL_DEBUG, "Will not send now. Now %d lastsent %d < %d", now, lastsent, CONFIG_BUFFER_SEND); return ret; } if(buffer.count < 1) { return ret; } zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_REQUEST, ZBX_PROTO_VALUE_AGENT_DATA, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for(i=0;i<buffer.count;i++) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_HOST, buffer.data[i].host, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, buffer.data[i].key, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_VALUE, buffer.data[i].value, ZBX_JSON_TYPE_STRING); if (buffer.data[i].lastlogsize) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGLASTSIZE, buffer.data[i].lastlogsize); if (buffer.data[i].timestamp) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGTIMESTAMP, buffer.data[i].timestamp); if (buffer.data[i].source) zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGSOURCE, buffer.data[i].source, ZBX_JSON_TYPE_STRING); if (buffer.data[i].severity) zbx_json_adduint64(&json, ZBX_PROTO_TAG_LOGSEVERITY, buffer.data[i].severity); zbx_json_adduint64(&json, ZBX_PROTO_TAG_CLOCK, buffer.data[i].clock); zbx_json_close(&json); } zbx_json_close(&json); zbx_json_adduint64(&json, ZBX_PROTO_TAG_CLOCK, (int)time(NULL)); if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, MIN(buffer.count*CONFIG_TIMEOUT, 60)))) { zabbix_log(LOG_LEVEL_DEBUG, "JSON before sending [%s]", json.buffer); ret = zbx_tcp_send(&s, json.buffer); if( SUCCEED == ret ) { if( SUCCEED == (ret = zbx_tcp_recv(&s, &buf)) ) { zabbix_log(LOG_LEVEL_DEBUG, "JSON back [%s]", buf); if( !buf || check_response(buf) != SUCCEED ) { zabbix_log(LOG_LEVEL_DEBUG, "NOT OK"); } else { zabbix_log(LOG_LEVEL_DEBUG, "OK"); } } else zabbix_log(LOG_LEVEL_DEBUG, "Send value error: [recv] %s", zbx_tcp_strerror()); } else zabbix_log(LOG_LEVEL_DEBUG, "Send value error: [send] %s", zbx_tcp_strerror()); zbx_tcp_close(&s); } else zabbix_log(LOG_LEVEL_DEBUG, "Send value error: [connect] %s", zbx_tcp_strerror()); zbx_json_free(&json); if(SUCCEED == ret) { /* free buffer */ for(i=0;i<buffer.count;i++) { if(buffer.data[i].host != NULL) zbx_free(buffer.data[i].host); if(buffer.data[i].key != NULL) zbx_free(buffer.data[i].key); if(buffer.data[i].value != NULL) zbx_free(buffer.data[i].value); if(buffer.data[i].source != NULL) zbx_free(buffer.data[i].source); } buffer.count = 0; } if(SUCCEED == ret) lastsent = now; return ret; }
int main(int argc, char **argv) { char ch; int task = ZBX_TASK_START; char *TEST_METRIC = NULL; zbx_sock_t s_in; zbx_sock_t s_out; int ret; char **value, *command; AGENT_RESULT result; progname = get_program_name(argv[0]); /* parse the command-line */ while ((char)EOF != (ch = (char)zbx_getopt_long(argc, argv, "c:hVpt:", longopts, NULL))) { switch (ch) { case 'c': CONFIG_FILE = strdup(zbx_optarg); break; case 'h': help(); exit(FAIL); break; case 'V': version(); #ifdef _AIX tl_version(); #endif exit(FAIL); break; case 'p': if (task == ZBX_TASK_START) task = ZBX_TASK_PRINT_SUPPORTED; break; case 't': if (task == ZBX_TASK_START) { task = ZBX_TASK_TEST_METRIC; TEST_METRIC = strdup(zbx_optarg); } break; default: usage(); exit(FAIL); break; } } if (NULL == CONFIG_FILE) CONFIG_FILE = DEFAULT_CONFIG_FILE; /* load configuration */ if (ZBX_TASK_PRINT_SUPPORTED == task || ZBX_TASK_TEST_METRIC == task) zbx_load_config(ZBX_CFG_FILE_OPTIONAL); else zbx_load_config(ZBX_CFG_FILE_REQUIRED); /* metrics should be initialized before loading user parameters */ init_metrics(); /* user parameters */ load_user_parameters(CONFIG_USER_PARAMETERS); /* aliases */ load_aliases(CONFIG_ALIASES); zbx_free_config(); /* do not create debug files */ zabbix_open_log(LOG_TYPE_SYSLOG, LOG_LEVEL_EMPTY, NULL); switch (task) { case ZBX_TASK_TEST_METRIC: case ZBX_TASK_PRINT_SUPPORTED: if (ZBX_TASK_TEST_METRIC == task) test_parameter(TEST_METRIC); else test_parameters(); zabbix_close_log(); free_metrics(); alias_list_free(); exit(SUCCEED); break; default: /* do nothing */ break; } signal(SIGINT, child_signal_handler); signal(SIGTERM, child_signal_handler); signal(SIGQUIT, child_signal_handler); signal(SIGALRM, child_signal_handler); alarm(CONFIG_TIMEOUT); zbx_tcp_init(&s_in, (ZBX_SOCKET)fileno(stdin)); zbx_tcp_init(&s_out, (ZBX_SOCKET)fileno(stdout)); if (SUCCEED == (ret = zbx_tcp_check_security(&s_in, CONFIG_HOSTS_ALLOWED, 0))) { if (SUCCEED == (ret = zbx_tcp_recv(&s_in, &command))) { zbx_rtrim(command, "\r\n"); zabbix_log(LOG_LEVEL_DEBUG, "Requested [%s]", command); init_result(&result); process(command, 0, &result); if (NULL == (value = GET_TEXT_RESULT(&result))) value = GET_MSG_RESULT(&result); if (NULL != value) { zabbix_log(LOG_LEVEL_DEBUG, "Sending back [%s]", *value); ret = zbx_tcp_send(&s_out, *value); } free_result(&result); } if (FAIL == ret) zabbix_log(LOG_LEVEL_DEBUG, "Processing error: %s", zbx_tcp_strerror()); } fflush(stdout); alarm(0); zabbix_close_log(); free_metrics(); alias_list_free(); return SUCCEED; }
/****************************************************************************** * * * 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: 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_sock_t *sock, struct zbx_json_parse *jp) { char host[HOST_HOST_LEN_MAX], *name_esc, params[MAX_STRING_LEN], pattern[MAX_STRING_LEN], tmp[32], key_severity[MAX_STRING_LEN], key_logeventid[MAX_STRING_LEN]; DB_RESULT result; DB_ROW row; DB_ITEM item; struct zbx_json json; int res = FAIL; zbx_uint64_t hostid; char error[MAX_STRING_LEN]; DC_ITEM dc_item; char **regexp = NULL; int regexp_alloc = 0; int regexp_num = 0, n; char *sql = NULL; int sql_alloc = 2048; int sql_offset; zabbix_log(LOG_LEVEL_DEBUG, "In send_list_of_active_checks_json()"); 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; } if (FAIL == get_hostid_by_host(host, &hostid, error)) goto error; sql = zbx_malloc(sql, sql_alloc); name_esc = DBdyn_escape_string(host); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 1024, "select %s where i.hostid=h.hostid and h.status=%d and i.type=%d and h.hostid=" ZBX_FS_UI64 " and h.proxy_hostid=0", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_TYPE_ZABBIX_ACTIVE, hostid); if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and (i.status=%d or (i.status=%d and i.lastclock+%d<=%d))", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, CONFIG_REFRESH_UNSUPPORTED, time(NULL)); else zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 256, " and i.status=%d", ITEM_STATUS_ACTIVE); zbx_free(name_esc); 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); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { if (FAIL == DCconfig_get_item_by_key(&dc_item, (zbx_uint64_t)0, host, row[1])) { zabbix_log(LOG_LEVEL_DEBUG, "Item '%s' was not found in the server cache. Not sending now.", row[1]); continue; } zabbix_log(LOG_LEVEL_DEBUG, "Item '%s' was successfully found in the server cache. Sending.", row[1]); DBget_item_from_db(&item, row); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, item.key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(item.key, item.key_orig)) zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, item.key_orig, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.delay); zbx_json_addstring(&json, ZBX_PROTO_TAG_DELAY, tmp, ZBX_JSON_TYPE_STRING); /* The agent expects ALWAYS to have lastlogsize and mtime tags. Removing those would cause older agents to fail. */ zbx_snprintf(tmp, sizeof(tmp), "%d", item.lastlogsize); zbx_json_addstring(&json, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, ZBX_JSON_TYPE_STRING); zbx_snprintf(tmp, sizeof(tmp), "%d", item.mtime); zbx_json_addstring(&json, ZBX_PROTO_TAG_MTIME, tmp, ZBX_JSON_TYPE_STRING); zbx_json_close(&json); /* Special processing for log[] and logrt[] items */ do { /* simple try realization */ /* log[filename,pattern,encoding,maxlinespersec] */ /* logrt[filename_format,pattern,encoding,maxlinespersec] */ if (0 != strncmp(item.key, "log[", 4) && 0 != strncmp(item.key, "logrt[", 6)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break; /*dealing with `pattern' parameter*/ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); } while (0); /* simple try realization */ /* Special processing for eventlog[] items */ do { /* simple try realization */ /* eventlog[filename,pattern,severity,source,logeventid,maxlinespersec] */ if (0 != strncmp(item.key, "eventlog[", 9)) break; if (2 != parse_command(item.key, NULL, 0, params, MAX_STRING_LEN)) break; /*dealing with `pattern' parameter*/ if (0 == get_param(params, 2, pattern, sizeof(pattern)) && *pattern == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, pattern + 1); /*dealing with `severity' parameter*/ if (0 == get_param(params, 3, key_severity, sizeof(key_severity)) && *key_severity == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_severity + 1); /*dealing with `logeventid' parameter*/ if (0 == get_param(params, 5, key_logeventid, sizeof(key_logeventid)) && *key_logeventid == '@') add_regexp_name(®exp, ®exp_alloc, ®exp_num, key_logeventid + 1); } while (0); /* simple try realization */ } zbx_json_close(&json); DBfree_result(result); if (0 != regexp_num) { zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "select r.name,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive" " from regexps r,expressions e where r.regexpid=e.regexpid and r.name in ("); for (n = 0; n < regexp_num; n++) { name_esc = DBdyn_escape_string(regexp[n]); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512, "%s'%s'", n == 0 ? "" : ",", name_esc); zbx_free(name_esc); zbx_free(regexp[n]); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, ")"); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", row[0], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", row[1], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression_type", row[2], ZBX_JSON_TYPE_INT); zbx_json_addstring(&json, "exp_delimiter", row[3], ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "case_sensitive", row[4], ZBX_JSON_TYPE_INT); zbx_json_close(&json); } DBfree_result(result); } zbx_free(regexp); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", json.buffer); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_tcp_strerror()); else res = SUCCEED; alarm(0); zbx_json_free(&json); zbx_free(sql); return res; error: //zabbix_log(LOG_LEVEL_WARNING, "Sending list of active checks to [%s] failed: %s", // get_ip_by_socket(sock), 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, "Sending [%s]", json.buffer); res = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); return res; }