diff --git a/deps/Makefile b/deps/Makefile
index 28b4a566e..4b198e70b 100644
--- a/deps/Makefile
+++ b/deps/Makefile
@@ -20,7 +20,7 @@ endif
libmicrohttpd/libmicrohttpd/src/microhttpd/.libs/libmicrohttpd.a:
cd libmicrohttpd && rm -rf libmicrohttpd-0.9.55 || true
cd libmicrohttpd && tar -zxf libmicrohttpd-0.9.55.tar.gz
- cd libmicrohttpd/libmicrohttpd && ./configure && CC=${CC} CXX=${CXX} ${MAKE}
+ cd libmicrohttpd/libmicrohttpd && ./configure --disable-https && CC=${CC} CXX=${CXX} ${MAKE}
microhttpd: libmicrohttpd/libmicrohttpd/src/microhttpd/.libs/libmicrohttpd.a
cityhash/cityhash/src/.libs/libcityhash.a:
diff --git a/include/ProxySQL_Statistics.hpp b/include/ProxySQL_Statistics.hpp
index e86751790..7eaf40cf9 100644
--- a/include/ProxySQL_Statistics.hpp
+++ b/include/ProxySQL_Statistics.hpp
@@ -55,9 +55,9 @@ class ProxySQL_Statistics {
void MySQL_Threads_Handler_sets(SQLite3_result *);
void system_cpu_sets();
void system_memory_sets();
- SQLite3_result * get_mysql_metrics();
- SQLite3_result * get_system_cpu_metrics();
- SQLite3_result * get_system_memory_metrics();
+ SQLite3_result * get_mysql_metrics(int interval);
+ SQLite3_result * get_system_cpu_metrics(int interval);
+ SQLite3_result * get_system_memory_metrics(int interval);
};
#endif /* CLASS_PROXYSQL_STATISTICS_H */
diff --git a/lib/Makefile b/lib/Makefile
index 3c58b5489..cf2b61a29 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -73,7 +73,7 @@ default: libproxysql.a
_OBJ = c_tokenizer.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
-_OBJ_CXX = ProxySQL_GloVars.oo network.oo debug.oo configfile.oo Query_Cache.oo SpookyV2.oo MySQL_Authentication.oo gen_utils.oo sqlite3db.oo mysql_connection.oo MySQL_HostGroups_Manager.oo mysql_data_stream.oo MySQL_Thread.oo MySQL_Session.oo MySQL_Protocol.oo mysql_backend.oo Query_Processor.oo ProxySQL_Admin.oo MySQL_Monitor.oo MySQL_Logger.oo thread.oo MySQL_PreparedStatement.oo ProxySQL_Cluster.oo SQLite3_Server.oo ClickHouse_Authentication.oo ClickHouse_Server.oo ProxySQL_Statistics.oo Chart_bundle_js.oo ProxySQL_HTTP_Server.oo
+_OBJ_CXX = ProxySQL_GloVars.oo network.oo debug.oo configfile.oo Query_Cache.oo SpookyV2.oo MySQL_Authentication.oo gen_utils.oo sqlite3db.oo mysql_connection.oo MySQL_HostGroups_Manager.oo mysql_data_stream.oo MySQL_Thread.oo MySQL_Session.oo MySQL_Protocol.oo mysql_backend.oo Query_Processor.oo ProxySQL_Admin.oo MySQL_Monitor.oo MySQL_Logger.oo thread.oo MySQL_PreparedStatement.oo ProxySQL_Cluster.oo SQLite3_Server.oo ClickHouse_Authentication.oo ClickHouse_Server.oo ProxySQL_Statistics.oo Chart_bundle_js.oo ProxySQL_HTTP_Server.oo font-awesome.min.css.oo
OBJ_CXX = $(patsubst %,$(ODIR)/%,$(_OBJ_CXX))
%.ko: %.cpp
diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp
index 641bc1476..3ac37ecc9 100644
--- a/lib/ProxySQL_Admin.cpp
+++ b/lib/ProxySQL_Admin.cpp
@@ -40,6 +40,7 @@
#define READ_ONLY_ON "\x01\x00\x00\x01\x02\x23\x00\x00\x02\x03\x64\x65\x66\x00\x00\x00\x0d\x56\x61\x72\x69\x61\x62\x6c\x65\x5f\x6e\x61\x6d\x65\x00\x0c\x21\x00\x0f\x00\x00\x00\xfd\x01\x00\x1f\x00\x00\x1b\x00\x00\x03\x03\x64\x65\x66\x00\x00\x00\x05\x56\x61\x6c\x75\x65\x00\x0c\x21\x00\x0f\x00\x00\x00\xfd\x01\x00\x1f\x00\x00\x05\x00\x00\x04\xfe\x00\x00\x02\x00\x0d\x00\x00\x05\x09\x72\x65\x61\x64\x5f\x6f\x6e\x6c\x79\x02\x4f\x4e\x05\x00\x00\x06\xfe\x00\x00\x02\x00"
+
struct MHD_Daemon *Admin_HTTP_Server;
extern ProxySQL_Statistics *GloProxyStats;
@@ -3718,7 +3719,10 @@ void ProxySQL_Admin::flush_admin_variables___database_to_runtime(SQLite3DB *db,
Admin_HTTP_Server = MHD_start_daemon(MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
variables.web_port,
NULL, NULL, http_handler, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_STRICT_FOR_CLIENT, (int) 1, MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 4,
+ MHD_OPTION_NONCE_NC_SIZE, (unsigned int) 300,
+ MHD_OPTION_END);
} else {
MHD_stop_daemon(Admin_HTTP_Server);
Admin_HTTP_Server = NULL;
@@ -3732,7 +3736,10 @@ void ProxySQL_Admin::flush_admin_variables___database_to_runtime(SQLite3DB *db,
Admin_HTTP_Server = MHD_start_daemon(MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
variables.web_port,
NULL, NULL, http_handler, NULL,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_STRICT_FOR_CLIENT, (int) 1, MHD_OPTION_END);
+ MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) 4,
+ MHD_OPTION_NONCE_NC_SIZE, (unsigned int) 300,
+ MHD_OPTION_END);
}
variables.web_port_old = variables.web_port;
}
diff --git a/lib/ProxySQL_HTTP_Server.cpp b/lib/ProxySQL_HTTP_Server.cpp
index 747dc4e39..1b45f472d 100644
--- a/lib/ProxySQL_HTTP_Server.cpp
+++ b/lib/ProxySQL_HTTP_Server.cpp
@@ -40,9 +40,120 @@
extern ProxySQL_Statistics *GloProxyStats;
extern char * Chart_bundle_js_c;
+extern char * font_awesome;
#define RATE_LIMIT_PAGE "
Rate Limit PageRate Limit Reached"
+#define DENIED "ProxySQL status pageAccess denied"
+#define OPAQUE "733b20011778ce330631c9afof70a870baddd964"
+
+
+
+static char *div1= (char *)"\n");
+// html.append(div1); html.append(base); html.append("&interval=7200"); html.append(style1); html.append("Last 2 hours\n");
+// html.append(div1); html.append(base); html.append("&interval=28800"); html.append(style1); html.append("Last 8 hours\n");
+
+ html.append("\n\nCategory:
\n");
+
+ html.append("\n");
+ html.append(div1); html.append("system"); html.append(style2); html.append("System\n");
+ html.append(div1); html.append("mysql"); html.append(style2); html.append("MySQL\n");
+ html.append(div1); html.append("cache"); html.append(style2); html.append("Query Cache\n");
+
+ html.append("\n\n");
+
+ html.append("\n");
+ html.append("\n");
+ html.append("
\n");
+ html.append("
\n");
+ html.append("
General information
\n
\n");
+ html.append("
\n");
+ html.append("\n");
+ //html.append("| \n");
+ html.append(" | \n");
+ html.append("Uptime = 0d 0h00m44s \n");
+ html.append("OS version = CentOS 7.3 \n");
+ html.append("Worker threads = 8 \n");
+ html.append("Idle threads = enabled \n");
+ html.append("Monitor = enabled \n");
+ html.append(" | \n");
+ html.append("\n");
+ html.append("ProxySQL version = 1.4.3 \n");
+ html.append("ProxySQL latest = 1.4.4 \n");
+ html.append(" | \n");
+ html.append("\n");
+ //html.append(" | \n");
+ html.append("ProxySQL version = 1.4.3 \n");
+ html.append("ProxySQL latest = 1.4.4 \n");
+ html.append(" | \n");
+ html.append("
\n");
+ html.append("
\n");
+ html.append("
\n");
+ s = strdup(html.c_str());
+ return s;
+}
+
+static char *generate_buttons(char *base) {
+ char *s = NULL;
+ //char *style = (char *)"style=\"color: white ; background-color: blue; font-size: 14px; border: 2px solid; border-radius: 5px; text-decoration: none; padding-left: 5px; padding-right: 5px;\"";
+ string html = "\n");
+ html.append(div1); html.append(base); html.append("&interval=3600"); html.append(style1); html.append("Last 1 hour\n");
+ html.append(div1); html.append(base); html.append("&interval=7200"); html.append(style1); html.append("Last 2 hours\n");
+ html.append(div1); html.append(base); html.append("&interval=28800"); html.append(style1); html.append("Last 8 hours\n");
+
+ html.append("\n\nTime range:
\n");
+
+ html.append(div1); html.append(base); html.append("&interval=86400"); html.append(style1); html.append("Last 1 day\n");
+ html.append(div1); html.append(base); html.append("&interval=259200"); html.append(style1); html.append("Last 3 days\n");
+ html.append(div1); html.append(base); html.append("&interval=604800"); html.append(style1); html.append("Last 7 days\n");
+ html.append(div1); html.append(base); html.append("&interval=2592000"); html.append(style1); html.append("Last 1 month\n");
+ html.append(div1); html.append(base); html.append("&interval=7776000"); html.append(style1); html.append("Last 3 months\n");
+
+ html.append("\n\n");
+ html.append("\n");
+// html.append(div1); html.append(base); html.append("&interval=3600"); html.append(style1); html.append("Last 1 hour\n");
+// html.append(div1); html.append(base); html.append("&interval=7200"); html.append(style1); html.append("Last 2 hours\n");
+// html.append(div1); html.append(base); html.append("&interval=28800"); html.append(style1); html.append("Last 8 hours\n");
+
+ html.append("\n\nCategory:
\n");
+
+ html.append("\n");
+ html.append(div1); html.append("system"); html.append(style2); html.append("System\n");
+ html.append(div1); html.append("mysql"); html.append(style2); html.append("MySQL\n");
+ html.append(div1); html.append("cache"); html.append(style2); html.append("Query Cache\n");
+
+ html.append("\n\n");
+
+
+/*
+ html.append("30mins");
+ html.append("60mins");
+ html.append("120mins");
+ html.append("8hrs");
+ html.append("24hrs");
+ html.append("72hrs");
+ html.append("7days");
+ html.append("30days");
+ html.append("90days");
+*/
+ s = strdup(html.c_str());
+ return s;
+}
+
char * ProxySQL_HTTP_Server::extract_values(SQLite3_result *result, int idx, bool relative, double mult) {
string s = "[";
@@ -102,9 +213,39 @@ int ProxySQL_HTTP_Server::handler(void *cls, struct MHD_Connection *connection,
struct MHD_Response *response;
int ret;
+
+
+ char *username;
+ const char *password = "testpass";
+ const char *realm = "Access to ProxySQL status page";
+
+ username = MHD_digest_auth_get_username(connection);
+ if (username == NULL || strcmp(username,"stats")) {
+ response = MHD_create_response_from_buffer(strlen(DENIED), (void *)DENIED, MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_auth_fail_response(connection, realm, OPAQUE, response, MHD_NO);
+ MHD_destroy_response(response);
+ return ret;
+ }
+ ret = MHD_digest_auth_check(connection, realm, username, password, 300);
+ free(username);
+ if ( (ret == MHD_INVALID_NONCE) || (ret == MHD_NO) ) {
+ response = MHD_create_response_from_buffer(strlen(DENIED), (void *)DENIED, MHD_RESPMEM_PERSISTENT);
+ if (NULL == response)
+ return MHD_NO;
+ ret = MHD_queue_auth_fail_response(connection, realm, OPAQUE, response, (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
+ MHD_destroy_response(response);
+ return ret;
+ }
+
+
+
+
+
char *valmetric = NULL;
char *valinterval = NULL;
char *valunit = NULL;
+ char *interval_s = NULL;
+ int interval_i = 1800;
time_t now = time(NULL);
if (now != cur_time) {
@@ -130,14 +271,33 @@ int ProxySQL_HTTP_Server::handler(void *cls, struct MHD_Connection *connection,
if (strcmp(url,"/stats")==0) {
valmetric = (char *)MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, (char *)"metric");
+/*
valinterval = (char *)MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, (char *)"points");
valunit = (char *)MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, (char *)"unit");
+*/
+ interval_s = (char *)MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, (char *)"interval");
+ //fprintf(stderr,"Interval = %s\n", interval_s);
if (valmetric == NULL) {
response = MHD_create_response_from_buffer (strlen (EMPTY_PAGE), (void *) EMPTY_PAGE, MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
MHD_destroy_response (response);
return ret;
}
+ int tmp_ = 0;
+ if (interval_s) {
+ tmp_ = atoi(interval_s);
+ }
+ switch (tmp_) {
+ case 1800:
+ case 3600:
+ case 7200:
+ case 28800:
+ interval_i = tmp_;
+ break;
+ default:
+ break;
+ }
+/*
if (valunit == NULL) {
valunit = (char *)"second";
}
@@ -158,19 +318,27 @@ int ProxySQL_HTTP_Server::handler(void *cls, struct MHD_Connection *connection,
valinterval = (char *)"365";
}
}
-
+*/
if (strcmp(valmetric,"system")==0) {
string *s = generate_header((char *)"ProxySQL Graphs");
+ char *buttons = generate_buttons((char *)"system");
+ s->append(buttons);
+ free(buttons);
+ s->append("\n");
string *s1 = generate_canvas((char *)"myChart1");
s->append(s1->c_str());
+ s->append("
\n");
s1 = generate_canvas((char *)"myChart2");
s->append(s1->c_str());
+ s->append("
\n");
s1 = generate_canvas((char *)"myChart3");
s->append(s1->c_str());
+ s->append("
\n");
s1 = generate_canvas((char *)"myChart4");
s->append(s1->c_str());
- SQLite3_result *cpu_sqlite = GloProxyStats->get_system_cpu_metrics();
- SQLite3_result *memory_sqlite = GloProxyStats->get_system_memory_metrics();
+ s->append("
\n");
+ SQLite3_result *cpu_sqlite = GloProxyStats->get_system_cpu_metrics(interval_i);
+ SQLite3_result *memory_sqlite = GloProxyStats->get_system_memory_metrics(interval_i);
//SQLite3_result *mysql_metrics_sqlite = GloProxyStats->get_mysql_metrics();
char **nm = NULL;
char **nl = NULL;
@@ -237,17 +405,25 @@ int ProxySQL_HTTP_Server::handler(void *cls, struct MHD_Connection *connection,
if (strcmp(valmetric,"mysql")==0) {
string *s = generate_header((char *)"ProxySQL Graphs");
+ char *buttons = generate_buttons((char *)"mysql");
+ s->append(buttons);
+ free(buttons);
+ s->append("\n");
string *s1 = generate_canvas((char *)"myChart1");
s->append(s1->c_str());
+ s->append("
\n");
s1 = generate_canvas((char *)"myChart2");
s->append(s1->c_str());
+ s->append("
\n");
s1 = generate_canvas((char *)"myChart3");
s->append(s1->c_str());
+ s->append("
\n");
s1 = generate_canvas((char *)"myChart4");
s->append(s1->c_str());
+ s->append("
\n");
//SQLite3_result *cpu_sqlite = GloProxyStats->get_system_cpu_metrics();
//SQLite3_result *memory_sqlite = GloProxyStats->get_system_memory_metrics();
- SQLite3_result *mysql_metrics_sqlite = GloProxyStats->get_mysql_metrics();
+ SQLite3_result *mysql_metrics_sqlite = GloProxyStats->get_mysql_metrics(interval_i);
char **nm = NULL;
char **nl = NULL;
char **nv = NULL;
@@ -315,7 +491,7 @@ int ProxySQL_HTTP_Server::handler(void *cls, struct MHD_Connection *connection,
free(ts);
s->append("