Пример #1
0
void	collect_perfstat()
{
	const char		*__function_name = "collect_perfstat";
	PERF_COUNTER_DATA	*cptr;
	PDH_STATUS		pdh_status;
	time_t			now;
	PDH_FMT_COUNTERVALUE	value;

	if (SUCCEED != perf_collector_started())
		return;

	if (NULL == ppsd.pPerfCounterList)	/* no counters */
		return;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	now = time(NULL);

	/* refresh unsupported counters */
	if (ppsd.nextcheck <= now)
	{
		for (cptr = ppsd.pPerfCounterList; NULL != cptr; cptr = cptr->next)
 		{
			if (PERF_COUNTER_NOTSUPPORTED != cptr->status)
				continue;

			zbx_PdhAddCounter(__function_name, cptr, ppsd.pdh_query, cptr->counterpath, &cptr->handle);
		}

		ppsd.nextcheck = now + UNSUPPORTED_REFRESH_PERIOD;
	}

	/* query for new data */
	if (ERROR_SUCCESS != (pdh_status = PdhCollectQueryData(ppsd.pdh_query)))
	{
		for (cptr = ppsd.pPerfCounterList; NULL != cptr; cptr = cptr->next)
		{
			if (PERF_COUNTER_NOTSUPPORTED != cptr->status)
				deactivate_perf_counter(cptr);
		}

		zabbix_log(LOG_LEVEL_DEBUG, "%s() call to PdhCollectQueryData() failed: %s",
				__function_name, strerror_from_module(pdh_status, L"PDH.DLL"));

		goto out;
	}

	/* get the raw values */
	for (cptr = ppsd.pPerfCounterList; NULL != cptr; cptr = cptr->next)
	{
		if (PERF_COUNTER_NOTSUPPORTED == cptr->status)
			continue;

		if (ERROR_SUCCESS != zbx_PdhGetRawCounterValue(__function_name, cptr->counterpath,
				cptr->handle, &cptr->rawValues[cptr->olderRawValue]))
		{
			deactivate_perf_counter(cptr);
			continue;
		}

		if (PERF_COUNTER_INITIALIZED < cptr->status)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "%s() counterpath:'%s' old first:%I64d second:%I64d",
					__function_name, cptr->counterpath,
					cptr->rawValues[(cptr->olderRawValue + 1) % 2].FirstValue,
					cptr->rawValues[(cptr->olderRawValue + 1) % 2].SecondValue);

			zabbix_log(LOG_LEVEL_DEBUG, "%s() counterpath:'%s' new first:%I64d second:%I64d",
					__function_name, cptr->counterpath,
					cptr->rawValues[cptr->olderRawValue].FirstValue,
					cptr->rawValues[cptr->olderRawValue].SecondValue);
		}

		cptr->olderRawValue = (cptr->olderRawValue + 1) % 2;

		pdh_status = PdhCalculateCounterFromRawValue(cptr->handle, PDH_FMT_DOUBLE,
				&cptr->rawValues[(cptr->olderRawValue + 1) % 2],						/* the new value */
				(PERF_COUNTER_INITIALIZED < cptr->status ? &cptr->rawValues[cptr->olderRawValue] : NULL),	/* the older value */
				&value);

		if (ERROR_SUCCESS == pdh_status && PDH_CSTATUS_VALID_DATA != value.CStatus && PDH_CSTATUS_NEW_DATA != value.CStatus)
			pdh_status = value.CStatus;

		if (PDH_CSTATUS_INVALID_DATA == pdh_status)
		{
			/* some (e.g., rate) counters require two raw values, MSDN lacks documentation */
			/* about what happens but tests show that PDH_CSTATUS_INVALID_DATA is returned */

			cptr->status = PERF_COUNTER_GET_SECOND_VALUE;
			continue;
		}

		if (PDH_CALC_NEGATIVE_DENOMINATOR == pdh_status)
		{
			/* This counter type shows the average percentage of active time observed during the sample   */
			/* interval. This is an inverse counter. Inverse counters are calculated by monitoring the    */
			/* percentage of time that the service was inactive and then subtracting that value from 100  */
			/* percent. The formula used to calculate the counter value is:                               */
			/* (1 - (inactive time delta) / (total time delta)) x 100                                     */
			/* For some unknown reason sometimes the collected row values indicate that inactive delta is */
			/* greater than total time delta. There must be some kind of bug in how performance counters  */
			/* work. When this happens function PdhCalculateCounterFromRawValue() returns error           */
			/* PDH_CALC_NEGATIVE_DENOMINATOR. Basically this means that an item was inactive all the time */
			/* so we set the return value to 0.0 and change status to indicate success.                   */
			/* More info: technet.microsoft.com/en-us/library/cc757283(WS.10).aspx                        */

			zabbix_log(LOG_LEVEL_DEBUG, "%s() counterpath:'%s'"
					" negative denominator error is treated as 0.0",
					__function_name, cptr->counterpath);

			pdh_status = ERROR_SUCCESS;
			value.doubleValue = 0.0;	/* 100% inactive */
		}

		if (ERROR_SUCCESS == pdh_status)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "%s() '%s' calculated value:" ZBX_FS_DBL, __function_name,
					cptr->counterpath, value.doubleValue);

			cptr->status = PERF_COUNTER_ACTIVE;
			cptr->value_current = (cptr->value_current + 1) % cptr->interval;
			if (cptr->value_count == cptr->interval)
				cptr->sum -= cptr->value_array[cptr->value_current];	/* remove the oldest value, value_count will not increase */
			cptr->value_array[cptr->value_current] = value.doubleValue;
			cptr->sum += cptr->value_array[cptr->value_current];
			if (cptr->value_count < cptr->interval)
				cptr->value_count++;
		}
		else
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot calculate performance counter value \"%s\": %s",
					cptr->counterpath, strerror_from_module(pdh_status, L"PDH.DLL"));

			deactivate_perf_counter(cptr);
		}
	}
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Пример #2
0
/* get Nth error from event log. 1 is the first. */
static int	zbx_get_eventlog_message(LPCTSTR wsource, HANDLE eventlog_handle, long which, char **out_source, char **out_message,
		unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid)
{
	const char	*__function_name = "zbx_get_eventlog_message";
	int		buffer_size = 512;
	EVENTLOGRECORD	*pELR = NULL;
	DWORD		dwRead, dwNeeded, dwErr;
	TCHAR		stat_buf[MAX_PATH], MsgDll[MAX_PATH];
	HKEY		hk = NULL;
	LPTSTR		pFile = NULL, pNextFile = NULL;
	DWORD		szData, Type;
	HINSTANCE	hLib = NULL;				/* handle to the messagetable DLL */
	LPTSTR		pCh, aInsertStrs[MAX_INSERT_STRS];	/* array of pointers to insert */
	LPTSTR		msgBuf = NULL;				/* hold text of the error message */
	char		*buf = NULL;
	long		i, err = 0;
	int		ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%ld", __function_name, which);

	*out_source	= NULL;
	*out_message	= NULL;
	*out_severity	= 0;
	*out_timestamp	= 0;
	*out_eventid	= 0;
	memset(aInsertStrs, 0, sizeof(aInsertStrs));

	pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size);
retry:
	if (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which,
			pELR, buffer_size, &dwRead, &dwNeeded))
	{
		dwErr = GetLastError();
		if (dwErr == ERROR_INSUFFICIENT_BUFFER)
		{
			buffer_size = dwNeeded;
			pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size);
			goto retry;
		}
		else
		{
			zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr));
			goto out;
		}
	}

	*out_severity	= pELR->EventType;			/* return event type */
	*out_timestamp	= pELR->TimeGenerated;			/* return timestamp */
	*out_eventid	= pELR->EventID & 0xffff;
	*out_source	= zbx_unicode_to_utf8((LPTSTR)(pELR + 1));	/* copy source name */

	err = FAIL;

	/* prepare the array of insert strings for FormatMessage - the
	insert strings are in the log entry. */
	for (i = 0, pCh = (LPTSTR)((LPBYTE)pELR + pELR->StringOffset);
			i < pELR->NumStrings && i < MAX_INSERT_STRS;
			i++, pCh += zbx_strlen(pCh) + 1) /* point to next string */
	{
		aInsertStrs[i] = pCh;
	}

	/* Get path to message dll */
	zbx_wsnprintf(stat_buf, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s\\%s"), wsource, (LPTSTR)(pELR + 1));

	if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, stat_buf, 0, KEY_READ, &hk))
	{
		if (ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("EventMessageFile"), NULL, &Type, NULL, &szData))
		{
			buf = zbx_malloc(buf, szData);
			if (ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("EventMessageFile"), NULL, &Type, (LPBYTE)buf, &szData))
				pFile = (LPTSTR)buf;
		}

		RegCloseKey(hk);
	}

	err = FAIL;

	while (NULL != pFile && FAIL == err)
	{
		if (NULL != (pNextFile = zbx_strchr(pFile, ';')))
		{
			*pNextFile = '\0';
			pNextFile++;
		}

		if (ExpandEnvironmentStrings(pFile, MsgDll, MAX_PATH))
		{
			if (NULL != (hLib = LoadLibraryEx(MsgDll, NULL, LOAD_LIBRARY_AS_DATAFILE)))
			{
				/* Format the message from the message DLL with the insert strings */
				if (0 != FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER |
						FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_SYSTEM |
						FORMAT_MESSAGE_MAX_WIDTH_MASK,	/* do not generate new line breaks */
						hLib,				/* the messagetable DLL handle */
						pELR->EventID,			/* message ID */
						MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US),	/* language ID */
						(LPTSTR)&msgBuf,		/* address of pointer to buffer for message */
						0,
						(va_list *)aInsertStrs))	/* array of insert strings for the message */
				{
					*out_message = zbx_unicode_to_utf8(msgBuf);
					zbx_rtrim(*out_message, "\r\n ");

					/* Free the buffer that FormatMessage allocated for us. */
					LocalFree((HLOCAL)msgBuf);

					err = SUCCEED;
				}
				FreeLibrary(hLib);
			}
		}
		pFile = pNextFile;
	}

	zbx_free(buf);

	if (SUCCEED != err)
	{
		*out_message = zbx_strdcatf(*out_message, "The description for Event ID (%lu) in Source (%s) cannot be found."
				" The local computer may not have the necessary registry information or message DLL files to"
				" display messages from a remote computer.", *out_eventid, NULL == *out_source ? "" : *out_source);
		if (pELR->NumStrings)
			*out_message = zbx_strdcatf(*out_message, " The following information is part of the event: ");
		for (i = 0; i < pELR->NumStrings && i < MAX_INSERT_STRS; i++)
		{
			if (i > 0)
				*out_message = zbx_strdcatf(*out_message, "; ");
			if (aInsertStrs[i])
			{
				buf = zbx_unicode_to_utf8(aInsertStrs[i]);
				*out_message = zbx_strdcatf(*out_message, "%s", buf);
				zbx_free(buf);
			}
		}
	}

	ret = SUCCEED;
out:
	zbx_free(pELR);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #3
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_execute_script                                               *
 *                                                                            *
 * Purpose: executing user scripts or remote commands                         *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments: !!! always call 'zbx_script_clean' function after                *
 *           'zbx_execute_script' to clear allocated memory                   *
 *                                                                            *
 ******************************************************************************/
int	zbx_execute_script(DC_HOST *host, zbx_script_t *script, char **result, char *error, size_t max_error_len)
{
	const char	*__function_name = "zbx_execute_script";
	int		ret = FAIL;
	zbx_uint64_t	groupid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	*error = '\0';

	switch (script->type)
	{
		case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT:
			dos2unix(script->command);	/* CR+LF (Windows) => LF (Unix) */

			switch (script->execute_on)
			{
				case ZBX_SCRIPT_EXECUTE_ON_AGENT:
					ret = zbx_execute_script_on_agent(host, script->command, result,
							error, max_error_len);
					break;
				case ZBX_SCRIPT_EXECUTE_ON_SERVER:
					ret = zbx_execute(script->command, result, error, max_error_len,
							CONFIG_TRAPPER_TIMEOUT);
					break;
				default:
					zbx_snprintf(error, max_error_len, "Invalid 'Execute on' option [%d]",
							(int)script->execute_on);
			}
			break;
		case ZBX_SCRIPT_TYPE_IPMI:
#ifdef HAVE_OPENIPMI
			if (SUCCEED == (ret = zbx_execute_ipmi_command(host, script->command, error, max_error_len)))
			{
				if (NULL != result)
					*result = zbx_strdup(*result, "IPMI command successfully executed");
			}
#else
			zbx_strlcpy(error, "Support for IPMI commands was not compiled in", max_error_len);
#endif
			break;
		case ZBX_SCRIPT_TYPE_SSH:
#ifdef HAVE_SSH2
			substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL,
					&script->publickey, MACRO_TYPE_COMMON, NULL, 0);
			substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL,
					&script->privatekey, MACRO_TYPE_COMMON, NULL, 0);
			/* break; is not missing here */
#else
			zbx_strlcpy(error, "Support for SSH script was not compiled in", max_error_len);
			break;
#endif
		case ZBX_SCRIPT_TYPE_TELNET:
			substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL,
					&script->username, MACRO_TYPE_COMMON, NULL, 0);
			substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL,
					&script->password, MACRO_TYPE_COMMON, NULL, 0);

			ret = zbx_execute_script_on_terminal(host, script, result, error, max_error_len);
			break;
		case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT:
			if (SUCCEED != DBget_script_by_scriptid(script->scriptid, script, &groupid))
			{
				zbx_snprintf(error, max_error_len,
						"Unknown Script ID [" ZBX_FS_UI64 "]", script->scriptid);
				break;
			}

			if (SUCCEED == check_script_permissions(groupid, host->hostid, error, max_error_len))
			{
				substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, host, NULL,
						&script->command, MACRO_TYPE_SCRIPT, NULL, 0);

				ret = zbx_execute_script(host, script, result, error, max_error_len);	/* recursion */
			}
			break;
		default:
			zbx_snprintf(error, max_error_len, "Invalid command type [%d]", (int)script->type);
	}

	if (FAIL == ret && NULL != result)
		*result = zbx_strdup(*result, "");

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #4
0
/******************************************************************************
 *                                                                            *
 * 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;
}
Пример #5
0
static void	process_active_checks(char *server, unsigned short port)
{
	const char	*__function_name = "process_active_checks";
	register int	i, s_count, p_count;
	char		**pvalue;
	int		now, send_err = SUCCEED, ret;
	char		*value = NULL, *item_value = NULL;
	zbx_uint64_t	lastlogsize;
	int		mtime;
	char		params[MAX_STRING_LEN], filename[MAX_STRING_LEN];
	char		pattern[MAX_STRING_LEN], output_template[MAX_STRING_LEN];
	/* checks `log', `eventlog', `logrt' may contain parameter, which overrides CONFIG_MAX_LINES_PER_SECOND */
	char		maxlines_persec_str[16];
	int		maxlines_persec;
#ifdef _WINDOWS
	unsigned long	timestamp, logeventid;
	unsigned short	severity;
	char		key_severity[MAX_STRING_LEN], str_severity[32] /* for `regex_match_ex' */;
	char		key_source[MAX_STRING_LEN], *provider = NULL, *source = NULL;
	char		key_logeventid[MAX_STRING_LEN], str_logeventid[8] /* for `regex_match_ex' */;
	OSVERSIONINFO	versionInfo;
	zbx_uint64_t	keywords;
	EVT_HANDLE	eventlog6_render_context = NULL;
	EVT_HANDLE	eventlog6_query = NULL;
	zbx_uint64_t	eventlog6_firstid = 0;
	zbx_uint64_t	eventlog6_lastid = 0;
#endif
	char		encoding[32];
	char		tmp[16];

	AGENT_RESULT	result;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s('%s',%hu)", __function_name, server, port);

	init_result(&result);

	now = (int)time(NULL);

	for (i = 0; NULL != active_metrics[i].key && SUCCEED == send_err; i++)
	{
		if (active_metrics[i].nextcheck > now)
			continue;

		if (ITEM_STATE_NORMAL != active_metrics[i].state)
			continue;

		/* special processing for log files without rotation */
		if (0 == strncmp(active_metrics[i].key, "log[", 4))
		{
			ret = FAIL;

			do
			{
				/* simple try realization */
				if (ZBX_COMMAND_WITH_PARAMS != parse_command(active_metrics[i].key, NULL, 0,
						params, sizeof(params)))
				{
					break;
				}

				if (6 < num_param(params))
					break;

				if (0 != get_param(params, 1, filename, sizeof(filename)))
					break;

				if (0 != get_param(params, 2, pattern, sizeof(pattern)))
					*pattern = '\0';

				if (0 != get_param(params, 3, encoding, sizeof(encoding)))
					*encoding = '\0';

				zbx_strupper(encoding);

				if (0 != get_param(params, 4, maxlines_persec_str, sizeof(maxlines_persec_str)) ||
						'\0' == *maxlines_persec_str)
					maxlines_persec = CONFIG_MAX_LINES_PER_SECOND;
				else if (MIN_VALUE_LINES > (maxlines_persec = atoi(maxlines_persec_str)) ||
						MAX_VALUE_LINES < maxlines_persec)
					break;

				if (0 != get_param(params, 5, tmp, sizeof(tmp)))
					*tmp = '\0';

				if ('\0' == *tmp || 0 == strcmp(tmp, "all"))
					active_metrics[i].skip_old_data = 0;
				else if (0 != strcmp(tmp, "skip"))
					break;

				if (0 != get_param(params, 6, output_template, sizeof(output_template)))
					*output_template = '\0';

				s_count = 0;
				p_count = 0;
				lastlogsize = active_metrics[i].lastlogsize;

				while (SUCCEED == (ret = process_log(filename, &lastlogsize, &value, encoding,
						active_metrics[i].skip_old_data)))
				{
					active_metrics[i].skip_old_data = 0;

					/* End of file. The file could become empty, must save `lastlogsize'. */
					if (NULL == value)
					{
						active_metrics[i].lastlogsize = lastlogsize;
						break;
					}

					if (SUCCEED == regexp_sub_ex(&regexps, value, pattern, ZBX_CASE_SENSITIVE,
							output_template, &item_value))
					{
						send_err = process_value(server, port, CONFIG_HOSTNAME,
								active_metrics[i].key_orig, item_value, &lastlogsize,
								NULL, NULL, NULL, NULL,	NULL, 1);

						zbx_free(item_value);

						s_count++;
					}
					p_count++;

					zbx_free(value);

					if (SUCCEED == send_err)
						active_metrics[i].lastlogsize = lastlogsize;
					else
					{
						/* buffer is full, stop processing active checks */
						/* till the buffer is cleared */
						lastlogsize = active_metrics[i].lastlogsize;
						goto ret;
					}

					/* do not flood Zabbix server if file grows too fast */
					if (s_count >= (maxlines_persec * active_metrics[i].refresh))
						break;

					/* do not flood local system if file grows too fast */
					if (p_count >= (4 * maxlines_persec * active_metrics[i].refresh))
						break;
				} /* while processing a log */

			}
			while (0); /* simple try realization */

			if (FAIL == ret)
			{
				active_metrics[i].state = ITEM_STATE_NOTSUPPORTED;
				zabbix_log(LOG_LEVEL_WARNING, "active check \"%s\" is not supported",
						active_metrics[i].key);

				process_value(server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, NULL,
						&active_metrics[i].lastlogsize, NULL, NULL, NULL, NULL, NULL, 0);
			}
		}
		/* special processing for log files with rotation */
		else if (0 == strncmp(active_metrics[i].key, "logrt[", 6))
		{
			ret = FAIL;

			do
			{
				/* simple try realization */
				if (ZBX_COMMAND_WITH_PARAMS != parse_command(active_metrics[i].key, NULL, 0,
						params, sizeof(params)))
				{
					break;
				}

				if (6 < num_param(params))
					break;

				if (0 != get_param(params, 1, filename, sizeof(filename)))
					break;

				if (0 != get_param(params, 2, pattern, sizeof(pattern)))
					*pattern = '\0';

				if (0 != get_param(params, 3, encoding, sizeof(encoding)))
					*encoding = '\0';

				zbx_strupper(encoding);

				if (0 != get_param(params, 4, maxlines_persec_str, sizeof(maxlines_persec_str)) ||
						'\0' == *maxlines_persec_str)
					maxlines_persec = CONFIG_MAX_LINES_PER_SECOND;
				else if (MIN_VALUE_LINES > (maxlines_persec = atoi(maxlines_persec_str)) ||
						MAX_VALUE_LINES < maxlines_persec)
					break;

				if (0 != get_param(params, 5, tmp, sizeof(tmp)))
					*tmp = '\0';

				if ('\0' == *tmp || 0 == strcmp(tmp, "all"))
					active_metrics[i].skip_old_data = 0;
				else if (0 != strcmp(tmp, "skip"))
					break;

				if (0 != get_param(params, 6, output_template, sizeof(output_template)))
					*output_template = '\0';

				s_count = 0;
				p_count = 0;
				lastlogsize = active_metrics[i].lastlogsize;
				mtime = active_metrics[i].mtime;

				while (SUCCEED == (ret = process_logrt(filename, &lastlogsize, &mtime, &value,
						encoding, active_metrics[i].skip_old_data)))
				{
					active_metrics[i].skip_old_data = 0;

					/* End of file. The file could become empty,*/
					/* must save `lastlogsize' and `mtime'. */
					if (NULL == value)
					{
						active_metrics[i].lastlogsize = lastlogsize;
						active_metrics[i].mtime	= mtime;
						break;
					}

					if (SUCCEED == regexp_sub_ex(&regexps, value, pattern, ZBX_CASE_SENSITIVE,
							output_template, &item_value))
					{
						send_err = process_value(server, port, CONFIG_HOSTNAME,
								active_metrics[i].key_orig, item_value, &lastlogsize,
								&mtime, NULL, NULL, NULL, NULL, 1);

						zbx_free(item_value);

						s_count++;
					}
					p_count++;

					zbx_free(value);

					if (SUCCEED == send_err)
					{
						active_metrics[i].lastlogsize = lastlogsize;
						active_metrics[i].mtime = mtime;
					}
					else
					{
						/* buffer is full, stop processing active checks */
						/* till the buffer is cleared */
						lastlogsize = active_metrics[i].lastlogsize;
						mtime = active_metrics[i].mtime;
						goto ret;
					}

					/* do not flood Zabbix server if file grows too fast */
					if (s_count >= (maxlines_persec * active_metrics[i].refresh))
						break;

					/* do not flood local system if file grows too fast */
					if (p_count >= (4 * maxlines_persec * active_metrics[i].refresh))
						break;
				} /* while processing a log */
			}
			while (0); /* simple try realization */

			if (FAIL == ret)
			{
				active_metrics[i].state = ITEM_STATE_NOTSUPPORTED;
				zabbix_log(LOG_LEVEL_WARNING, "active check \"%s\" is not supported",
						active_metrics[i].key);

				process_value(server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, NULL,
						&active_metrics[i].lastlogsize, &active_metrics[i].mtime,
						NULL, NULL, NULL, NULL, 0);
			}
		}
		/* special processing for eventlog */
		else if (0 == strncmp(active_metrics[i].key, "eventlog[", 9))
		{
			ret = FAIL;
#ifdef _WINDOWS
			do
			{
				/* simple try realization */
				if (ZBX_COMMAND_WITH_PARAMS != parse_command(active_metrics[i].key, NULL, 0,
						params, sizeof(params)))
				{
					break;
				}

				if (7 < num_param(params))
					break;

				if (0 != get_param(params, 1, filename, sizeof(filename)))
					break;

				if (0 != get_param(params, 2, pattern, sizeof(pattern)))
					*pattern = '\0';

				if (0 != get_param(params, 3, key_severity, sizeof(key_severity)))
					*key_severity = '\0';

				if (0 != get_param(params, 4, key_source, sizeof(key_source)))
					*key_source = '\0';

				if (0 != get_param(params, 5, key_logeventid, sizeof(key_logeventid)))
					*key_logeventid = '\0';

				if (0 != get_param(params, 6, maxlines_persec_str, sizeof(maxlines_persec_str)) ||
						'\0' == *maxlines_persec_str)
					maxlines_persec = CONFIG_MAX_LINES_PER_SECOND;
				else if (MIN_VALUE_LINES > (maxlines_persec = atoi(maxlines_persec_str)) ||
						MAX_VALUE_LINES < maxlines_persec)
					break;

				if (0 != get_param(params, 7, tmp, sizeof(tmp)))
					*tmp = '\0';

				if ('\0' == *tmp || 0 == strcmp(tmp, "all"))
					active_metrics[i].skip_old_data = 0;
				else if (0 != strcmp(tmp, "skip"))
					break;

				s_count = 0;
				p_count = 0;
				lastlogsize = active_metrics[i].lastlogsize;

				versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
				GetVersionEx(&versionInfo);

				if (versionInfo.dwMajorVersion >= 6)	/* Windows Vista, 7 or Server 2008 */
				{
					__try
					{
						if (SUCCEED != initialize_eventlog6(filename, &lastlogsize,
								&eventlog6_firstid, &eventlog6_lastid,
								&eventlog6_render_context, &eventlog6_query))
						{
							finalize_eventlog6(&eventlog6_render_context, &eventlog6_query);
							break;
						}

						while (SUCCEED == (ret = process_eventlog6(filename, &lastlogsize,
								&timestamp, &provider, &source, &severity, &value,
								&logeventid, &eventlog6_firstid, &eventlog6_lastid,
								&eventlog6_render_context, &eventlog6_query,
								&keywords, active_metrics[i].skip_old_data)))
						{
							active_metrics[i].skip_old_data = 0;

							/* End of file. */
							/* The eventlog could become empty, must save `lastlogsize'. */
							if (NULL == value)
							{
								active_metrics[i].lastlogsize = lastlogsize;
								break;
							}

							switch (severity)
							{
								case WINEVENT_LEVEL_LOG_ALWAYS:
								case WINEVENT_LEVEL_INFO:
									if (0 != (keywords &
											WINEVENT_KEYWORD_AUDIT_FAILURE))
									{
										severity = ITEM_LOGTYPE_FAILURE_AUDIT;
										strscpy(str_severity, AUDIT_FAILURE);
										break;
									}
									else if (0 != (keywords &
											WINEVENT_KEYWORD_AUDIT_SUCCESS))
									{
										severity = ITEM_LOGTYPE_SUCCESS_AUDIT;
										strscpy(str_severity, AUDIT_SUCCESS);
										break;
									}
									else
										severity = ITEM_LOGTYPE_INFORMATION;
										strscpy(str_severity, INFORMATION_TYPE);
										break;
								case WINEVENT_LEVEL_WARNING:
									severity = ITEM_LOGTYPE_WARNING;
									strscpy(str_severity, WARNING_TYPE);
									break;
								case WINEVENT_LEVEL_ERROR:
									severity = ITEM_LOGTYPE_ERROR;
									strscpy(str_severity, ERROR_TYPE);
									break;
								case WINEVENT_LEVEL_CRITICAL:
									severity = ITEM_LOGTYPE_CRITICAL;
									strscpy(str_severity, CRITICAL_TYPE);
									break;
								case WINEVENT_LEVEL_VERBOSE:
									severity = ITEM_LOGTYPE_VERBOSE;
									strscpy(str_severity, VERBOSE_TYPE);
									break;
							}

							zbx_snprintf(str_logeventid, sizeof(str_logeventid), "%lu",
									logeventid);

							if (SUCCEED == regexp_match_ex(&regexps, value, pattern, ZBX_CASE_SENSITIVE) &&
								SUCCEED == regexp_match_ex(&regexps, str_severity, key_severity,
										ZBX_IGNORE_CASE) &&
								SUCCEED == regexp_match_ex(&regexps, provider, key_source,
										ZBX_IGNORE_CASE) &&
								SUCCEED == regexp_match_ex(&regexps, str_logeventid,
										key_logeventid, ZBX_CASE_SENSITIVE))
							{
								send_err = process_value(server, port, CONFIG_HOSTNAME,
										active_metrics[i].key_orig, value, &lastlogsize,
										NULL, &timestamp, provider, &severity, &logeventid, 1);
								s_count++;
							}
							p_count++;

							zbx_free(source);
							zbx_free(provider);
							zbx_free(value);

							if (SUCCEED == send_err)
								active_metrics[i].lastlogsize = lastlogsize;
							else
							{
								/* buffer is full, stop processing active checks*/
								/* till the buffer is cleared */
								lastlogsize = active_metrics[i].lastlogsize;
								goto ret;
							}

							/* do not flood Zabbix server if file grows too fast */
							if (s_count >= (maxlines_persec * active_metrics[i].refresh))
								break;

							/* do not flood local system if file grows too fast */
							if (p_count >= (4 * maxlines_persec * active_metrics[i].refresh))
								break;

						} /* while processing an eventlog */

						finalize_eventlog6(&eventlog6_render_context, &eventlog6_query);
					}
					__except (DelayLoadDllExceptionFilter(GetExceptionInformation()))
					{
						zabbix_log(LOG_LEVEL_WARNING, "failed to process eventlog");
						break;
					}
				}
				else if (versionInfo.dwMajorVersion < 6)    /* Windows versions before Vista */
				{
					while (SUCCEED == (ret = process_eventlog(filename, &lastlogsize,
							&timestamp, &source, &severity, &value, &logeventid,
							active_metrics[i].skip_old_data)))
					{
						active_metrics[i].skip_old_data = 0;

						/* End of file. */
						/* The eventlog could become empty, must save `lastlogsize'. */
						if (NULL == value)
						{
							active_metrics[i].lastlogsize = lastlogsize;
							break;
						}

						switch (severity)
						{
							case EVENTLOG_SUCCESS:
							case EVENTLOG_INFORMATION_TYPE:
								severity = ITEM_LOGTYPE_INFORMATION;
								strscpy(str_severity, INFORMATION_TYPE);
								break;
							case EVENTLOG_WARNING_TYPE:
								severity = ITEM_LOGTYPE_WARNING;
								strscpy(str_severity, WARNING_TYPE);
								break;
							case EVENTLOG_ERROR_TYPE:
								severity = ITEM_LOGTYPE_ERROR;
								strscpy(str_severity, ERROR_TYPE);
								break;
							case EVENTLOG_AUDIT_FAILURE:
								severity = ITEM_LOGTYPE_FAILURE_AUDIT;
								strscpy(str_severity, AUDIT_FAILURE);
								break;
							case EVENTLOG_AUDIT_SUCCESS:
								severity = ITEM_LOGTYPE_SUCCESS_AUDIT;
								strscpy(str_severity, AUDIT_SUCCESS);
								break;
						}

						zbx_snprintf(str_logeventid, sizeof(str_logeventid), "%lu", logeventid);

						if (SUCCEED == regexp_match_ex(&regexps, value, pattern, ZBX_CASE_SENSITIVE) &&
								SUCCEED == regexp_match_ex(&regexps, str_severity, key_severity,
										ZBX_IGNORE_CASE) &&
								SUCCEED == regexp_match_ex(&regexps, source, key_source,
										ZBX_IGNORE_CASE) &&
								SUCCEED == regexp_match_ex(&regexps, str_logeventid,
										key_logeventid, ZBX_CASE_SENSITIVE))
						{
							send_err = process_value(server, port, CONFIG_HOSTNAME,
									active_metrics[i].key_orig, value, &lastlogsize,
									NULL, &timestamp, source, &severity, &logeventid, 1);
							s_count++;
						}
						p_count++;

						zbx_free(source);
						zbx_free(value);

						if (SUCCEED == send_err)
							active_metrics[i].lastlogsize = lastlogsize;
						else
						{
							/* buffer is full, stop processing active checks */
							/* till the buffer is cleared */
							lastlogsize = active_metrics[i].lastlogsize;
							goto ret;
						}

						/* do not flood Zabbix server if file grows too fast */
						if (s_count >= (maxlines_persec * active_metrics[i].refresh))
							break;

						/* do not flood local system if file grows too fast */
						if (p_count >= (4 * maxlines_persec * active_metrics[i].refresh))
							break;
					} /* while processing an eventlog */
				}
				break;
			}
			while (0); /* simple try realization */
#endif	/* _WINDOWS */

			if (FAIL == ret)
			{
				active_metrics[i].state = ITEM_STATE_NOTSUPPORTED;
				zabbix_log(LOG_LEVEL_WARNING, "active check \"%s\" is not supported",
						active_metrics[i].key);

				process_value(server, port, CONFIG_HOSTNAME, active_metrics[i].key_orig, NULL,
						&active_metrics[i].lastlogsize, NULL, NULL, NULL, NULL, NULL, 0);
			}
		}
Пример #6
0
/* obtain a particular message from a desired eventlog */
static int	zbx_get_eventlog_message6(LPCWSTR wsource, zbx_uint64_t *which, unsigned short *out_severity,
                                      unsigned long *out_timestamp, char **out_provider, char **out_source, char **out_message,
                                      unsigned long *out_eventid, EVT_HANDLE *render_context, EVT_HANDLE *query, zbx_uint64_t *keywords)
{
    const char		*__function_name = "zbx_get_eventlog_message6";
    EVT_HANDLE		event_bookmark = NULL;
    EVT_VARIANT*		renderedContent = NULL;
    LPCWSTR			pprovider = NULL;
    LPSTR			tmp_str = NULL;
    DWORD			size = DEFAULT_EVENT_CONTENT_SIZE;
    DWORD			bookmarkedCount = 0;
    DWORD			require = 0;
    const zbx_uint64_t	sec_1970 = 116444736000000000;
    const zbx_uint64_t	success_audit = 0x20000000000000;
    const zbx_uint64_t	failure_audit = 0x10000000000000;
    int			ret = FAIL;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() lastlogsize:" ZBX_FS_UI64, __function_name, *which);

    if (NULL == *query)
    {
        zabbix_log(LOG_LEVEL_DEBUG, "no EvtQuery handle");
        goto finish;
    }

    /* get the entries and allocate required space */
    renderedContent = zbx_malloc(renderedContent, size);
    if (TRUE != EvtNext(*query, 1, &event_bookmark, INFINITE, 0, &require))
    {
        zabbix_log(LOG_LEVEL_WARNING, "EvtNext failed: %s, lastlogsize:" ZBX_FS_UI64,
                   strerror_from_system(GetLastError()), *which);
        goto finish;
    }

    /* obtain the information from the selected events */
    if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
                          &require, &bookmarkedCount) )
    {
        /* information exceeds the space allocated */
        if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
        {
            zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed: %s", strerror_from_system(GetLastError()));
            goto finish;
        }

        renderedContent = (EVT_VARIANT*)zbx_realloc((void *)renderedContent, require);
        size = require;

        if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
                              &require, &bookmarkedCount))
        {
            zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed: %s", strerror_from_system(GetLastError()));
            goto finish;
        }
    }

    pprovider = VAR_PROVIDER_NAME(renderedContent);
    *out_provider = zbx_unicode_to_utf8(pprovider);

    if (NULL != VAR_SOURCE_NAME(renderedContent))
    {
        *out_source = zbx_unicode_to_utf8(VAR_SOURCE_NAME(renderedContent));
    }

    *keywords = VAR_KEYWORDS(renderedContent) & (success_audit | failure_audit);
    *out_severity = VAR_LEVEL(renderedContent);
    *out_timestamp = (unsigned long)((VAR_TIME_CREATED(renderedContent) - sec_1970) / 10000000);
    *out_eventid = VAR_EVENT_ID(renderedContent);
    *out_message = expand_message6(pprovider, event_bookmark);

    tmp_str = zbx_unicode_to_utf8(wsource);

    if (VAR_RECORD_NUMBER(renderedContent) != *which)
    {
        zabbix_log(LOG_LEVEL_DEBUG, "Overwriting expected EventRecordID:" ZBX_FS_UI64 " with the real"
                   " EventRecordID:" ZBX_FS_UI64 " in eventlog '%s'", *which,
                   VAR_RECORD_NUMBER(renderedContent), tmp_str);
        *which = VAR_RECORD_NUMBER(renderedContent);
    }

    /* some events dont have enough information for making event message */
    if (NULL == *out_message)
    {
        *out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'"
                                    " cannot be found. Either the component that raises this event is not installed"
                                    " on your local computer or the installation is corrupted. You can install or repair"
                                    " the component on the local computer. If the event originated on another computer,"
                                    " the display information had to be saved with the event.", *out_eventid,
                                    NULL == *out_provider ? "" : *out_provider);
    }

    ret = SUCCEED;

finish:
    if (NULL != event_bookmark)
        EvtClose(event_bookmark);
    zbx_free(tmp_str);
    zbx_free(renderedContent);
    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

    return ret;
}
Пример #7
0
/******************************************************************************
 *                                                                            *
 * 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(&regexps);

	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(&regexps, 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;
}
Пример #8
0
/******************************************************************************
 *                                                                            *
 * Function: main_alerter_loop                                                *
 *                                                                            *
 * Purpose: periodically check table alerts and send notifications if needed  *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
void	main_alerter_loop()
{
	char			error[MAX_STRING_LEN], *error_esc;
	int			res;
	DB_RESULT		result;
	DB_ROW			row;
	DB_ALERT		alert;
	DB_MEDIATYPE		mediatype;

	zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));

	DBconnect(ZBX_DB_CONNECT_NORMAL);

	for (;;)
	{
		zbx_setproctitle("%s [sending alerts]", get_process_type_string(process_type));

		result = DBselect(
				"select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid,"
				"mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path,"
				"mt.gsm_modem,mt.username,mt.passwd,a.retries"
				" from alerts a,media_type mt"
				" where a.mediatypeid=mt.mediatypeid"
					" and a.status=%d"
					" and a.alerttype=%d"
					DB_NODE
				" order by a.alertid",
				ALERT_STATUS_NOT_SENT,
				ALERT_TYPE_MESSAGE,
				DBnode_local("mt.mediatypeid"));

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(alert.alertid, row[0]);
			ZBX_STR2UINT64(alert.mediatypeid, row[1]);
			alert.sendto = row[2];
			alert.subject = row[3];
			alert.message = row[4];
			alert.status = atoi(row[5]);

			ZBX_STR2UINT64(mediatype.mediatypeid, row[6]);
			mediatype.type = atoi(row[7]);
			mediatype.description = row[8];
			mediatype.smtp_server = row[9];
			mediatype.smtp_helo = row[10];
			mediatype.smtp_email = row[11];
			mediatype.exec_path = row[12];
			mediatype.gsm_modem = row[13];
			mediatype.username = row[14];
			mediatype.passwd = row[15];

			alert.retries = atoi(row[16]);

			*error = '\0';
			res = execute_action(&alert, &mediatype, error, sizeof(error));

			if (SUCCEED == res)
			{
				zabbix_log(LOG_LEVEL_DEBUG, "alert ID [" ZBX_FS_UI64 "] was sent successfully",
						alert.alertid);
				DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64,
						ALERT_STATUS_SENT, alert.alertid);
			}
			else
			{
				zabbix_log(LOG_LEVEL_DEBUG, "error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid);

				error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN);

				alert.retries++;

				if (ALERT_MAX_RETRIES > alert.retries)
				{
					DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
							alert.retries, error_esc, alert.alertid);
				}
				else
				{
					DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
							ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid);
				}

				zbx_free(error_esc);
			}

		}
		DBfree_result(result);

		zbx_sleep_loop(CONFIG_SENDER_FREQUENCY);
	}
}
Пример #9
0
/******************************************************************************
 *                                                                            *
 * Function: execute_action                                                   *
 *                                                                            *
 * Purpose: execute an action depending on mediatype                          *
 *                                                                            *
 * Parameters: alert - alert details                                          *
 *             mediatype - media details                                      *
 *                                                                            *
 * Return value: SUCCESS - action executed successfully                       *
 *               FAIL - otherwise, error will contain error message           *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
int	execute_action(DB_ALERT *alert, DB_MEDIATYPE *mediatype, char *error, int max_error_len)
{
	const char	*__function_name = "execute_action";

	int 	res = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s(): alertid [" ZBX_FS_UI64 "] mediatype [%d]",
			__function_name, alert->alertid, mediatype->type);

	if (MEDIA_TYPE_EMAIL == mediatype->type)
	{
		alarm(ALARM_ACTION_TIMEOUT);
		res = send_email(mediatype->smtp_server, mediatype->smtp_helo, mediatype->smtp_email,
				alert->sendto, alert->subject, alert->message, error, max_error_len);
		alarm(0);
	}
#ifdef HAVE_JABBER
	else if (MEDIA_TYPE_JABBER == mediatype->type)
	{
		/* Jabber uses its own timeouts */
		res = send_jabber(mediatype->username, mediatype->passwd,
				alert->sendto, alert->subject, alert->message, error, max_error_len);
	}
#endif
	else if (MEDIA_TYPE_SMS == mediatype->type)
	{
		/* SMS uses its own timeouts */
		res = send_sms(mediatype->gsm_modem, alert->sendto, alert->message, error, max_error_len);
	}
	else if (MEDIA_TYPE_EZ_TEXTING == mediatype->type)
	{
		/* Ez Texting uses its own timeouts */
		res = send_ez_texting(mediatype->username, mediatype->passwd,
				alert->sendto, alert->message, mediatype->exec_path, error, max_error_len);
	}
	else if (MEDIA_TYPE_EXEC == mediatype->type)
	{
		char	*cmd = NULL, *send_to, *subject, *message, *output = NULL;
		size_t	cmd_alloc = ZBX_KIBIBYTE, cmd_offset = 0;

		cmd = zbx_malloc(cmd, cmd_alloc);

		zbx_snprintf_alloc(&cmd, &cmd_alloc, &cmd_offset, "%s/%s",
				CONFIG_ALERT_SCRIPTS_PATH, mediatype->exec_path);

		if (0 == access(cmd, X_OK))
		{
			send_to = zbx_dyn_escape_string(alert->sendto, "\"\\");
			subject = zbx_dyn_escape_string(alert->subject, "\"\\");
			message = zbx_dyn_escape_string(alert->message, "\"\\");

			zbx_snprintf_alloc(&cmd, &cmd_alloc, &cmd_offset, " \"%s\" \"%s\" \"%s\"",
					send_to, subject, message);

			zbx_free(send_to);
			zbx_free(subject);
			zbx_free(message);

			if (SUCCEED == (res = zbx_execute(cmd, &output, error, max_error_len, ALARM_ACTION_TIMEOUT)))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "%s output:\n%s", mediatype->exec_path, output);
				zbx_free(output);
			}
			else
				res = FAIL;
		}
		else
			zbx_snprintf(error, max_error_len, "%s: %s", cmd, zbx_strerror(errno));

		zbx_free(cmd);
	}
	else
	{
		zbx_snprintf(error, max_error_len, "unsupported media type [%d]", mediatype->type);
		zabbix_log(LOG_LEVEL_ERR, "alert ID [" ZBX_FS_UI64 "]: %s", alert->alertid, error);
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res));

	return res;
}
Пример #10
0
static int apply_new_entries ()
{
    int count, i;
    unsigned long s = 0, t;
    size_t ofs;

    zabbix_log (LOG_LEVEL_DEBUG, "apply_active_buffer");

    free_entries ();

    if (!buffer.new_entries)
        return 1;

    /* get amount of active checks */
    count = i = 0;
    while (buffer.new_entries[i++].key)
        count++;

    zabbix_log (LOG_LEVEL_DEBUG, "apply_active_buffer: count of new checks %d", count);

    buffer.entries = (buffer_check_entry_t*)malloc (count*sizeof (buffer_check_entry_t));

    if (!buffer.entries)
        return 0;

    buffer.header_size = sizeof (buffer_signature) + sizeof (unsigned int);
    buffer.size = count;
    zabbix_log (LOG_LEVEL_DEBUG, "apply_active_buffer: memory for new entries allocated");

    if (count) {
        for (i = 0; i < count; i++) {
            buffer.entries[i].key = strdup (buffer.new_entries[i].key);

            if (buffer.new_entries[i].refresh)
                s += (entry_size_estimation * 60UL) / buffer.new_entries[i].refresh;
            else
                s += (entry_size_estimation * 60UL) / 1;
        }

        /* here we have estimation of our buffer space in minutes */
	t = (CONFIG_ACTIVE_BUF_SIZE_MB * 1024UL*1024UL) / s;

        zabbix_log (LOG_LEVEL_DEBUG, "apply_active_buffer: New buffer's estimation time to live is %lu minutes", t);

        ofs = 0;
        s = 0;

        for (i = 0; i < count; i++) {
            buffer.header_size += strlen (buffer.entries[i].key) + 1 + sizeof (size_t)*2 + sizeof (int)*2;
            buffer.entries[i].beg_offset = ofs;

            if (buffer.new_entries[i].refresh)
                ofs += t*(entry_size_estimation * 60UL) / buffer.new_entries[i].refresh;
            else
                ofs += t*(entry_size_estimation * 60UL) / 1;

            buffer.entries[i].max_offset = ofs;
            buffer.entries[i].index = 0;
            buffer.entries[i].count = 0;
            buffer.entries[i].refresh = buffer.new_entries[i].refresh;
            buffer.entries[i].max_items = (buffer.entries[i].max_offset-buffer.entries[i].beg_offset) / 6;
            buffer.entries[i].sizes = (unsigned short*)calloc (sizeof (unsigned short), buffer.entries[i].max_items);
            buffer.header_size += buffer.entries[i].max_items*sizeof (unsigned short);

            zabbix_log (LOG_LEVEL_DEBUG, "Item %s: refr: %d, max_items = %d", buffer.entries[i].key, 
                        buffer.new_entries[i].refresh, buffer.entries[i].max_items);
            s += buffer.entries[i].max_offset-buffer.entries[i].beg_offset;
        }

        zabbix_log (LOG_LEVEL_DEBUG, "Total size of buffers %d", s);
    }

    /* all finished ok */
    buffer.new_entries = NULL;
    flush_buffer ();

    return 1;
}
Пример #11
0
void store_in_active_buffer (const char* key, const char* value)
{
    int i, len = strlen (value), fill, p;
    time_t ts = time (NULL);
    buffer_check_entry_t* e;
    size_t ofs;
    unsigned char zero = 0;

    if (!buffer.active)
        return;

    zabbix_log (LOG_LEVEL_DEBUG, "store_in_active_buffer ()");

    for (i = 0; i < buffer.size; i++) {
        if (strcmp (buffer.entries[i].key, key))
            continue;

        e = buffer.entries+i;
        zabbix_log (LOG_LEVEL_DEBUG, "Item found. It's %d-th item. Count: %d, It has index %d, beg: %lu, end: %lu", 
                    i, e->count, e->index, e->beg_offset, e->max_offset);

        /* find space to store our value */
        ofs = e->beg_offset;
        for (i = 0; i < e->index; i++)
            ofs += e->sizes[i];

        if (ofs + sizeof (ts) + len + 1 > e->max_offset) {
            zabbix_log (LOG_LEVEL_DEBUG, "Wrap detected!");
            e->index = 0;
            ofs = e->beg_offset;
        }

        fill = 0;

        if (e->sizes[e->index] > 0) {
            /* if there is another item on our way, wipe it out */
            p = e->index;

            while (fill < sizeof (ts) + len + 1) {
                fill += e->sizes[p];
                e->sizes[p] = 0;
                e->count--;
                buffer.items--;
                p++;
            }
        }

        e->sizes[e->index] = sizeof (ts) + len + 1;
        fseek (buffer.file, ofs+buffer.header_size, SEEK_SET);
        fwrite (&ts, sizeof (ts), 1, buffer.file);
        fwrite (value, len+1, 1, buffer.file);

        if (fill > 0) {
            fill -= e->sizes[e->index];
            fwrite (&zero, sizeof (unsigned char), fill, buffer.file);
            e->sizes[e->index] += fill;
        }

        e->index++;
        e->count++;
        e->index %= e->max_items;
        zabbix_log (LOG_LEVEL_DEBUG, "New item properties: index %d, count: %d, beg: %lu, end: %lu, ofs: %lu", 
		    e->index, e->count, e->beg_offset, e->max_offset, ofs);
        buffer.items++;
        break;
    }

    if (++flush_counter == FLUSH_EVERY_ITEMS)
        flush_buffer ();
}
Пример #12
0
static int read_initial_buffer ()
{
    unsigned long sig;
    unsigned int i, j, len;
    int index;
    char c;
    char buf[1024];

    zabbix_log (LOG_LEVEL_DEBUG, "read_initial_buffer");

    /* check signature */
    if (!fread (&sig, sizeof (sig), 1, buffer.file))
        return 0;

    if (sig != buffer_signature)
        return 0;

    if (fread (&buffer.size, sizeof (unsigned int), 1, buffer.file) != 1)
        return 0;

    if (!buffer.size)           /* read finished, there are no items in buffer */
        return 1;

    zabbix_log (LOG_LEVEL_DEBUG, "Reading %d items of history from buffer", buffer.size);

    buffer.entries = (buffer_check_entry_t*)calloc (buffer.size, sizeof (buffer_check_entry_t));

    if (!buffer.entries) {
	    buffer.size = 0;
	    return 1;
    }

    for (i = 0; i < buffer.size; i++) {
        buffer.entries[i].key = NULL;
        len = 0;
        while ((c = fgetc (buffer.file))) {
            buf[len++] = c;
            if (len == 1023) {
                buf[len] = 0;
                buffer.entries[i].key = zbx_strdcat (buffer.entries[i].key, buf);
                len = 0;
            }
        }

        if (len) {
            buf[len] = 0;
            buffer.entries[i].key = zbx_strdcat (buffer.entries[i].key, buf);
        }

        fread (&buffer.entries[i].refresh, sizeof (int), 1, buffer.file);
        fread (&buffer.entries[i].beg_offset, sizeof (size_t), 1, buffer.file);
        fread (&buffer.entries[i].max_offset, sizeof (size_t), 1, buffer.file);
        fread (&buffer.entries[i].max_items,  sizeof (int), 1, buffer.file);

        buffer.entries[i].sizes = (unsigned short*)malloc (buffer.entries[i].max_items * sizeof (unsigned short));
        fread (buffer.entries[i].sizes, sizeof (unsigned short), buffer.entries[i].max_items, buffer.file);

        /* find index (hm-hm) and item's count */
        index = -1;
        buffer.entries[i].count = 0;
        buffer.entries[i].index = 0;

        for (j = 0; j < buffer.entries[i].max_items; j++) {
            if (!buffer.entries[i].sizes[j]) {
                if (index < 0)
                    index = j;
            }
            else
                buffer.entries[i].count++;
        }

        if (index >= 0)
            buffer.entries[i].index = index;

        zabbix_log (LOG_LEVEL_DEBUG, "Read item history. Key %s, refresh %d, len: %lu, items: %d, index: %d, count: %d", buffer.entries[i].key, 
                    buffer.entries[i].refresh, buffer.entries[i].max_offset - buffer.entries[i].beg_offset, buffer.entries[i].max_items,
                    buffer.entries[i].index, buffer.entries[i].count);
    }

    return 1;
}
Пример #13
0
int	SYSTEM_HOSTNAME(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	DWORD	dwSize = 256;
	wchar_t	computerName[256];
	char	*type, buffer[256];
	int	netbios, rc;
	WSADATA sockInfo;

	if (1 < request->nparam)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		return SYSINFO_RET_FAIL;
	}

	type = get_rparam(request, 0);

	if (NULL == type || '\0' == *type || 0 == strcmp(type, "netbios"))
		netbios = 1;
	else if (0 == strcmp(type, "host"))
		netbios = 0;
	else
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
		return SYSINFO_RET_FAIL;
	}

	if (1 == netbios)
	{
		/* Buffer size is chosen large enough to contain any DNS name, not just MAX_COMPUTERNAME_LENGTH + 1 */
		/* characters. MAX_COMPUTERNAME_LENGTH is usually less than 32, but it varies among systems, so we  */
		/* cannot use the constant in a precompiled Windows agent, which is expected to work on any system. */
		if (0 == GetComputerName(computerName, &dwSize))
		{
			zabbix_log(LOG_LEVEL_ERR, "GetComputerName() failed: %s", strerror_from_system(GetLastError()));
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain computer name: %s",
					strerror_from_system(GetLastError())));
			return SYSINFO_RET_FAIL;
		}

		SET_STR_RESULT(result, zbx_unicode_to_utf8(computerName));
	}
	else
	{
		if (0 != (rc = WSAStartup(MAKEWORD(2, 2), &sockInfo)))
		{
			zabbix_log(LOG_LEVEL_ERR, "WSAStartup() failed: %s", strerror_from_system(rc));
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot initialize Winsock DLL: %s",
					strerror_from_system(rc)));
			return SYSINFO_RET_FAIL;
		}
		else if (SUCCEED != gethostname(buffer, sizeof(buffer)))
		{
			zabbix_log(LOG_LEVEL_ERR, "gethostname() failed: %s", strerror_from_system(WSAGetLastError()));
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain host name: %s",
					strerror_from_system(WSAGetLastError())));
			return SYSINFO_RET_FAIL;
		}

		SET_STR_RESULT(result, zbx_strdup(NULL, buffer));
	}

	return SYSINFO_RET_OK;
}
Пример #14
0
/******************************************************************************
 *                                                                            *
 * Comments: if the specified counter exists or a new is successfully         *
 *           added, a pointer to that counter is returned, NULL otherwise     *
 *                                                                            *
 ******************************************************************************/
PERF_COUNTER_DATA	*add_perf_counter(const char *name, const char *counterpath, int interval)
{
	const char		*__function_name = "add_perf_counter";
	PERF_COUNTER_DATA	*cptr;
	char			*alias_name;
	PDH_STATUS		pdh_status;
	int			result = FAIL;

	assert(counterpath);

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() counter:'%s' interval:%d", __function_name, counterpath, interval);

	if (SUCCEED != perf_collector_started())
	{
		zabbix_log(LOG_LEVEL_WARNING, "PerfCounter '%s' FAILED: collector is not started!", counterpath);
		return NULL;
	}

	if (1 > interval || 900 < interval)
	{
		zabbix_log(LOG_LEVEL_WARNING, "PerfCounter '%s' FAILED: interval value out of range", counterpath);
		return NULL;
	}

	for (cptr = ppsd.pPerfCounterList; ; cptr = cptr->next)
	{
		/* add new parameters */
		if (NULL == cptr)
		{
			cptr = (PERF_COUNTER_DATA *)zbx_malloc(cptr, sizeof(PERF_COUNTER_DATA));

			/* initialize the counter */
			memset(cptr, 0, sizeof(PERF_COUNTER_DATA));
			if (NULL != name)
				cptr->name = strdup(name);
			cptr->counterpath = strdup(counterpath);
			cptr->interval = interval;
			cptr->value_current = -1;
			cptr->value_array = (double *)zbx_malloc(cptr->value_array, sizeof(double) * interval);

			/* add the counter to the query */
			pdh_status = zbx_PdhAddCounter(__function_name, cptr, ppsd.pdh_query, counterpath, &cptr->handle);

			zbx_mutex_lock(&perfstat_access);
			cptr->next = ppsd.pPerfCounterList;
			ppsd.pPerfCounterList = cptr;
			zbx_mutex_unlock(&perfstat_access);

			if (ERROR_SUCCESS != pdh_status && PDH_CSTATUS_NO_INSTANCE != pdh_status)
			{
				zabbix_log(LOG_LEVEL_WARNING, "cannot add performance counter \"%s\": invalid format",
						counterpath);
				cptr = NULL;	/* indicate a failure */
			}

			result = SUCCEED;
			break;
		}

		if (NULL != name && 0 == strcmp(cptr->name, name))
			break;

		if (NULL == name && 0 == strcmp(cptr->counterpath, counterpath) && cptr->interval == interval)
			break;
	}

	if (FAIL == result)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s() counter '%s' already exists", __function_name, counterpath);
	}
	else if (NULL != name)
	{
		alias_name = zbx_dsprintf(NULL, "__UserPerfCounter[%s]", name);
		add_alias(name, alias_name);
		zbx_free(alias_name);
	}

	return cptr;
}
Пример #15
0
int	process_eventlog(const char *source, zbx_uint64_t *lastlogsize, unsigned long *out_timestamp,
                     char **out_source, unsigned short *out_severity, char **out_message,
                     unsigned long *out_eventid, unsigned char skip_old_data)
{
    const char	*__function_name = "process_eventlog";
    int		ret = FAIL;
    static HMODULE	hmod_wevtapi = NULL;
    HANDLE		eventlog_handle;
    LPTSTR		wsource;
    zbx_uint64_t	FirstID, LastID;
    register long	i;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() source:'%s' lastlogsize:" ZBX_FS_UI64,
               __function_name, source, *lastlogsize);

    *out_timestamp = 0;
    *out_source = NULL;
    *out_severity = 0;
    *out_message = NULL;
    *out_eventid = 0;

    if (NULL == source || '\0' == *source)
    {
        zabbix_log(LOG_LEVEL_WARNING, "cannot open eventlog with empty name");
        return ret;
    }

    wsource = zbx_utf8_to_unicode(source);

    if (SUCCEED == zbx_open_eventlog(wsource, &eventlog_handle,
                                     &LastID /* number */, &FirstID /* oldest */))
    {
        LastID += FirstID;

        if (1 == skip_old_data)
        {
            *lastlogsize = LastID - 1;
            zabbix_log(LOG_LEVEL_DEBUG, "skipping existing data: lastlogsize:" ZBX_FS_UI64, *lastlogsize);
        }

        if (*lastlogsize > LastID)
            *lastlogsize = FirstID;
        else if (*lastlogsize >= FirstID)
            FirstID = (long)*lastlogsize + 1;

        for (i = (long)FirstID; i < LastID; i++)
        {
            if (SUCCEED == zbx_get_eventlog_message(wsource, eventlog_handle, i, out_source, out_message,
                                                    out_severity, out_timestamp, out_eventid))
            {
                *lastlogsize = i;
                break;
            }
        }
        zbx_close_eventlog(eventlog_handle);

        ret = SUCCEED;
    }
    else
        zabbix_log(LOG_LEVEL_ERR, "cannot open eventlog '%s': %s", source,
                   strerror_from_system(GetLastError()));

    zbx_free(wsource);
    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

    return ret;
}
Пример #16
0
/******************************************************************************
 *                                                                            *
 * Function: recv_getqueue                                                    *
 *                                                                            *
 * Purpose: process queue request                                             *
 *                                                                            *
 * Parameters:  sock  - [IN] the request socket                               *
 *              jp    - [IN] the request data                                 *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 ******************************************************************************/
static int	recv_getqueue(zbx_socket_t *sock, struct zbx_json_parse *jp)
{
	const char		*__function_name = "recv_getqueue";
	int			ret = FAIL, request_type = -1, now, i;
	char			type[MAX_STRING_LEN], sessionid[MAX_STRING_LEN];
	zbx_vector_ptr_t	queue;
	struct zbx_json		json;
	zbx_hashset_t		queue_stats;
	zbx_queue_stats_t	*stats;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid)) ||
		FAIL == zbx_session_validate(sessionid, USER_TYPE_SUPER_ADMIN))
	{
		zbx_send_response_raw(sock, ret, "Permission denied.", CONFIG_TIMEOUT);
		goto out;
	}

	if (FAIL != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type)))
	{
		if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_OVERVIEW))
			request_type = ZBX_GET_QUEUE_OVERVIEW;
		else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_PROXY))
			request_type = ZBX_GET_QUEUE_PROXY;
		else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_DETAILS))
			request_type = ZBX_GET_QUEUE_DETAILS;
	}

	if (-1 == request_type)
	{
		zbx_send_response_raw(sock, ret, "Unsupported request type.", CONFIG_TIMEOUT);
		goto out;
	}

	now = time(NULL);
	zbx_vector_ptr_create(&queue);
	DCget_item_queue(&queue, 6, -1);

	zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN);

	switch (request_type)
	{
		case ZBX_GET_QUEUE_OVERVIEW:
			zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC,
					ZBX_DEFAULT_UINT64_COMPARE_FUNC);

			/* gather queue stats by item type */
			for (i = 0; i < queue.values_num; i++)
			{
				zbx_queue_item_t	*item = queue.values[i];
				zbx_uint64_t		id = item->type;

				if (NULL == (stats = zbx_hashset_search(&queue_stats, &id)))
				{
					zbx_queue_stats_t	data = {id};

					stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data));
				}
				queue_stats_update(stats, now - item->nextcheck);
			}

			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS,
					ZBX_JSON_TYPE_STRING);
			queue_stats_export(&queue_stats, "itemtype", &json);
			zbx_hashset_destroy(&queue_stats);

			break;
		case ZBX_GET_QUEUE_PROXY:
			zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC,
					ZBX_DEFAULT_UINT64_COMPARE_FUNC);

			/* gather queue stats by proxy hostid */
			for (i = 0; i < queue.values_num; i++)
			{
				zbx_queue_item_t	*item = queue.values[i];
				zbx_uint64_t		id = item->proxy_hostid;

				if (NULL == (stats = zbx_hashset_search(&queue_stats, &id)))
				{
					zbx_queue_stats_t	data = {id};

					stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data));
				}
				queue_stats_update(stats, now - item->nextcheck);
			}

			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS,
					ZBX_JSON_TYPE_STRING);
			queue_stats_export(&queue_stats, "proxyid", &json);
			zbx_hashset_destroy(&queue_stats);

			break;
		case ZBX_GET_QUEUE_DETAILS:
			zbx_vector_ptr_sort(&queue, (zbx_compare_func_t)queue_compare_by_nextcheck_asc);
			zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS,
					ZBX_JSON_TYPE_STRING);
			zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA);

			for (i = 0; i < queue.values_num && i <= 500; i++)
			{
				zbx_queue_item_t	*item = queue.values[i];

				zbx_json_addobject(&json, NULL);
				zbx_json_adduint64(&json, "itemid", item->itemid);
				zbx_json_adduint64(&json, "nextcheck", item->nextcheck);
				zbx_json_close(&json);
			}

			zbx_json_close(&json);

			break;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "%s() json.buffer:'%s'", __function_name, json.buffer);

	zbx_tcp_send_raw(sock, json.buffer);

	DCfree_item_queue(&queue);
	zbx_vector_ptr_destroy(&queue);

	zbx_json_free(&json);

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return ret;
}
Пример #17
0
/* open eventlog using API 6 and return the number of records */
static int zbx_open_eventlog6(LPCWSTR wsource, zbx_uint64_t *lastlogsize, EVT_HANDLE *render_context,
                              zbx_uint64_t *FirstID, zbx_uint64_t *LastID)
{
    const char	*__function_name = "zbx_open_eventlog6";
    EVT_HANDLE	log = NULL;
    EVT_VARIANT	var;
    EVT_HANDLE	tmp_all_event_query = NULL;
    EVT_HANDLE	event_bookmark = NULL;
    EVT_VARIANT*	renderedContent = NULL;
    DWORD		status = 0;
    DWORD		size_required = 0;
    DWORD		size = DEFAULT_EVENT_CONTENT_SIZE;
    DWORD		bookmarkedCount = 0;
    zbx_uint64_t	numIDs = 0;
    LPSTR		tmp_str = NULL;
    int		ret = FAIL;

    *FirstID = 0;
    *LastID = 0;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

    /* try to open the desired log */
    if (NULL == (log = EvtOpenLog(NULL, wsource, EvtOpenChannelPath)))
    {
        tmp_str = zbx_unicode_to_utf8(wsource);
        zabbix_log(LOG_LEVEL_WARNING, "cannot open eventlog '%s':%s", tmp_str,
                   strerror_from_system(GetLastError()));
        goto finish;
    }

    /* obtain the number of records in the log */
    if (TRUE != EvtGetLogInfo(log, EvtLogNumberOfLogRecords, sizeof(var), &var, &size_required))
    {
        zabbix_log(LOG_LEVEL_WARNING, "EvtGetLogInfo failed:%s",
                   strerror_from_system(GetLastError()));
        goto finish;
    }

    numIDs = var.UInt64Val;

    /* get the number of the oldest record in the log				*/
    /* "EvtGetLogInfo()" does not work properly with "EvtLogOldestRecordNumber"	*/
    /* we have to get it from the first EventRecordID				*/

    /* create the system render */
    if (NULL == (*render_context = EvtCreateRenderContext(RENDER_ITEMS_COUNT, RENDER_ITEMS, EvtRenderContextValues)))
    {
        zabbix_log(LOG_LEVEL_WARNING, "EvtCreateRenderContext failed:%s", strerror_from_system(GetLastError()));
        goto finish;
    }

    /* get all eventlog */
    tmp_all_event_query = EvtQuery(NULL, wsource, NULL, EvtQueryChannelPath);
    if (NULL == tmp_all_event_query)
    {
        if (ERROR_EVT_CHANNEL_NOT_FOUND == (status = GetLastError()))
            zabbix_log(LOG_LEVEL_WARNING, "EvtQuery channel missed:%s", strerror_from_system(status));
        else
            zabbix_log(LOG_LEVEL_WARNING, "EvtQuery failed:%s", strerror_from_system(status));

        goto finish;
    }

    /* get the entries and allocate the required space */
    renderedContent = zbx_malloc(renderedContent, size);
    if (TRUE != EvtNext(tmp_all_event_query, 1, &event_bookmark, INFINITE, 0, &size_required))
    {
        /* no data in eventlog */
        zabbix_log(LOG_LEVEL_DEBUG, "first EvtNext failed:%s", strerror_from_system(GetLastError()));
        *FirstID = 1;
        *LastID = 1;
        numIDs = 0;
        *lastlogsize = 0;
        ret = SUCCEED;
        goto finish;
    }

    /* obtain the information from selected events */
    if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
                          &size_required, &bookmarkedCount))
    {
        /* information exceeds the allocated space */
        if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
        {
            zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed:%s", strerror_from_system(GetLastError()));
            goto finish;
        }

        renderedContent = (EVT_VARIANT*)zbx_realloc((void *)renderedContent, size_required);
        size = size_required;

        if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
                              &size_required, &bookmarkedCount))
        {
            zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed:%s", strerror_from_system(GetLastError()));
            goto finish;
        }
    }

    *FirstID = VAR_RECORD_NUMBER(renderedContent);
    *LastID = *FirstID + numIDs;

    if (*lastlogsize >= *LastID)
    {
        *lastlogsize = *FirstID - 1;
        zabbix_log(LOG_LEVEL_DEBUG, "lastlogsize is too big. It is set to:" ZBX_FS_UI64, *lastlogsize);
    }
    ret = SUCCEED;

finish:
    if (NULL != log)
        EvtClose(log);
    if (NULL != tmp_all_event_query)
        EvtClose(tmp_all_event_query);
    if (NULL != event_bookmark)
        EvtClose(event_bookmark);
    zbx_free(tmp_str);
    zbx_free(renderedContent);
    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s FirstID:" ZBX_FS_UI64 " LastID:" ZBX_FS_UI64 " numIDs:" ZBX_FS_UI64,
               __function_name, zbx_result_string(ret), *FirstID, *LastID, numIDs);

    return ret;
}
Пример #18
0
static int	process_trap(zbx_socket_t *sock, char *s, zbx_timespec_t *ts)
{
	int	ret = SUCCEED;

	zbx_rtrim(s, " \r\n");

	zabbix_log(LOG_LEVEL_DEBUG, "trapper got '%s'", s);

	if ('{' == *s)	/* JSON protocol */
	{
		struct zbx_json_parse	jp;
		char			value[MAX_STRING_LEN];

		if (SUCCEED != zbx_json_open(s, &jp))
		{
			zbx_send_response(sock, FAIL, zbx_json_strerror(), CONFIG_TIMEOUT);
			zabbix_log(LOG_LEVEL_WARNING, "received invalid JSON object from %s: %s",
					sock->peer, zbx_json_strerror());
			return FAIL;
		}

		if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value)))
		{
			if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
				{
					send_proxyconfig(sock, &jp);
				}
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
				{
					zabbix_log(LOG_LEVEL_WARNING, "received configuration data from server"
							" at \"%s\", datalen " ZBX_FS_SIZE_T,
							sock->peer, (zbx_fs_size_t)(jp.end - jp.start + 1));
					recv_proxyconfig(sock, &jp);
				}
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_ACTIVE))
				{
					/* This is a misconfiguration: the proxy is configured in active mode */
					/* but server sends requests to it as to a proxy in passive mode. To  */
					/* prevent logging of this problem for every request we report it     */
					/* only when the server sends configuration to the proxy and ignore   */
					/* it for other requests.                                             */
					active_passive_misconfig(sock);
				}
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) ||
					0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA))
			{
				recv_agenthistory(sock, &jp, ts);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_proxyhistory(sock, &jp, ts);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_proxyhistory(sock, ts);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_discovery_data(sock, &jp);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_discovery_data(sock);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_areg_data(sock, &jp);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_areg_data(sock);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_proxy_heartbeat(sock, &jp);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS))
			{
				ret = send_list_of_active_checks_json(sock, &jp);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_HOST_AVAILABILITY))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					recv_host_availability(sock, &jp);
				else if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
					send_host_availability(sock);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND))
			{
				ret = node_process_command(sock, s, &jp);
			}
			else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_QUEUE))
			{
				if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER))
					ret = recv_getqueue(sock, &jp);
			}
			else
				zabbix_log(LOG_LEVEL_WARNING, "unknown request received [%s]", value);
		}
	}
	else if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21))	/* request for list of active checks */
	{
		ret = send_list_of_active_checks(sock, s);
	}
	else
	{
		char		value_dec[MAX_BUFFER_LEN], lastlogsize[ZBX_MAX_UINT64_LEN], timestamp[11],
				source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11];
		AGENT_VALUE	av;

		memset(&av, 0, sizeof(AGENT_VALUE));

		if ('<' == *s)	/* XML protocol */
		{
			comms_parse_response(s, av.host_name, sizeof(av.host_name), av.key, sizeof(av.key), value_dec,
					sizeof(value_dec), lastlogsize, sizeof(lastlogsize), timestamp,
					sizeof(timestamp), source, sizeof(source), severity, sizeof(severity));

			av.value = value_dec;
			if (SUCCEED != is_uint64(lastlogsize, &av.lastlogsize))
				av.lastlogsize = 0;
			av.timestamp = atoi(timestamp);
			av.source = source;
			av.severity = atoi(severity);
		}
		else
		{
			char	*pl, *pr;

			pl = s;
			if (NULL == (pr = strchr(pl, ':')))
				return FAIL;

			*pr = '\0';
			zbx_strlcpy(av.host_name, pl, sizeof(av.host_name));
			*pr = ':';

			pl = pr + 1;
			if (NULL == (pr = strchr(pl, ':')))
				return FAIL;

			*pr = '\0';
			zbx_strlcpy(av.key, pl, sizeof(av.key));
			*pr = ':';

			av.value = pr + 1;
			av.severity = 0;
		}

		zbx_timespec(&av.ts);

		if (0 == strcmp(av.value, ZBX_NOTSUPPORTED))
			av.state = ITEM_STATE_NOTSUPPORTED;

		process_mass_data(sock, 0, &av, 1, NULL);

		zbx_alarm_on(CONFIG_TIMEOUT);
		if (SUCCEED != zbx_tcp_send_raw(sock, "OK"))
			zabbix_log(LOG_LEVEL_WARNING, "Error sending result back");
		zbx_alarm_off();
	}

	return ret;
}
Пример #19
0
/* process eventlog with Windows API version 6 */
int	process_eventlog6(const char *source, zbx_uint64_t *lastlogsize, unsigned long *out_timestamp,
                      char **out_provider, char **out_source, unsigned short *out_severity, char **out_message,
                      unsigned long *out_eventid, zbx_uint64_t *FirstID, zbx_uint64_t *LastID, EVT_HANDLE *render_context,
                      EVT_HANDLE *query, zbx_uint64_t *keywords, unsigned char skip_old_data)
{
    const char	*__function_name = "process_eventlog6";
    zbx_uint64_t	i = 0;
    zbx_uint64_t	reading_startpoint = 0;
    LPWSTR		wsource = NULL;
    int		ret = FAIL;

    *out_timestamp	= 0;
    *out_provider	= NULL;
    *out_source	= NULL;
    *out_severity	= 0;
    *out_message	= NULL;
    *out_eventid	= 0;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() source: '%s' previous lastlogsize: " ZBX_FS_UI64 ", FirstID: "
               ZBX_FS_UI64 ", LastID: " ZBX_FS_UI64, __function_name, source, *lastlogsize, *FirstID,
               *LastID);

    wsource = zbx_utf8_to_unicode(source);

    /* update counters */
    if (1 == skip_old_data)
    {
        (*lastlogsize) = *LastID - 1;
        zabbix_log(LOG_LEVEL_DEBUG, "skipping existing data: lastlogsize:" ZBX_FS_UI64,
                   *lastlogsize);
        ret = SUCCEED;
        goto finish;
    }
    else if (*lastlogsize >= *FirstID && *lastlogsize < *LastID)
        reading_startpoint = (*lastlogsize) + 1;
    else
        reading_startpoint = *FirstID;

    if (reading_startpoint == *LastID)
    {
        ret = SUCCEED;
        goto finish;
    }

    /* cycle through the new records */
    for (i = reading_startpoint; i < *LastID; i++)
    {
        if (SUCCEED == zbx_get_eventlog_message6(wsource, &i, out_severity, out_timestamp, out_provider,
                out_source, out_message, out_eventid, render_context, query, keywords))
        {
            *lastlogsize = i;
            ret = SUCCEED;
            goto finish;
        }
    }

finish:
    zbx_free(wsource);
    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

    return ret;
}
Пример #20
0
int	zbx_module_nginx_status(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	char		*CONFIG_SOURCE_IP = NULL;	
	zbx_socket_t	s;
	char		*key;
	const char      *buf;
	int		ret = SYSINFO_RET_FAIL;
	int		find = 0;
	int		net_error = 0;
	char		r[MAX_STRING_LEN];

	zbx_uint64_t	ac = 0;    /* current number of active client connections */
	zbx_uint64_t	rd = 0;    /* current number of connections where nginx is reading the request header */
	zbx_uint64_t	wr = 0;    /* current number of connections where nginx is writing the response back to the client */
	zbx_uint64_t	wa = 0;    /* current number of idle client connections waiting for a request */

	if (request->nparam == 1)
	{
		key = get_rparam(request, 0);
	}
	else
	{
		/* set optional error message */
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters"));
		return ret;
	}

	/* for dev
	zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], request key:[%s]", key);
	*/

	if (SUCCEED == zbx_tcp_connect(&s, CONFIG_SOURCE_IP, CONFIG_NGINX_HOST, (unsigned short)CONFIG_NGINX_PORT, 0, ZBX_TCP_SEC_UNENCRYPTED, NULL, NULL))
	{
		/* for dev
		zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], connect to [%s:%d] successful", CONFIG_NGINX_HOST, CONFIG_NGINX_PORT);
		*/

		if (NULL == CONFIG_NGINX_DOMAIN)
		{
			zbx_snprintf(r, sizeof(r),
				"GET /%s HTTP/1.1\r\n"
				"Host: %s\r\n"
				"Connection: close\r\n"
				"\r\n",
				CONFIG_NGINX_STATUS_URI, CONFIG_NGINX_HOST);
		}
		else
		{
			zbx_snprintf(r, sizeof(r),
				"GET /%s HTTP/1.1\r\n"
				"Host: %s\r\n"
				"Connection: close\r\n"
				"\r\n",
				CONFIG_NGINX_STATUS_URI, CONFIG_NGINX_DOMAIN);
		}

		/* for dev
		zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], r:[%s]", r);
		*/

		if (SUCCEED == zbx_tcp_send_raw(&s, r))
		{
			/* for dev
			zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], send request successful");
			*/

			while (NULL != (buf = zbx_tcp_recv_line(&s)))
			{
				/* for dev
				zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], got [%s]", buf);
				*/

				if (0 == strcmp(key, "ac") && 0 == strncmp(buf, "Active connections", 18))
				{
					if(1 == sscanf(buf, "%*s" "%*s" ZBX_FS_UI64, &ac))
					{
						/* for dev
						zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], key:[%s] value:[%d]", key, ac);
						*/
						find = 1;
						SET_UI64_RESULT(result, ac);
						ret = SYSINFO_RET_OK;
					}
				}
				else if (0 == strcmp(key, "rd") && 3 == sscanf(buf, "%*s" ZBX_FS_UI64 "%*s" ZBX_FS_UI64 "%*s" ZBX_FS_UI64, &rd, &wr, &wa))
				{
					/* for dev
					zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], key:[%s] value:[%d]", key, rd);
					*/
					find = 1;
					SET_UI64_RESULT(result, rd);
					ret = SYSINFO_RET_OK;
				}
				else if (0 == strcmp(key, "wr") && 3 == sscanf(buf, "%*s" ZBX_FS_UI64 "%*s" ZBX_FS_UI64 "%*s" ZBX_FS_UI64, &rd, &wr, &wa))
				{
					/* for dev
					zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], key:[%s] value:[%d]", key, wr);
					*/
					find = 1;
					SET_UI64_RESULT(result, wr);
					ret = SYSINFO_RET_OK;
				}
				else if (0 == strcmp(key, "wa") && 3 == sscanf(buf, "%*s" ZBX_FS_UI64 "%*s" ZBX_FS_UI64 "%*s" ZBX_FS_UI64, &rd, &wr, &wa))
				{
					/* for dev
					zabbix_log(LOG_LEVEL_INFORMATION, "module [nginx], func [zbx_module_nginx_status], key:[%s] value:[%d]", key, wa);
					*/
					find = 1;
					SET_UI64_RESULT(result, wa);
					ret = SYSINFO_RET_OK;
				}

			}
		}
		else
		{
			net_error = 1;
			zabbix_log(LOG_LEVEL_WARNING, "module [nginx], func [zbx_module_nginx_status], get nginx status error: [%s]", zbx_socket_strerror());
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Get nginx status error [%s]", zbx_socket_strerror()));
		}

		zbx_tcp_close(&s);
	}
	else
	{
		net_error = 1;
		zabbix_log(LOG_LEVEL_WARNING, "module [nginx], func [zbx_module_nginx_status], get nginx status error: [%s]", zbx_socket_strerror());
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Get nginx status error [%s]", zbx_socket_strerror()));
	}

	if (1 != find && 0 == net_error)
	{
		zabbix_log(LOG_LEVEL_WARNING, "module [nginx], func [zbx_module_nginx_status], not supported key: [%s]", key);
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Not supported key [%s]", key));
	}

	return ret;
}
Пример #21
0
/******************************************************************************
 *                                                                            *
 * 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;
}
Пример #22
0
/******************************************************************************
 *                                                                            *
 * Function : process_history_table_data:                                     *
 *                                                                            *
 * Purpose: process new history data                                          *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Aleksander Vladishev                                               *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	process_history_table_data(ZBX_TABLE *table, int master_nodeid, int nodeid)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		*data = NULL, *tmp = NULL;
	int		data_allocated = 1024*1024, tmp_allocated = 4096, tmp_offset, data_offset, f, fld, len;
	int		data_found = 0;
	zbx_uint64_t	lastid;

	zabbix_log( LOG_LEVEL_DEBUG, "In process_history_table_data()");

	DBbegin();

	if ((table->flags & ZBX_HISTORY) && FAIL == get_history_lastid(master_nodeid, nodeid, table, &lastid))
		return;

	data = zbx_malloc(data, data_allocated);
	tmp = zbx_malloc(tmp, tmp_allocated);

	data_offset = 0;
	zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "History%c%d%c%d%c%s",
		ZBX_DM_DELIMITER, CONFIG_NODEID,
		ZBX_DM_DELIMITER, nodeid,
		ZBX_DM_DELIMITER, table->table);

	/* Do not send history for current node if CONFIG_NODE_NOHISTORY is set */
/*	if ((CONFIG_NODE_NOHISTORY != 0) && (CONFIG_NODEID == nodeid))
		goto exit;*/

	tmp_offset = 0;
	if (table->flags & ZBX_HISTORY_SYNC) {
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "select %s,",
			table->recid);
	} else { /* ZBX_HISTORY */
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 16, "select ");
	}

	for (f = 0; table->fields[f].name != 0; f++) {
		if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
			continue;

		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "%s,",
			table->fields[f].name);
	}
	tmp_offset--;

	if (table->flags & ZBX_HISTORY_SYNC) {
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where nodeid=%d order by %s",
			table->table,
			nodeid,
			table->recid);
	} else { /* ZBX_HISTORY */
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where %s>"ZBX_FS_UI64
			DB_NODE " order by %s",
			table->table,
			table->recid,
			lastid,
			DBnode(table->recid, nodeid),
			table->recid);
	}

	result = DBselectN(tmp, 10000);
	while (NULL != (row = DBfetch(result))) {
		if (table->flags & ZBX_HISTORY_SYNC) {
			ZBX_STR2UINT64(lastid, row[0]);
			fld = 1;
		} else
			fld = 0;

		zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n");

		for (f = 0; table->fields[f].name != 0; f++) {
			if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
				continue;

			len = (int)strlen(row[fld]);

			if (table->fields[f].type == ZBX_TYPE_INT ||
				table->fields[f].type == ZBX_TYPE_UINT ||
				table->fields[f].type == ZBX_TYPE_ID ||
				table->fields[f].type == ZBX_TYPE_FLOAT)
			{
				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%s%c",
					row[fld], ZBX_DM_DELIMITER);
			} else { /* ZBX_TYPE_CHAR ZBX_TYPE_BLOB ZBX_TYPE_TEXT */
				len = zbx_binary2hex((u_char *)row[fld], len, &tmp, &tmp_allocated);
				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, len + 8, "%s%c",
					tmp, ZBX_DM_DELIMITER);
			}
			fld++;
		}
		data_offset--;
		data_found = 1;
	}
	DBfree_result(result);

	data[data_offset] = '\0';

	if (1 == data_found && SUCCEED == send_to_node(table->table, master_nodeid, nodeid, data)) {
		if (table->flags & ZBX_HISTORY_SYNC) {
			DBexecute("delete from %s where nodeid=%d and %s<="ZBX_FS_UI64,
				table->table,
				nodeid,
				table->recid,
				lastid);
		}
	}

	DBcommit();

	zbx_free(tmp);
	zbx_free(data);
}
Пример #23
0
/******************************************************************************
 *                                                                            *
 * Function: process_value                                                    *
 *                                                                            *
 * Purpose: Buffer new value or send the whole buffer to the server           *
 *                                                                            *
 * Parameters: server      - IP or Hostname of Zabbix server                  *
 *             port        - port of Zabbix server                            *
 *             host        - name of host in Zabbix database                  *
 *             key         - name of metric                                   *
 *             value       - key value                                        *
 *             lastlogsize - size of read logfile                             *
 *             mtime       - time of last file modification                   *
 *             timestamp   - timestamp of read value                          *
 *             source      - name of logged data source                       *
 *             severity    - severity of logged data sources                  *
 *             logeventid  - the application-specific identifier for          *
 *                           the event; used for monitoring of Windows        *
 *                           event logs                                       *
 *             persistent  - do not overwrite old values                      *
 *                                                                            *
 * Return value: returns SUCCEED on successful parsing,                       *
 *               FAIL on other cases                                          *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	process_value(
		const char	*server,
		unsigned short	port,
		const char	*host,
		const char	*key,
		const char	*value,
		zbx_uint64_t	*lastlogsize,
		int		*mtime,
		unsigned long	*timestamp,
		const char	*source,
		unsigned short	*severity,
		unsigned long	*logeventid,
		unsigned char	persistent
)
{
	const char			*__function_name = "process_value";
	ZBX_ACTIVE_BUFFER_ELEMENT	*el = NULL;
	int				i, ret = FAIL;
	size_t				sz;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s:%s' value:'%s'", __function_name, host, key, value);

	send_buffer(server, port);

	if (0 != persistent && CONFIG_BUFFER_SIZE / 2 <= buffer.pcount)
	{
		zabbix_log(LOG_LEVEL_WARNING, "buffer is full, cannot store persistent value");
		goto out;
	}

	if (CONFIG_BUFFER_SIZE > buffer.count)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "buffer: new element %d", buffer.count);
		el = &buffer.data[buffer.count];
		buffer.count++;
	}
	else
	{
		if (0 == persistent)
		{
			for (i = 0; i < buffer.count; i++)
			{
				el = &buffer.data[i];
				if (0 == strcmp(el->host, host) && 0 == strcmp(el->key, key))
					break;
			}
		}

		if (0 != persistent || i == buffer.count)
		{
			for (i = 0; i < buffer.count; i++)
			{
				el = &buffer.data[i];
				if (0 == el->persistent)
					break;
			}
		}

		zabbix_log(LOG_LEVEL_DEBUG, "remove element [%d] Key:'%s:%s'", i, el->host, el->key);

		zbx_free(el->host);
		zbx_free(el->key);
		zbx_free(el->value);
		zbx_free(el->source);

		sz = (CONFIG_BUFFER_SIZE - i - 1) * sizeof(ZBX_ACTIVE_BUFFER_ELEMENT);
		memmove(&buffer.data[i], &buffer.data[i + 1], sz);

		zabbix_log(LOG_LEVEL_DEBUG, "buffer full: new element %d", buffer.count - 1);

		el = &buffer.data[CONFIG_BUFFER_SIZE - 1];
	}

	memset(el, 0, sizeof(ZBX_ACTIVE_BUFFER_ELEMENT));
	el->host = zbx_strdup(NULL, host);
	el->key = zbx_strdup(NULL, key);
	el->value = (NULL == value) ? NULL : zbx_strdup(NULL, value);

	if (NULL != source)
		el->source = strdup(source);
	if (NULL != severity)
		el->severity = *severity;
	if (NULL != lastlogsize)
		el->lastlogsize = *lastlogsize;
	if (NULL != mtime) /* will be null for "eventlog" and "log" and the value will be 0, only "logrt" matters */
		el->mtime = *mtime;
	if (NULL != timestamp)
		el->timestamp = *timestamp;
	if (NULL != logeventid)
		el->logeventid = (int)*logeventid;

	zbx_timespec(&el->ts);
	el->persistent	= persistent;

	if (0 != persistent)
		buffer.pcount++;

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #24
0
/******************************************************************************
 *                                                                            *
 * Function: diskstat_shm_extend                                              *
 *                                                                            *
 * Purpose: create a new, larger disk statistics shared memory segment and    *
 *          copy data from the old one.                                       *
 *                                                                            *
 ******************************************************************************/
void	diskstat_shm_extend()
{
#ifndef _WINDOWS
	const char		*__function_name = "diskstat_shm_extend";
	key_t			shm_key;
	size_t			old_shm_size, new_shm_size;
	int			old_shmid, new_shmid, old_max, new_max;
	ZBX_DISKDEVICES_DATA	*new_diskdevices;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	/* caclulate the size of the new shared memory segment */
	old_max = diskdevices->max_diskdev;

	if (old_max < 4)
		new_max = old_max + 1;
	else if (old_max < 256)
		new_max = old_max * 2;
	else
		new_max = old_max + 256;

	old_shm_size = sizeof(ZBX_DISKDEVICES_DATA) + sizeof(ZBX_SINGLE_DISKDEVICE_DATA) * (old_max - 1);
	new_shm_size = sizeof(ZBX_DISKDEVICES_DATA) + sizeof(ZBX_SINGLE_DISKDEVICE_DATA) * (new_max - 1);

	/* Create the new shared memory segment. The same key is used. */
	if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, ZBX_IPC_COLLECTOR_DISKSTAT)))
	{
		zabbix_log(LOG_LEVEL_CRIT, "cannot create IPC key for extending disk statistics collector");
		exit(EXIT_FAILURE);
	}

	/* zbx_shmget() will:                                                 */
	/*	- see that a shared memory segment with this key exists       */
	/*	- mark it for deletion                                        */
	/*	- create a new segment with this key, but with a different id */

	if (-1 == (new_shmid = zbx_shmget(shm_key, new_shm_size)))
	{
		zabbix_log(LOG_LEVEL_CRIT, "cannot allocate shared memory for extending disk statistics collector");
		exit(EXIT_FAILURE);
	}

	if ((void *)(-1) == (new_diskdevices = shmat(new_shmid, NULL, 0)))
	{
		zabbix_log(LOG_LEVEL_CRIT, "cannot attach shared memory for extending disk statistics collector: %s",
				zbx_strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* copy data from the old segment */
	memcpy(new_diskdevices, diskdevices, old_shm_size);
	new_diskdevices->max_diskdev = new_max;

	/* delete the old segment */
	if (-1 == shmdt((void *) diskdevices))
	{
		zabbix_log(LOG_LEVEL_CRIT, "cannot detach from disk statistics collector shared memory");
		exit(EXIT_FAILURE);
	}

	/* switch to the new segment */
	old_shmid = collector->diskstat_shmid;
	collector->diskstat_shmid = new_shmid;
	my_diskstat_shmid = collector->diskstat_shmid;
	diskdevices = new_diskdevices;

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s() extended diskstat shared memory: old_max:%d new_max:%d old_size:%d"
			" new_size:%d old_shmid:%d new_shmid:%d", __function_name, old_max, new_max, old_shm_size,
			new_shm_size, old_shmid, collector->diskstat_shmid);
#endif
}
Пример #25
0
int	process_eventlog(const char *source, long *lastlogsize, unsigned long *out_timestamp, char **out_source,
		unsigned short *out_severity, char **out_message, unsigned long	*out_eventid)
{
	const char	*__function_name = "process_eventlog";
	int		ret = FAIL;
	HANDLE		eventlog_handle;
	long		FirstID, LastID;
	register long	i;
	LPTSTR		wsource;

	assert(lastlogsize);
	assert(out_timestamp);
	assert(out_source);
	assert(out_severity);
	assert(out_message);
	assert(out_eventid);

	*out_timestamp	= 0;
	*out_source	= NULL;
	*out_severity	= 0;
	*out_message	= NULL;
	*out_eventid	= 0;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() source:'%s' lastlogsize:%ld",
			__function_name, source, *lastlogsize);

	if (NULL == source || '\0' == *source)
	{
		zabbix_log(LOG_LEVEL_WARNING, "Can't open eventlog with empty name");
		return ret;
	}

	wsource = zbx_utf8_to_unicode(source);

	if (SUCCEED == zbx_open_eventlog(wsource, &eventlog_handle, &LastID /* number */, &FirstID /* oldest */))
	{
		LastID += FirstID;

		if (*lastlogsize > LastID)
			*lastlogsize = FirstID;
		else if (*lastlogsize >= FirstID)
			FirstID = (*lastlogsize) + 1;

		for (i = FirstID; i < LastID; i++)
		{
			if (SUCCEED == zbx_get_eventlog_message(wsource, eventlog_handle, i, out_source, out_message,
					out_severity, out_timestamp, out_eventid))
			{
				*lastlogsize = i;
				break;
			}
		}
		zbx_close_eventlog(eventlog_handle);

		ret = SUCCEED;
	}
	else
		zabbix_log(LOG_LEVEL_ERR, "Can't open eventlog '%s' [%s]",
				source, strerror_from_system(GetLastError()));

	zbx_free(wsource);
	
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #26
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_get_cpu_num                                                  *
 *                                                                            *
 * Purpose: returns the number of processors which are currently online       *
 *          (i.e., available).                                                *
 *                                                                            *
 * Return value: number of CPUs                                               *
 *                                                                            *
 * Author: Eugene Grigorjev                                                   *
 *                                                                            *
 ******************************************************************************/
static int	zbx_get_cpu_num()
{
#if defined(_WINDOWS)
	SYSTEM_INFO	sysInfo;

	GetSystemInfo(&sysInfo);

	return (int)sysInfo.dwNumberOfProcessors;
#elif defined(HAVE_SYS_PSTAT_H)
	struct pst_dynamic	psd;

	if (-1 == pstat_getdynamic(&psd, sizeof(struct pst_dynamic), 1, 0))
		goto return_one;

	return (int)psd.psd_proc_cnt;
#elif defined(_SC_NPROCESSORS_CONF)
	/* FreeBSD 7.0 x86 */
	/* Solaris 10 x86 */
	int	ncpu;

	if (-1 == (ncpu = sysconf(_SC_NPROCESSORS_CONF)))
		goto return_one;

	return ncpu;
#elif defined(HAVE_FUNCTION_SYSCTL_HW_NCPU)
	/* FreeBSD 6.2 x86; FreeBSD 7.0 x86 */
	/* NetBSD 3.1 x86; NetBSD 4.0 x86 */
	/* OpenBSD 4.2 x86 */
	size_t	len;
	int	mib[] = {CTL_HW, HW_NCPU}, ncpu;

	len = sizeof(ncpu);

	if (0 != sysctl(mib, 2, &ncpu, &len, NULL, 0))
		goto return_one;

	return ncpu;
#elif defined(HAVE_PROC_CPUINFO)
	FILE	*f = NULL;
	int	ncpu = 0;

	if (NULL == (file = fopen("/proc/cpuinfo", "r")))
		goto return_one;

	while (NULL != fgets(line, 1024, file))
	{
		if (NULL == strstr(line, "processor"))
			continue;
		ncpu++;
	}
	zbx_fclose(file);

	if (0 == ncpu)
		goto return_one;

	return ncpu;
#elif defined(HAVE_LIBPERFSTAT)
	/* AIX 6.1 */
	perfstat_cpu_total_t	ps_cpu_total;

	if (-1 == perfstat_cpu_total(NULL, &ps_cpu_total, sizeof(ps_cpu_total), 1))
		goto return_one;

	return (int)ps_cpu_total.ncpus;
#endif

#ifndef _WINDOWS
return_one:
	zabbix_log(LOG_LEVEL_WARNING, "cannot determine number of CPUs, assuming 1");
	return 1;
#endif
}
Пример #27
0
static int	zbx_execute_script_on_terminal(DC_HOST *host, zbx_script_t *script, char **result,
		char *error, size_t max_error_len)
{
	const char	*__function_name = "zbx_execute_script_on_terminal";
	int		ret;
	AGENT_RESULT	agent_result;
	DC_ITEM		item;
	int             (*function)();

#ifdef HAVE_SSH2
	assert(ZBX_SCRIPT_TYPE_SSH == script->type || ZBX_SCRIPT_TYPE_TELNET == script->type);
#else
	assert(ZBX_SCRIPT_TYPE_TELNET == script->type);
#endif

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	*error = '\0';
	memset(&item, 0, sizeof(item));
	memcpy(&item.host, host, sizeof(item.host));

	if (SUCCEED != (ret = DCconfig_get_interface_by_type(&item.interface, host->hostid, INTERFACE_TYPE_AGENT)))
	{
		zbx_snprintf(error, max_error_len, "Zabbix agent interface is not defined for host [%s]", host->host);
		goto fail;
	}

	switch (script->type)
	{
		case ZBX_SCRIPT_TYPE_SSH:
			item.authtype = script->authtype;
			item.publickey = script->publickey;
			item.privatekey = script->privatekey;
			/* break; is not missing here */
		case ZBX_SCRIPT_TYPE_TELNET:
			item.username = script->username;
			item.password = script->password;
			break;
	}

	substitute_simple_macros(NULL, NULL, NULL, NULL, &host->hostid, NULL, NULL,
			&script->port, MACRO_TYPE_COMMON, NULL, 0);

	if ('\0' != *script->port && SUCCEED != (ret = is_ushort(script->port, NULL)))
	{
		zbx_snprintf(error, max_error_len, "Invalid port number [%s]", script->port);
		goto fail;
	}

#ifdef HAVE_SSH2
	if (ZBX_SCRIPT_TYPE_SSH == script->type)
	{
		item.key = zbx_dsprintf(item.key, "ssh.run[,,%s]", script->port);
		function = get_value_ssh;
	}
	else
	{
#endif
		item.key = zbx_dsprintf(item.key, "telnet.run[,,%s]", script->port);
		function = get_value_telnet;
#ifdef HAVE_SSH2
	}
#endif
	item.value_type = ITEM_VALUE_TYPE_TEXT;
	item.params = zbx_strdup(item.params, script->command);

	init_result(&agent_result);

	alarm(CONFIG_TIMEOUT);

	if (SUCCEED != (ret = function(&item, &agent_result)))
	{
		if (ISSET_MSG(&agent_result))
			zbx_strlcpy(error, agent_result.msg, max_error_len);
		ret = FAIL;
	}
	else if (NULL != result && ISSET_TEXT(&agent_result))
		*result = zbx_strdup(*result, agent_result.text);

	alarm(0);

	free_result(&agent_result);

	zbx_free(item.params);
	zbx_free(item.key);
fail:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Пример #28
0
/* get Nth error from event log. 1 is the first. */
static int	zbx_get_eventlog_message(LPCTSTR wsource, HANDLE eventlog_handle, long which, char **out_source,
                                     char **out_message, unsigned short *out_severity, unsigned long *out_timestamp,
                                     unsigned long *out_eventid)
{
    const char	*__function_name = "zbx_get_eventlog_message";
    int		buffer_size = 512;
    EVENTLOGRECORD	*pELR = NULL;
    DWORD		dwRead, dwNeeded, dwErr;
    LPTSTR		pEventMessageFile = NULL, pParamMessageFile = NULL, pFile = NULL, pNextFile = NULL, pCh,
                *pInsertStrings = NULL;
    HINSTANCE	hLib = NULL, hParamLib = NULL;
    long		i, err = 0;
    int		ret = FAIL;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%ld", __function_name, which);

    *out_source	= NULL;
    *out_message	= NULL;
    *out_severity	= 0;
    *out_timestamp	= 0;
    *out_eventid	= 0;

    pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size);

    while (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which,
                             pELR, buffer_size, &dwRead, &dwNeeded))
    {
        if (ERROR_INSUFFICIENT_BUFFER != (dwErr = GetLastError()))
        {
            zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr));
            goto out;
        }

        buffer_size = dwNeeded;
        pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size);
    }

    *out_severity	= pELR->EventType;			/* return event type */
    *out_timestamp	= pELR->TimeGenerated;			/* return timestamp */
    *out_eventid	= pELR->EventID & 0xffff;
    *out_source	= zbx_unicode_to_utf8((LPTSTR)(pELR + 1));	/* copy source name */

    /* get message file names */
    zbx_get_message_files(wsource, (LPTSTR)(pELR + 1), &pEventMessageFile, &pParamMessageFile);

    /* prepare insert string array */
    if (0 < pELR->NumStrings)
    {
        pInsertStrings = zbx_malloc(NULL, sizeof(LPWSTR) * pELR->NumStrings);

        pCh = (LPWSTR)((LPBYTE)pELR + pELR->StringOffset);

        for (i = 0; i < pELR->NumStrings; i++)
        {
            pInsertStrings[i] = pCh;
            pCh += zbx_strlen(pCh) + 1;
        }
    }

    err = FAIL;

    for (pFile = pEventMessageFile; NULL != pFile && err != SUCCEED; pFile = pNextFile)
    {
        if (NULL != (pNextFile = zbx_strchr(pFile, ';')))
        {
            *pNextFile = '\0';
            pNextFile++;
        }

        if (NULL != (hLib = zbx_load_message_file(pFile)))
        {
            if (NULL != (*out_message = zbx_format_message(hLib, pELR->EventID, pInsertStrings)))
            {
                err = SUCCEED;

                if (NULL != (hParamLib = zbx_load_message_file(pParamMessageFile)))
                {
                    zbx_translate_message_params(out_message, hParamLib);
                    FreeLibrary(hParamLib);
                }
            }

            FreeLibrary(hLib);
        }
    }

    zbx_free(pInsertStrings);

    zbx_free(pEventMessageFile);
    zbx_free(pParamMessageFile);

    if (SUCCEED != err)
    {
        *out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'"
                                    " cannot be found. The local computer may not have the necessary registry"
                                    " information or message DLL files to display messages from a remote computer.",
                                    *out_eventid, NULL == *out_source ? "" : *out_source);

        if (0 < pELR->NumStrings)
        {
            char	*buf;

            *out_message = zbx_strdcat(*out_message, " The following information is part of the event: ");

            for (i = 0, pCh = (LPWSTR)((LPBYTE)pELR + pELR->StringOffset);
                    i < pELR->NumStrings;
                    i++, pCh += zbx_strlen(pCh) + 1)
            {
                if (0 < i)
                    *out_message = zbx_strdcat(*out_message, "; ");

                buf = zbx_unicode_to_utf8(pCh);
                *out_message = zbx_strdcat(*out_message, buf);
                zbx_free(buf);
            }
        }
    }

    ret = SUCCEED;
out:
    zbx_free(pELR);

    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

    return ret;
}
Пример #29
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_set_defaults                                                 *
 *                                                                            *
 * Purpose: set configuration defaults                                        *
 *                                                                            *
 * Author: Rudolfs Kreicbergs                                                 *
 *                                                                            *
 ******************************************************************************/
static void	zbx_set_defaults()
{
	AGENT_RESULT	result;
	char		**value = NULL;

	CONFIG_SERVER_STARTUP_TIME = time(NULL);

	if (NULL == CONFIG_HOSTNAME)
	{
		if (NULL == CONFIG_HOSTNAME_ITEM)
			CONFIG_HOSTNAME_ITEM = zbx_strdup(CONFIG_HOSTNAME_ITEM, "system.hostname");

		init_result(&result);

		if (SUCCEED == process(CONFIG_HOSTNAME_ITEM, PROCESS_LOCAL_COMMAND, &result) &&
				NULL != (value = GET_STR_RESULT(&result)))
		{
			assert(*value);

			if (MAX_ZBX_HOSTNAME_LEN < strlen(*value))
			{
				(*value)[MAX_ZBX_HOSTNAME_LEN] = '\0';
				zabbix_log(LOG_LEVEL_WARNING, "proxy name truncated to [%s])", *value);
			}

			CONFIG_HOSTNAME = zbx_strdup(CONFIG_HOSTNAME, *value);
		}
		else
			zabbix_log(LOG_LEVEL_WARNING, "failed to get proxy name from [%s])", CONFIG_HOSTNAME_ITEM);

		free_result(&result);
	}
	else if (NULL != CONFIG_HOSTNAME_ITEM)
		zabbix_log(LOG_LEVEL_WARNING, "both Hostname and HostnameItem defined, using [%s]", CONFIG_HOSTNAME);

	if (NULL == CONFIG_DBHOST)
		CONFIG_DBHOST = zbx_strdup(CONFIG_DBHOST, "localhost");

	if (NULL == CONFIG_SNMPTRAP_FILE)
		CONFIG_SNMPTRAP_FILE = zbx_strdup(CONFIG_SNMPTRAP_FILE, "/tmp/zabbix_traps.tmp");

	if (NULL == CONFIG_PID_FILE)
		CONFIG_PID_FILE = zbx_strdup(CONFIG_PID_FILE, "/tmp/zabbix_proxy.pid");

	if (NULL == CONFIG_TMPDIR)
		CONFIG_TMPDIR = zbx_strdup(CONFIG_TMPDIR, "/tmp");

	if (NULL == CONFIG_FPING_LOCATION)
		CONFIG_FPING_LOCATION = zbx_strdup(CONFIG_FPING_LOCATION, "/usr/sbin/fping");

#ifdef HAVE_IPV6
	if (NULL == CONFIG_FPING6_LOCATION)
		CONFIG_FPING6_LOCATION = zbx_strdup(CONFIG_FPING6_LOCATION, "/usr/sbin/fping6");
#endif

	if (NULL == CONFIG_EXTERNALSCRIPTS)
		CONFIG_EXTERNALSCRIPTS = zbx_strdup(CONFIG_EXTERNALSCRIPTS, DATADIR "/zabbix/externalscripts");

	if (ZBX_PROXYMODE_ACTIVE != CONFIG_PROXYMODE || 0 == CONFIG_HEARTBEAT_FREQUENCY)
		CONFIG_HEARTBEAT_FORKS = 0;

	if (ZBX_PROXYMODE_PASSIVE == CONFIG_PROXYMODE)
	{
		CONFIG_CONFSYNCER_FORKS = CONFIG_DATASENDER_FORKS = 0;
		daemon_type = ZBX_DAEMON_TYPE_PROXY_PASSIVE;
	}
}
Пример #30
0
/*
 * returns interface statistics by IP address or interface name
 */
static int	get_if_stats(const char *if_name, MIB_IFROW *pIfRow)
{
    DWORD		dwSize, dwRetVal, i, j;
    int		ret = FAIL;
    char		ip[16];
    /* variables used for GetIfTable and GetIfEntry */
    MIB_IFTABLE	*pIfTable = NULL;
    /* variables used for GetIpAddrTable */
    MIB_IPADDRTABLE	*pIPAddrTable = NULL;
    IN_ADDR		in_addr;

    /* Allocate memory for our pointers. */
    dwSize = sizeof(MIB_IPADDRTABLE);
    pIPAddrTable = (MIB_IPADDRTABLE *)zbx_malloc(pIPAddrTable, sizeof(MIB_IPADDRTABLE));

    /* Make an initial call to GetIpAddrTable to get the
       necessary size into the dwSize variable */
    if (ERROR_INSUFFICIENT_BUFFER == GetIpAddrTable(pIPAddrTable, &dwSize, 0))
        pIPAddrTable = (MIB_IPADDRTABLE *)zbx_realloc(pIPAddrTable, dwSize);

    /* Make a second call to GetIpAddrTable to get the
       actual data we want */
    if (NO_ERROR != (dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)))
    {
        zabbix_log(LOG_LEVEL_DEBUG, "GetIpAddrTable failed with error: %s", strerror_from_system(dwRetVal));
        goto clean;
    }

    /* Allocate memory for our pointers. */
    dwSize = sizeof(MIB_IFTABLE);
    pIfTable = (MIB_IFTABLE *)zbx_malloc(pIfTable, dwSize);

    /* Before calling GetIfEntry, we call GetIfTable to make
       sure there are entries to get and retrieve the interface index.
       Make an initial call to GetIfTable to get the necessary size into dwSize */
    if (ERROR_INSUFFICIENT_BUFFER == GetIfTable(pIfTable, &dwSize, 0))
        pIfTable = (MIB_IFTABLE *)zbx_realloc(pIfTable, dwSize);

    /* Make a second call to GetIfTable to get the actual data we want. */
    if (NO_ERROR != (dwRetVal = GetIfTable(pIfTable, &dwSize, 0)))
    {
        zabbix_log(LOG_LEVEL_DEBUG, "GetIfTable failed with error: %s", strerror_from_system(dwRetVal));
        goto clean;
    }

    for (i = 0; i < pIfTable->dwNumEntries; i++)
    {
        LPSTR	utf8_descr;

        pIfRow->dwIndex = pIfTable->table[i].dwIndex;
        if (NO_ERROR != (dwRetVal = GetIfEntry(pIfRow)))
        {
            zabbix_log(LOG_LEVEL_DEBUG, "GetIfEntry failed with error: %s",
                       strerror_from_system(dwRetVal));
            continue;
        }

        utf8_descr = get_if_description(pIfRow);
        if (0 == strcmp(if_name, utf8_descr))
            ret = SUCCEED;
        zbx_free(utf8_descr);

        if (SUCCEED == ret)
            break;

        for (j = 0; j < pIPAddrTable->dwNumEntries; j++)
        {
            if (pIPAddrTable->table[j].dwIndex == pIfRow->dwIndex)
            {
                in_addr.S_un.S_addr = pIPAddrTable->table[j].dwAddr;
                zbx_snprintf(ip, sizeof(ip), "%s", inet_ntoa(in_addr));
                if (0 == strcmp(if_name, ip))
                {
                    ret = SUCCEED;
                    break;
                }
            }
        }

        if (SUCCEED == ret)
            break;
    }
clean:
    zbx_free(pIfTable);
    zbx_free(pIPAddrTable);

    return ret;
}