diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index 489c9cf97..1ce5fed80 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -272,5 +272,7 @@ class MySQL_Data_Stream void destroy_queues(); bool data_in_rbio(); + + void get_client_myds_info_json(json&); }; #endif /* __CLASS_MYSQL_DATA_STREAM_H */ diff --git a/include/mysql_connection.h b/include/mysql_connection.h index 350a8940c..9fb33c86f 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -26,7 +26,7 @@ class MySQLServers_SslParams; class Variable { public: char *value = (char*)""; - void fill_server_internal_session(json &j, int conn_num, int idx); + void fill_server_internal_session(json &j, int idx); void fill_client_internal_session(json &j, int idx); }; @@ -254,5 +254,8 @@ class MySQL_Connection { unsigned int number_of_matching_session_variables(const MySQL_Connection *client_conn, unsigned int& not_matching); unsigned long get_mysql_thread_id() { return mysql ? mysql->thread_id : 0; } static void set_ssl_params(MYSQL *mysql, MySQLServers_SslParams *ssl_params); + + void get_mysql_info_json(json&); + void get_backend_conn_info_json(json&); }; #endif /* __CLASS_MYSQL_CONNECTION_H */ diff --git a/include/query_processor.h b/include/query_processor.h index 3d7d8d156..9d6233029 100644 --- a/include/query_processor.h +++ b/include/query_processor.h @@ -10,7 +10,7 @@ #define DIGEST_STATS_FAST_MINSIZE 100000 #define DIGEST_STATS_FAST_THREADS 4 - +#include "../deps/json/json.hpp" #include "khash.h" @@ -204,6 +204,20 @@ class Query_Processor_Output { free(comment); } } + void get_info_json(nlohmann::json& j) { + j["create_new_connection"] = create_new_conn; + j["reconnect"] = reconnect; + j["sticky_conn"] = sticky_conn; + j["cache_timeout"] = cache_timeout; + j["cache_ttl"] = cache_ttl; + j["delay"] = delay; + j["destination_hostgroup"] = destination_hostgroup; + j["firewall_whitelist_mode"] = firewall_whitelist_mode; + j["multiplex"] = multiplex; + j["timeout"] = timeout; + j["retries"] = retries; + j["max_lag_ms"] = max_lag_ms; + } }; static char *commands_counters_desc[MYSQL_COM_QUERY___NONE]; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index b649a201d..01bc41d28 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1379,6 +1379,9 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["warning_in_hg"] = warning_in_hg; j["gtid"]["hid"] = gtid_hid; j["gtid"]["last"] = ( strlen(gtid_buf) ? gtid_buf : "" ); + json& jqpo = j["qpo"]; + qpo->get_info_json(jqpo); +/* j["qpo"]["create_new_connection"] = qpo->create_new_conn; j["qpo"]["reconnect"] = qpo->reconnect; j["qpo"]["sticky_conn"] = qpo->sticky_conn; @@ -1391,80 +1394,19 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["qpo"]["timeout"] = qpo->timeout; j["qpo"]["retries"] = qpo->retries; j["qpo"]["max_lag_ms"] = qpo->max_lag_ms; +*/ j["default_schema"] = ( default_schema ? default_schema : "" ); j["user_attributes"] = ( user_attributes ? user_attributes : "" ); j["transaction_persistent"] = transaction_persistent; if (client_myds != NULL) { // only if client_myds is defined - j["client"]["stream"]["pkts_recv"] = client_myds->pkts_recv; - j["client"]["stream"]["pkts_sent"] = client_myds->pkts_sent; - j["client"]["stream"]["bytes_recv"] = client_myds->bytes_info.bytes_recv; - j["client"]["stream"]["bytes_sent"] = client_myds->bytes_info.bytes_sent; - j["client"]["client_addr"]["address"] = ( client_myds->addr.addr ? client_myds->addr.addr : "" ); - j["client"]["client_addr"]["port"] = client_myds->addr.port; - j["client"]["proxy_addr"]["address"] = ( client_myds->proxy_addr.addr ? client_myds->proxy_addr.addr : "" ); - j["client"]["proxy_addr"]["port"] = client_myds->proxy_addr.port; - j["client"]["encrypted"] = client_myds->encrypted; - if (client_myds->encrypted) { - const SSL_CIPHER *cipher = SSL_get_current_cipher(client_myds->ssl); - if (cipher) { - const char * name = SSL_CIPHER_get_name(cipher); - if (name) { - j["client"]["ssl_cipher"] = name; - } - } - } - j["client"]["DSS"] = client_myds->DSS; - j["client"]["switching_auth_sent"] = client_myds->switching_auth_sent; - j["client"]["switching_auth_type"] = client_myds->switching_auth_type; - j["client"]["prot"]["sent_auth_plugin_id"] = client_myds->myprot.sent_auth_plugin_id; - j["client"]["prot"]["auth_plugin_id"] = client_myds->myprot.auth_plugin_id; - switch (client_myds->myprot.auth_plugin_id) { - case AUTH_MYSQL_NATIVE_PASSWORD: - j["client"]["prot"]["auth_plugin"] = "mysql_native_password"; - break; - case AUTH_MYSQL_CLEAR_PASSWORD: - j["client"]["prot"]["auth_plugin"] = "mysql_clear_password"; - break; - case AUTH_MYSQL_CACHING_SHA2_PASSWORD: - j["client"]["prot"]["auth_plugin"] = "caching_sha2_password"; - break; - default: - break; - } - if (client_myds->myconn != NULL) { // only if myconn is defined - if (client_myds->myconn->userinfo != NULL) { // only if userinfo is defined - j["client"]["userinfo"]["username"] = ( client_myds->myconn->userinfo->username ? client_myds->myconn->userinfo->username : "" ); - j["client"]["userinfo"]["schemaname"] = ( client_myds->myconn->userinfo->schemaname ? client_myds->myconn->userinfo->schemaname : "" ); -#ifdef DEBUG - j["client"]["userinfo"]["password"] = ( client_myds->myconn->userinfo->password ? client_myds->myconn->userinfo->password : "" ); -#endif - } - j["conn"]["session_track_gtids"] = ( client_myds->myconn->options.session_track_gtids ? client_myds->myconn->options.session_track_gtids : "") ; - for (auto idx = 0; idx < SQL_NAME_LAST_LOW_WM; idx++) { - client_myds->myconn->variables[idx].fill_client_internal_session(j, idx); - } - { - MySQL_Connection *c = client_myds->myconn; - for (std::vector::const_iterator it_c = c->dynamic_variables_idx.begin(); it_c != c->dynamic_variables_idx.end(); it_c++) { - c->variables[*it_c].fill_client_internal_session(j, *it_c); - } - } - - j["conn"]["autocommit"] = ( client_myds->myconn->options.autocommit ? "ON" : "OFF" ); - j["conn"]["client_flag"]["value"] = client_myds->myconn->options.client_flag; - j["conn"]["client_flag"]["client_found_rows"] = (client_myds->myconn->options.client_flag & CLIENT_FOUND_ROWS ? 1 : 0); - j["conn"]["client_flag"]["client_multi_statements"] = (client_myds->myconn->options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0); - j["conn"]["client_flag"]["client_multi_results"] = (client_myds->myconn->options.client_flag & CLIENT_MULTI_RESULTS ? 1 : 0); - j["conn"]["client_flag"]["client_deprecate_eof"] = (client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF ? 1 : 0); - j["conn"]["no_backslash_escapes"] = client_myds->myconn->options.no_backslash_escapes; - j["conn"]["status"]["compression"] = client_myds->myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); - j["conn"]["ps"]["client_stmt_to_global_ids"] = client_myds->myconn->local_stmts->client_stmt_to_global_ids; - } + json& jclient = j["client"]; + client_myds->get_client_myds_info_json(jclient); } for (unsigned int i=0; ilen; i++) { MySQL_Backend *_mybe = NULL; _mybe=(MySQL_Backend *)mybes->index(i); //unsigned int i = _mybe->hostgroup_id; + j["backends"][i] = {}; j["backends"][i]["hostgroup_id"] = _mybe->hostgroup_id; j["backends"][i]["gtid"] = ( strlen(_mybe->gtid_uuid) ? _mybe->gtid_uuid : "" ); if (_mybe->server_myds) { @@ -1482,86 +1424,8 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["backends"][i]["stream"]["bytes_sent"] = _myds->bytes_info.bytes_sent; j["backends"][i]["stream"]["DSS"] = _myds->DSS; if (_myds->myconn) { - MySQL_Connection * _myconn = _myds->myconn; - for (auto idx = 0; idx < SQL_NAME_LAST_LOW_WM; idx++) { - _myconn->variables[idx].fill_server_internal_session(j, i, idx); - } - for (std::vector::const_iterator it_c = _myconn->dynamic_variables_idx.begin(); it_c != _myconn->dynamic_variables_idx.end(); it_c++) { - _myconn->variables[*it_c].fill_server_internal_session(j, i, *it_c); - } - sprintf(buff,"%p",_myconn); - j["backends"][i]["conn"]["address"] = buff; - j["backends"][i]["conn"]["auto_increment_delay_token"] = _myconn->auto_increment_delay_token; - j["backends"][i]["conn"]["bytes_recv"] = _myconn->bytes_info.bytes_recv; - j["backends"][i]["conn"]["bytes_sent"] = _myconn->bytes_info.bytes_sent; - j["backends"][i]["conn"]["questions"] = _myconn->statuses.questions; - j["backends"][i]["conn"]["myconnpoll_get"] = _myconn->statuses.myconnpoll_get; - j["backends"][i]["conn"]["myconnpoll_put"] = _myconn->statuses.myconnpoll_put; - //j["backend"][i]["conn"]["charset"] = _myds->myconn->options.charset; // not used for backend - j["backends"][i]["conn"]["session_track_gtids"] = ( _myconn->options.session_track_gtids ? _myconn->options.session_track_gtids : "") ; - j["backends"][i]["conn"]["init_connect"] = ( _myconn->options.init_connect ? _myconn->options.init_connect : ""); - j["backends"][i]["conn"]["init_connect_sent"] = _myds->myconn->options.init_connect_sent; - j["backends"][i]["conn"]["autocommit"] = ( _myds->myconn->options.autocommit ? "ON" : "OFF" ); - j["backends"][i]["conn"]["last_set_autocommit"] = _myds->myconn->options.last_set_autocommit; - j["backends"][i]["conn"]["no_backslash_escapes"] = _myconn->options.no_backslash_escapes; - j["backends"][i]["conn"]["status"]["get_lock"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_GET_LOCK); - j["backends"][i]["conn"]["status"]["lock_tables"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_LOCK_TABLES); - j["backends"][i]["conn"]["status"]["has_savepoint"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT); - j["backends"][i]["conn"]["status"]["temporary_table"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE); - j["backends"][i]["conn"]["status"]["user_variable"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_USER_VARIABLE); - j["backends"][i]["conn"]["status"]["found_rows"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_FOUND_ROWS); - j["backends"][i]["conn"]["status"]["no_multiplex"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); - j["backends"][i]["conn"]["status"]["no_multiplex_HG"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX_HG); - j["backends"][i]["conn"]["status"]["compression"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); - j["backends"][i]["conn"]["status"]["prepared_statement"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT); - j["backends"][i]["conn"]["status"]["has_warnings"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_HAS_WARNINGS); - j["backends"][i]["conn"]["warning_count"] = _myconn->warning_count; - { - // MultiplexDisabled : status returned by MySQL_Connection::MultiplexDisabled(); - // MultiplexDisabled_ext : status returned by MySQL_Connection::MultiplexDisabled() || MySQL_Connection::isActiveTransaction() - bool multiplex_disabled = _myconn->MultiplexDisabled(); - j["backends"][i]["conn"]["MultiplexDisabled"] = multiplex_disabled; - if (multiplex_disabled == false) { - if (_myconn->IsActiveTransaction() == true) { - multiplex_disabled = true; - } - } - j["backends"][i]["conn"]["MultiplexDisabled_ext"] = multiplex_disabled; - } - j["backends"][i]["conn"]["ps"]["backend_stmt_to_global_ids"] = _myconn->local_stmts->backend_stmt_to_global_ids; - j["backends"][i]["conn"]["ps"]["global_stmt_to_backend_ids"] = _myconn->local_stmts->global_stmt_to_backend_ids; - j["backends"][i]["conn"]["client_flag"]["value"] = _myconn->options.client_flag; - j["backends"][i]["conn"]["client_flag"]["client_found_rows"] = (_myconn->options.client_flag & CLIENT_FOUND_ROWS ? 1 : 0); - j["backends"][i]["conn"]["client_flag"]["client_multi_statements"] = (_myconn->options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0); - j["backends"][i]["conn"]["client_flag"]["client_deprecate_eof"] = (_myconn->options.client_flag & CLIENT_DEPRECATE_EOF ? 1 : 0); - if (_myconn->mysql && _myconn->ret_mysql) { - MYSQL * _my = _myconn->mysql; - sprintf(buff,"%p",_my); - j["backends"][i]["conn"]["mysql"]["address"] = buff; - j["backends"][i]["conn"]["mysql"]["host"] = ( _my->host ? _my->host : "" ); - j["backends"][i]["conn"]["mysql"]["host_info"] = ( _my->host_info ? _my->host_info : "" ); - j["backends"][i]["conn"]["mysql"]["port"] = _my->port; - j["backends"][i]["conn"]["mysql"]["server_version"] = ( _my->server_version ? _my->server_version : "" ); - j["backends"][i]["conn"]["mysql"]["user"] = ( _my->user ? _my->user : "" ); - j["backends"][i]["conn"]["mysql"]["unix_socket"] = (_my->unix_socket ? _my->unix_socket : ""); - j["backends"][i]["conn"]["mysql"]["db"] = (_my->db ? _my->db : ""); - j["backends"][i]["conn"]["mysql"]["affected_rows"] = _my->affected_rows; - j["backends"][i]["conn"]["mysql"]["insert_id"] = _my->insert_id; - j["backends"][i]["conn"]["mysql"]["thread_id"] = _my->thread_id; - j["backends"][i]["conn"]["mysql"]["server_status"] = _my->server_status; - j["backends"][i]["conn"]["mysql"]["charset"] = _my->charset->nr; - j["backends"][i]["conn"]["mysql"]["charset_name"] = _my->charset->csname; - //j["backends"][i]["conn"]["mysql"][""] = _my->; - //j["backends"][i]["conn"]["mysql"][""] = _my->; - j["backends"][i]["conn"]["mysql"]["options"]["charset_name"] = ( _my->options.charset_name ? _my->options.charset_name : "" ); - j["backends"][i]["conn"]["mysql"]["options"]["use_ssl"] = _my->options.use_ssl; - j["backends"][i]["conn"]["mysql"]["net"]["last_errno"] = _my->net.last_errno; - j["backends"][i]["conn"]["mysql"]["net"]["fd"] = _my->net.fd; - j["backends"][i]["conn"]["mysql"]["net"]["max_packet_size"] = _my->net.max_packet_size; - j["backends"][i]["conn"]["mysql"]["net"]["sqlstate"] = _my->net.sqlstate; - //j["backends"][i]["conn"]["mysql"]["net"][""] = _my->net.; - //j["backends"][i]["conn"]["mysql"]["net"][""] = _my->net.; - } + json& jc = j["backends"][i]["conn"]; + _myds->myconn->get_backend_conn_info_json(jc); } } } @@ -1635,17 +1499,18 @@ bool MySQL_Session::handler_special_queries_STATUS(PtrSize_t *pkt) { string vals[4]; json j = {}; + json& jc = j["conn"]; MySQL_Connection *conn = client_myds->myconn; // here we do a bit back and forth to and from JSON to reuse existing code instead of writing new code. // This is not great for performance, but this query is rarely executed. - conn->variables[SQL_CHARACTER_SET_CLIENT].fill_client_internal_session(j, SQL_CHARACTER_SET_CLIENT); - conn->variables[SQL_CHARACTER_SET_CONNECTION].fill_client_internal_session(j, SQL_CHARACTER_SET_CONNECTION); - conn->variables[SQL_CHARACTER_SET_DATABASE].fill_client_internal_session(j, SQL_CHARACTER_SET_DATABASE); + conn->variables[SQL_CHARACTER_SET_CLIENT].fill_client_internal_session(jc, SQL_CHARACTER_SET_CLIENT); + conn->variables[SQL_CHARACTER_SET_CONNECTION].fill_client_internal_session(jc, SQL_CHARACTER_SET_CONNECTION); + conn->variables[SQL_CHARACTER_SET_DATABASE].fill_client_internal_session(jc, SQL_CHARACTER_SET_DATABASE); - vals[0] = j["conn"][mysql_tracked_variables[SQL_CHARACTER_SET_CLIENT].internal_variable_name]; - vals[1] = j["conn"][mysql_tracked_variables[SQL_CHARACTER_SET_CONNECTION].internal_variable_name]; + vals[0] = jc[mysql_tracked_variables[SQL_CHARACTER_SET_CLIENT].internal_variable_name]; + vals[1] = jc[mysql_tracked_variables[SQL_CHARACTER_SET_CONNECTION].internal_variable_name]; vals[2] = string(mysql_thread___default_variables[SQL_CHARACTER_SET]); - vals[3] = j["conn"][mysql_tracked_variables[SQL_CHARACTER_SET_DATABASE].internal_variable_name]; + vals[3] = jc[mysql_tracked_variables[SQL_CHARACTER_SET_DATABASE].internal_variable_name]; const char *pta[4]; for (int i=0; i<4; i++) { diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 37c24b2db..3f0a8ef69 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -109,7 +109,7 @@ extern char * binary_sha1; #include "proxysql_find_charset.h" -void Variable::fill_server_internal_session(json &j, int conn_num, int idx) { +void Variable::fill_server_internal_session(json &j, int idx) { if (idx == SQL_CHARACTER_SET_RESULTS || idx == SQL_CHARACTER_SET_CLIENT || idx == SQL_CHARACTER_SET_DATABASE) { const MARIADB_CHARSET_INFO *ci = NULL; if (!value) { @@ -120,9 +120,9 @@ void Variable::fill_server_internal_session(json &j, int conn_num, int idx) { if (!ci) { if (idx == SQL_CHARACTER_SET_RESULTS && (!strcasecmp("NULL", value) || !strcasecmp("binary", value))) { if (!strcasecmp("NULL", value)) { - j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = ""; + j[mysql_tracked_variables[idx].internal_variable_name] = ""; } else { - j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = value; + j[mysql_tracked_variables[idx].internal_variable_name] = value; } } else { // LCOV_EXCL_START @@ -131,7 +131,7 @@ void Variable::fill_server_internal_session(json &j, int conn_num, int idx) { // LCOV_EXCL_STOP } } else { - j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = std::string((ci && ci->csname)?ci->csname:""); + j[mysql_tracked_variables[idx].internal_variable_name] = std::string((ci && ci->csname)?ci->csname:""); } } else if (idx == SQL_CHARACTER_SET_CONNECTION) { const MARIADB_CHARSET_INFO *ci = NULL; @@ -140,7 +140,7 @@ void Variable::fill_server_internal_session(json &j, int conn_num, int idx) { else ci = proxysql_find_charset_nr(atoi(value)); - j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = std::string((ci && ci->csname)?ci->csname:""); + j[mysql_tracked_variables[idx].internal_variable_name] = std::string((ci && ci->csname)?ci->csname:""); } else if (idx == SQL_COLLATION_CONNECTION) { const MARIADB_CHARSET_INFO *ci = NULL; if (!value) @@ -148,7 +148,7 @@ void Variable::fill_server_internal_session(json &j, int conn_num, int idx) { else ci = proxysql_find_charset_nr(atoi(value)); - j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = std::string((ci && ci->name)?ci->name:""); + j[mysql_tracked_variables[idx].internal_variable_name] = std::string((ci && ci->name)?ci->name:""); /* // NOTE: it seems we treat SQL_LOG_BIN in a special way // it doesn't seem necessary @@ -159,7 +159,7 @@ void Variable::fill_server_internal_session(json &j, int conn_num, int idx) { j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = std::string(!strcmp("1",value)?"ON":"OFF"); */ } else { - j["backends"][conn_num]["conn"][mysql_tracked_variables[idx].internal_variable_name] = std::string(value?value:""); + j[mysql_tracked_variables[idx].internal_variable_name] = std::string(value?value:""); } } @@ -174,9 +174,9 @@ void Variable::fill_client_internal_session(json &j, int idx) { if (!ci) { if (idx == SQL_CHARACTER_SET_RESULTS && (!strcasecmp("NULL", value) || !strcasecmp("binary", value))) { if (!strcasecmp("NULL", value)) { - j["conn"][mysql_tracked_variables[idx].internal_variable_name] = ""; + j[mysql_tracked_variables[idx].internal_variable_name] = ""; } else { - j["conn"][mysql_tracked_variables[idx].internal_variable_name] = value; + j[mysql_tracked_variables[idx].internal_variable_name] = value; } } else { // LCOV_EXCL_START @@ -185,7 +185,7 @@ void Variable::fill_client_internal_session(json &j, int idx) { // LCOV_EXCL_STOP } } else { - j["conn"][mysql_tracked_variables[idx].internal_variable_name] = (ci && ci->csname)?ci->csname:""; + j[mysql_tracked_variables[idx].internal_variable_name] = (ci && ci->csname)?ci->csname:""; } } else if (idx == SQL_CHARACTER_SET_CONNECTION) { const MARIADB_CHARSET_INFO *ci = NULL; @@ -193,14 +193,14 @@ void Variable::fill_client_internal_session(json &j, int idx) { ci = proxysql_find_charset_collate(mysql_tracked_variables[idx].default_value); else ci = proxysql_find_charset_nr(atoi(value)); - j["conn"][mysql_tracked_variables[idx].internal_variable_name] = (ci && ci->csname)?ci->csname:""; + j[mysql_tracked_variables[idx].internal_variable_name] = (ci && ci->csname)?ci->csname:""; } else if (idx == SQL_COLLATION_CONNECTION) { const MARIADB_CHARSET_INFO *ci = NULL; if (!value) ci = proxysql_find_charset_collate(mysql_tracked_variables[idx].default_value); else ci = proxysql_find_charset_nr(atoi(value)); - j["conn"][mysql_tracked_variables[idx].internal_variable_name] = (ci && ci->name)?ci->name:""; + j[mysql_tracked_variables[idx].internal_variable_name] = (ci && ci->name)?ci->name:""; /* // NOTE: it seems we treat SQL_LOG_BIN in a special way // it doesn't seem necessary @@ -211,7 +211,7 @@ void Variable::fill_client_internal_session(json &j, int idx) { j["conn"][mysql_tracked_variables[idx].internal_variable_name] = !strcmp("1", value)?"ON":"OFF"; */ } else { - j["conn"][mysql_tracked_variables[idx].internal_variable_name] = value?value:""; + j[mysql_tracked_variables[idx].internal_variable_name] = value?value:""; } } @@ -3008,3 +3008,87 @@ void MySQL_Connection::set_ssl_params(MYSQL *mysql, MySQLServers_SslParams *ssl_ ( ssl_params->ssl_crlpath.length() > 0 ? ssl_params->ssl_crlpath.c_str() : NULL ) ); } } + +void MySQL_Connection::get_mysql_info_json(json& j) { + char buff[32]; + sprintf(buff,"%p",mysql); + j["address"] = buff; + j["host"] = ( mysql->host ? mysql->host : "" ); + j["host_info"] = ( mysql->host_info ? mysql->host_info : "" ); + j["port"] = mysql->port; + j["server_version"] = ( mysql->server_version ? mysql->server_version : "" ); + j["user"] = ( mysql->user ? mysql->user : "" ); + j["unix_socket"] = (mysql->unix_socket ? mysql->unix_socket : ""); + j["db"] = (mysql->db ? mysql->db : ""); + j["affected_rows"] = mysql->affected_rows; + j["insert_id"] = mysql->insert_id; + j["thread_id"] = mysql->thread_id; + j["server_status"] = mysql->server_status; + j["charset"] = mysql->charset->nr; + j["charset_name"] = mysql->charset->csname; + j["options"]["charset_name"] = ( mysql->options.charset_name ? mysql->options.charset_name : "" ); + j["options"]["use_ssl"] = mysql->options.use_ssl; + j["net"]["last_errno"] = mysql->net.last_errno; + j["net"]["fd"] = mysql->net.fd; + j["net"]["max_packet_size"] = mysql->net.max_packet_size; + j["net"]["sqlstate"] = mysql->net.sqlstate; +} + +void MySQL_Connection::get_backend_conn_info_json(json& j) { + for (auto idx = 0; idx < SQL_NAME_LAST_LOW_WM; idx++) { + variables[idx].fill_server_internal_session(j, idx); + } + for (std::vector::const_iterator it_c = dynamic_variables_idx.begin(); it_c != dynamic_variables_idx.end(); it_c++) { + variables[*it_c].fill_server_internal_session(j, *it_c); + } + char buff[32]; + sprintf(buff,"%p", this); + j["address"] = buff; + j["auto_increment_delay_token"] = auto_increment_delay_token; + j["bytes_recv"] = bytes_info.bytes_recv; + j["bytes_sent"] = bytes_info.bytes_sent; + j["questions"] = statuses.questions; + j["myconnpoll_get"] = statuses.myconnpoll_get; + j["myconnpoll_put"] = statuses.myconnpoll_put; + j["session_track_gtids"] = ( options.session_track_gtids ? options.session_track_gtids : "") ; + j["init_connect"] = ( options.init_connect ? options.init_connect : ""); + j["init_connect_sent"] = options.init_connect_sent; + j["autocommit"] = ( options.autocommit ? "ON" : "OFF" ); + j["last_set_autocommit"] = options.last_set_autocommit; + j["no_backslash_escapes"] = options.no_backslash_escapes; + j["warning_count"] = warning_count; + json& js = j["status"]; + js["get_lock"] = get_status(STATUS_MYSQL_CONNECTION_GET_LOCK); + js["lock_tables"] = get_status(STATUS_MYSQL_CONNECTION_LOCK_TABLES); + js["has_savepoint"] = get_status(STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT); + js["temporary_table"] = get_status(STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE); + js["user_variable"] = get_status(STATUS_MYSQL_CONNECTION_USER_VARIABLE); + js["found_rows"] = get_status(STATUS_MYSQL_CONNECTION_FOUND_ROWS); + js["no_multiplex"] = get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); + js["no_multiplex_HG"] = get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX_HG); + js["compression"] = get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); + js["prepared_statement"] = get_status(STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT); + js["has_warnings"] = get_status(STATUS_MYSQL_CONNECTION_HAS_WARNINGS); + { + // MultiplexDisabled : status returned by MySQL_Connection::MultiplexDisabled(); + // MultiplexDisabled_ext : status returned by MySQL_Connection::MultiplexDisabled() || MySQL_Connection::isActiveTransaction() + bool multiplex_disabled = MultiplexDisabled(); + j["MultiplexDisabled"] = multiplex_disabled; + if (multiplex_disabled == false) { + if (IsActiveTransaction() == true) { + multiplex_disabled = true; + } + } + j["MultiplexDisabled_ext"] = multiplex_disabled; + } + j["ps"]["backend_stmt_to_global_ids"] = local_stmts->backend_stmt_to_global_ids; + j["ps"]["global_stmt_to_backend_ids"] = local_stmts->global_stmt_to_backend_ids; + j["client_flag"]["value"] = options.client_flag; + j["client_flag"]["client_found_rows"] = (options.client_flag & CLIENT_FOUND_ROWS ? 1 : 0); + j["client_flag"]["client_multi_statements"] = (options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0); + j["client_flag"]["client_deprecate_eof"] = (options.client_flag & CLIENT_DEPRECATE_EOF ? 1 : 0); + if (mysql && ret_mysql) { + json& jcm = j["mysql"]; + get_mysql_info_json(jcm); + } +} diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index f658992d2..8cb21c6fa 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -1549,3 +1549,72 @@ bool MySQL_Data_Stream::data_in_rbio() { } return false; } + +void MySQL_Data_Stream::get_client_myds_info_json(json& j) { + j["stream"]["pkts_recv"] = pkts_recv; + j["stream"]["pkts_sent"] = pkts_sent; + j["stream"]["bytes_recv"] = bytes_info.bytes_recv; + j["stream"]["bytes_sent"] = bytes_info.bytes_sent; + j["client_addr"]["address"] = ( addr.addr ? addr.addr : "" ); + j["client_addr"]["port"] = addr.port; + j["proxy_addr"]["address"] = ( proxy_addr.addr ? proxy_addr.addr : "" ); + j["proxy_addr"]["port"] = proxy_addr.port; + j["encrypted"] = encrypted; + if (encrypted) { + const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl); + if (cipher) { + const char * name = SSL_CIPHER_get_name(cipher); + if (name) { + j["ssl_cipher"] = name; + } + } + } + j["DSS"] = DSS; + j["switching_auth_sent"] = switching_auth_sent; + j["switching_auth_type"] = switching_auth_type; + j["prot"]["sent_auth_plugin_id"] = myprot.sent_auth_plugin_id; + j["prot"]["auth_plugin_id"] = myprot.auth_plugin_id; + + switch (myprot.auth_plugin_id) { + case AUTH_MYSQL_NATIVE_PASSWORD: + j["prot"]["auth_plugin"] = "mysql_native_password"; + break; + case AUTH_MYSQL_CLEAR_PASSWORD: + j["prot"]["auth_plugin"] = "mysql_clear_password"; + break; + case AUTH_MYSQL_CACHING_SHA2_PASSWORD: + j["prot"]["auth_plugin"] = "caching_sha2_password"; + break; + default: + break; + } + if (myconn != NULL) { // only if myconn is defined + json& jc = j["conn"]; + if (myconn->userinfo != NULL) { // only if userinfo is defined + j["userinfo"]["username"] = ( myconn->userinfo->username ? myconn->userinfo->username : "" ); + j["userinfo"]["schemaname"] = ( myconn->userinfo->schemaname ? myconn->userinfo->schemaname : "" ); +#ifdef DEBUG + j["userinfo"]["password"] = ( myconn->userinfo->password ? myconn->userinfo->password : "" ); +#endif + } + jc["session_track_gtids"] = ( myconn->options.session_track_gtids ? myconn->options.session_track_gtids : "") ; + for (auto idx = 0; idx < SQL_NAME_LAST_LOW_WM; idx++) { + myconn->variables[idx].fill_client_internal_session(jc, idx); + } + { + for (std::vector::const_iterator it_c = myconn->dynamic_variables_idx.begin(); it_c != myconn->dynamic_variables_idx.end(); it_c++) { + myconn->variables[*it_c].fill_client_internal_session(jc, *it_c); + } + } + + jc["autocommit"] = ( myconn->options.autocommit ? "ON" : "OFF" ); + jc["client_flag"]["value"] = myconn->options.client_flag; + jc["client_flag"]["client_found_rows"] = (myconn->options.client_flag & CLIENT_FOUND_ROWS ? 1 : 0); + jc["client_flag"]["client_multi_statements"] = (myconn->options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0); + jc["client_flag"]["client_multi_results"] = (myconn->options.client_flag & CLIENT_MULTI_RESULTS ? 1 : 0); + jc["client_flag"]["client_deprecate_eof"] = (myconn->options.client_flag & CLIENT_DEPRECATE_EOF ? 1 : 0); + jc["no_backslash_escapes"] = myconn->options.no_backslash_escapes; + jc["status"]["compression"] = myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); + jc["ps"]["client_stmt_to_global_ids"] = myconn->local_stmts->client_stmt_to_global_ids; + } +}