1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 
22 #include "db.h"
23 #include "log.h"
24 #include "daemon.h"
25 #include "zbxself.h"
26 
27 #include "httptest.h"
28 #include "httppoller.h"
29 
30 extern int		CONFIG_HTTPPOLLER_FORKS;
31 extern unsigned char	process_type, program_type;
32 extern int		server_num, process_num;
33 
34 /******************************************************************************
35  *                                                                            *
36  * Function: get_minnextcheck                                                 *
37  *                                                                            *
38  * Purpose: calculate when we have to process earliest httptest               *
39  *                                                                            *
40  * Parameters: now - current timestamp (not used)                             *
41  *                                                                            *
42  * Return value: timestamp of earliest check or -1 if not found               *
43  *                                                                            *
44  * Author: Alexei Vladishev                                                   *
45  *                                                                            *
46  * Comments:                                                                  *
47  *                                                                            *
48  ******************************************************************************/
get_minnextcheck(int now)49 static int	get_minnextcheck(int now)
50 {
51 	DB_RESULT	result;
52 	DB_ROW		row;
53 	int		res;
54 
55 	result = DBselect(
56 			"select min(t.nextcheck)"
57 			" from httptest t,hosts h"
58 			" where t.hostid=h.hostid"
59 				" and " ZBX_SQL_MOD(t.httptestid,%d) "=%d"
60 				" and t.status=%d"
61 				" and h.proxy_hostid is null"
62 				" and h.status=%d"
63 				" and (h.maintenance_status=%d or h.maintenance_type=%d)",
64 			CONFIG_HTTPPOLLER_FORKS, process_num - 1,
65 			HTTPTEST_STATUS_MONITORED,
66 			HOST_STATUS_MONITORED,
67 			HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL);
68 
69 	if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
70 	{
71 		zabbix_log(LOG_LEVEL_DEBUG, "No httptests to process in get_minnextcheck.");
72 		res = FAIL;
73 	}
74 	else
75 		res = atoi(row[0]);
76 
77 	DBfree_result(result);
78 
79 	return res;
80 }
81 
82 /******************************************************************************
83  *                                                                            *
84  * Function: main_httppoller_loop                                             *
85  *                                                                            *
86  * Purpose: main loop of processing of httptests                              *
87  *                                                                            *
88  * Parameters:                                                                *
89  *                                                                            *
90  * Return value:                                                              *
91  *                                                                            *
92  * Author: Alexei Vladishev                                                   *
93  *                                                                            *
94  * Comments: never returns                                                    *
95  *                                                                            *
96  ******************************************************************************/
ZBX_THREAD_ENTRY(httppoller_thread,args)97 ZBX_THREAD_ENTRY(httppoller_thread, args)
98 {
99 	int	now, nextcheck, sleeptime = -1, httptests_count = 0, old_httptests_count = 0;
100 	double	sec, total_sec = 0.0, old_total_sec = 0.0;
101 	time_t	last_stat_time;
102 
103 	process_type = ((zbx_thread_args_t *)args)->process_type;
104 	server_num = ((zbx_thread_args_t *)args)->server_num;
105 	process_num = ((zbx_thread_args_t *)args)->process_num;
106 
107 	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
108 			server_num, get_process_type_string(process_type), process_num);
109 
110 #define STAT_INTERVAL	5	/* if a process is busy and does not sleep then update status not faster than */
111 				/* once in STAT_INTERVAL seconds */
112 
113 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
114 	last_stat_time = time(NULL);
115 
116 	DBconnect(ZBX_DB_CONNECT_NORMAL);
117 
118 	for (;;)
119 	{
120 		zbx_handle_log();
121 
122 		if (0 != sleeptime)
123 		{
124 			zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, getting values]",
125 					get_process_type_string(process_type), process_num, old_httptests_count,
126 					old_total_sec);
127 		}
128 
129 		now = time(NULL);
130 		sec = zbx_time();
131 		httptests_count += process_httptests(process_num, now);
132 		total_sec += zbx_time() - sec;
133 
134 		nextcheck = get_minnextcheck(now);
135 		sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY);
136 
137 		if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time)
138 		{
139 			if (0 == sleeptime)
140 			{
141 				zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, getting values]",
142 						get_process_type_string(process_type), process_num, httptests_count,
143 						total_sec);
144 			}
145 			else
146 			{
147 				zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, idle %d sec]",
148 						get_process_type_string(process_type), process_num, httptests_count,
149 						total_sec, sleeptime);
150 				old_httptests_count = httptests_count;
151 				old_total_sec = total_sec;
152 			}
153 			httptests_count = 0;
154 			total_sec = 0.0;
155 			last_stat_time = time(NULL);
156 		}
157 
158 		zbx_sleep_loop(sleeptime);
159 
160 #if !defined(_WINDOWS) && defined(HAVE_RESOLV_H)
161 		zbx_update_resolver_conf();	/* handle /etc/resolv.conf update */
162 #endif
163 	}
164 
165 #undef STAT_INTERVAL
166 }
167