Browse Source

Starting stats collection implementation : request counter

Yann Weber 5 years ago
parent
commit
dffe441065
3 changed files with 135 additions and 2 deletions
  1. 63
    0
      include/stats.h
  2. 2
    2
      src/Makefile.am
  3. 70
    0
      src/stats.c

+ 63
- 0
include/stats.h View File

@@ -0,0 +1,63 @@
1
+/*
2
+ * Copyright (C) 2019 Weber Yann
3
+ * 
4
+ * This file is part of PyFCGI.
5
+ * 
6
+ * PyFCGI is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU Affero General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * any later version.
10
+ * 
11
+ * PyFCGI is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU Affero General Public License for more details.
15
+ * 
16
+ * You should have received a copy of the GNU Affero General Public License
17
+ * along with PyFCGI.  If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+/**@file stats.h
20
+ * @ingroup monitoring */
21
+#ifndef _STATS__H___
22
+#define _STATS__H___
23
+#include "config.h"
24
+
25
+#include <fcgiapp.h>
26
+
27
+#include <signal.h>
28
+#include <string.h>
29
+
30
+typedef struct pyfcgi_stats_s pyfcgi_stats_t;
31
+
32
+#include "conf.h"
33
+#include "logger.h"
34
+
35
+struct pyfcgi_stats_s
36
+{
37
+	/**@brief Request per seconds on 15 minutes */
38
+	int reqs[900];
39
+	/**@brief Current request index */
40
+	int cur_req;
41
+
42
+	/**@brief Repeating 1s timer sending SIGALRM */
43
+	timer_t timerid;
44
+
45
+	/**@brief Old SIGALRM handler */
46
+	struct sigaction oldact;
47
+};
48
+
49
+/**@brief Starts collecting statistics
50
+ *
51
+ * Set an handler for SIGALRM and set a repeating alarm each seconds
52
+ * @warning designed to be called from monitor server process
53
+ * @return -1 on error else 0
54
+ */
55
+int pyfcgi_stats_init();
56
+
57
+/**@brief SIGALRM signal handler
58
+ * @param int signum
59
+ */
60
+void pyfcgi_stats_collector(int);
61
+
62
+#endif
63
+

+ 2
- 2
src/Makefile.am View File

@@ -6,13 +6,13 @@ pyfcgi_LDADD = $(PYTHON_LDFLAGS)
6 6
 
7 7
 # libpyfcgi python module
8 8
 lib_LTLIBRARIES = libpyfcgi.la
9
-libpyfcgi_la_SOURCES = python_pyfcgi.c python_ioin.c ipc.c monitor.c
9
+libpyfcgi_la_SOURCES = python_pyfcgi.c python_ioin.c ipc.c monitor.c stats.c
10 10
 libpyfcgi_la_CFLAGS = $(PYTHON_SO_CFLAGS) $(AM_CFLAGS)
11 11
 libpyfcgi_la_LDFLAGS = $(PYTHON_SO_LDFLAGS)
12 12
 
13 13
 # static librarie for check
14 14
 noinst_LIBRARIES = libpyfcgi.a
15
-libpyfcgi_a_SOURCES = logger.c pyworker.c responder.c conf.c pyutils.c python_pyfcgi.c python_ioin.c ipc.c monitor.c
15
+libpyfcgi_a_SOURCES = logger.c pyworker.c responder.c conf.c pyutils.c python_pyfcgi.c python_ioin.c ipc.c monitor.c stats.c
16 16
 libpyfcgi_a_CFLAGS = $(PYTHON_CFLAGS) $(AM_CFLAGS)
17 17
 
18 18
 

+ 70
- 0
src/stats.c View File

@@ -0,0 +1,70 @@
1
+#include "stats.h"
2
+
3
+static pyfcgi_stats_t pyfcgi_stats;
4
+
5
+int pyfcgi_stats_init()
6
+{
7
+	struct sigaction act;
8
+	struct itimerspec timeout;
9
+
10
+	memset(&pyfcgi_stats, 0, sizeof(pyfcgi_stats_t));
11
+
12
+	if(timer_create(CLOCK_REALTIME, NULL, &(pyfcgi_stats.timerid)) < 0)
13
+	{
14
+		pyfcgi_log(LOG_ERR,
15
+			"Unable to create timer for stats collecting : %s",
16
+			strerror(errno));
17
+		goto err;
18
+	}
19
+
20
+	act.sa_handler = pyfcgi_stats_collector;
21
+	sigemptyset(&act.sa_mask);
22
+	act.sa_flags = 0;
23
+	act.sa_restorer = NULL;
24
+	if(sigaction(SIGALRM, &act, &(pyfcgi_stats.oldact)) < 0)
25
+	{
26
+		pyfcgi_log(LOG_ERR,
27
+			"Unable to register signal handler for stats collecting : %s",
28
+			strerror(errno));
29
+		goto err_deltimer;
30
+	}
31
+
32
+	timeout.it_value.tv_sec = 1;
33
+	timeout.it_value.tv_nsec = 0;
34
+	timeout.it_interval = timeout.it_value;
35
+	if(timer_settime(pyfcgi_stats.timerid, 0, &timeout, NULL) < 0)
36
+	{
37
+		pyfcgi_log(LOG_ERR,
38
+			"Unable to start timer for stats collecting : %s",
39
+			strerror(errno));
40
+		goto err_sigrestore;
41
+	}
42
+	return 0;
43
+
44
+err_sigrestore:
45
+	sigaction(SIGALRM, &(pyfcgi_stats.oldact), NULL);
46
+err_deltimer:
47
+	timer_delete(pyfcgi_stats.timerid);
48
+err:
49
+	memset(&pyfcgi_stats, 0, sizeof(pyfcgi_stats_t));
50
+	return -1;
51
+}
52
+
53
+void pyfcgi_stats_collector(int signum)
54
+{
55
+	int ret;
56
+	pyfcgi_stats_t *stats;
57
+
58
+	stats = &pyfcgi_stats;
59
+
60
+	stats->reqs[stats->cur_req] = 0;
61
+	while( !(ret = sem_trywait(PyFCGI_SEM(SEM_WREQS).sem)) )
62
+	{
63
+		stats->reqs[stats->cur_req]++;
64
+	}
65
+	pyfcgi_log(LOG_DEBUG, "%d req/s", stats->reqs[stats->cur_req]);
66
+	stats->cur_req++;
67
+
68
+	return;
69
+}
70
+

Loading…
Cancel
Save