Esempio n. 1
0
int	regexp_match_ex(zbx_vector_ptr_t *regexps, const char *string, const char *pattern, int case_sensitive)
{
	return regexp_sub_ex(regexps, string, pattern, case_sensitive, NULL, NULL);
}
Esempio n. 2
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);
			}
		}