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  * Return value: timestamp of earliest check or -1 if not found               *
41  *                                                                            *
42  * Author: Alexei Vladishev                                                   *
43  *                                                                            *
44  ******************************************************************************/
get_minnextcheck(void)45 static int	get_minnextcheck(void)
46 {
47 	DB_RESULT	result;
48 	DB_ROW		row;
49 	int		res;
50 
51 	result = DBselect(
52 			"select min(t.nextcheck)"
53 			" from httptest t,hosts h"
54 			" where t.hostid=h.hostid"
55 				" and " ZBX_SQL_MOD(t.httptestid,%d) "=%d"
56 				" and t.status=%d"
57 				" and h.proxy_hostid is null"
58 				" and h.status=%d"
59 				" and (h.maintenance_status=%d or h.maintenance_type=%d)",
60 			CONFIG_HTTPPOLLER_FORKS, process_num - 1,
61 			HTTPTEST_STATUS_MONITORED,
62 			HOST_STATUS_MONITORED,
63 			HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL);
64 
65 	if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
66 	{
67 		zabbix_log(LOG_LEVEL_DEBUG, "No httptests to process in get_minnextcheck.");
68 		res = FAIL;
69 	}
70 	else
71 		res = atoi(row[0]);
72 
73 	DBfree_result(result);
74 
75 	return res;
76 }
77 
78 /******************************************************************************
79  *                                                                            *
80  * Function: main_httppoller_loop                                             *
81  *                                                                            *
82  * Purpose: main loop of processing of httptests                              *
83  *                                                                            *
84  * Parameters:                                                                *
85  *                                                                            *
86  * Return value:                                                              *
87  *                                                                            *
88  * Author: Alexei Vladishev                                                   *
89  *                                                                            *
90  * Comments: never returns                                                    *
91  *                                                                            *
92  ******************************************************************************/
ZBX_THREAD_ENTRY(httppoller_thread,args)93 ZBX_THREAD_ENTRY(httppoller_thread, args)
94 {
95 	int	now, nextcheck, sleeptime = -1, httptests_count = 0, old_httptests_count = 0;
96 	double	sec, total_sec = 0.0, old_total_sec = 0.0;
97 	time_t	last_stat_time;
98 
99 	process_type = ((zbx_thread_args_t *)args)->process_type;
100 	server_num = ((zbx_thread_args_t *)args)->server_num;
101 	process_num = ((zbx_thread_args_t *)args)->process_num;
102 
103 	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
104 			server_num, get_process_type_string(process_type), process_num);
105 
106 	update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
107 
108 #define STAT_INTERVAL	5	/* if a process is busy and does not sleep then update status not faster than */
109 				/* once in STAT_INTERVAL seconds */
110 
111 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
112 	last_stat_time = time(NULL);
113 
114 	DBconnect(ZBX_DB_CONNECT_NORMAL);
115 
116 	while (ZBX_IS_RUNNING())
117 	{
118 		sec = zbx_time();
119 		zbx_update_env(sec);
120 
121 		if (0 != sleeptime)
122 		{
123 			zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, getting values]",
124 					get_process_type_string(process_type), process_num, old_httptests_count,
125 					old_total_sec);
126 		}
127 
128 		now = time(NULL);
129 		httptests_count += process_httptests(process_num, now);
130 		total_sec += zbx_time() - sec;
131 
132 		nextcheck = get_minnextcheck();
133 		sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY);
134 
135 		if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time)
136 		{
137 			if (0 == sleeptime)
138 			{
139 				zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, getting values]",
140 						get_process_type_string(process_type), process_num, httptests_count,
141 						total_sec);
142 			}
143 			else
144 			{
145 				zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, idle %d sec]",
146 						get_process_type_string(process_type), process_num, httptests_count,
147 						total_sec, sleeptime);
148 				old_httptests_count = httptests_count;
149 				old_total_sec = total_sec;
150 			}
151 			httptests_count = 0;
152 			total_sec = 0.0;
153 			last_stat_time = time(NULL);
154 		}
155 
156 		zbx_sleep_loop(sleeptime);
157 	}
158 
159 	zbx_setproctitle("%s #%d [terminated]", get_process_type_string(process_type), process_num);
160 
161 	while (1)
162 		zbx_sleep(SEC_PER_MIN);
163 #undef STAT_INTERVAL
164 }
165