diff --git a/src/www/qserv/css/QservMySQLConnections.css b/src/www/qserv/css/QservMySQLConnections.css index 50b66acb8..ed42965da 100644 --- a/src/www/qserv/css/QservMySQLConnections.css +++ b/src/www/qserv/css/QservMySQLConnections.css @@ -22,3 +22,6 @@ table#fwk-qserv-mysql-connections > thead > tr > th.sticky { top:80px; z-index:2; } +table#fwk-qserv-mysql-connections tbody > tr.display-worker-queries:hover { + cursor:pointer; +} \ No newline at end of file diff --git a/src/www/qserv/js/QservMySQLConnections.js b/src/www/qserv/js/QservMySQLConnections.js index 176e951f3..3c440da2d 100644 --- a/src/www/qserv/js/QservMySQLConnections.js +++ b/src/www/qserv/js/QservMySQLConnections.js @@ -136,32 +136,40 @@ function(CSSLoader, * Display MySQL connections */ _display(data) { + const queryInspectTitle = "Click to see MySQL queries runing on the worker's MySQL server."; let html = ''; for (let worker in data) { - if (!data[worker].success) { - html += ` -
${sql_conn_mgr.totalCount}
${sql_conn_mgr.sqlScanConnCount}
${sql_conn_mgr.maxSqlScanConnections}
${sql_conn_mgr.sqlSharedConnCount}
${sql_conn_mgr.maxSqlSharedConnections}
${totalCount}
${sqlScanConnCount}
${maxSqlScanConnections}
${sqlSharedConnCount}
${maxSqlSharedConnections}
Task | ++ | + | + | + | + | + | MySQL | ++ | + | + | + | + | |||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
QID | ++ | job | +chunk | +subchunk | +templ | +state | Id | Time | +Command | State | Query | @@ -89,6 +129,7 @@ function(CSSLoader, }); cont.find("button#reset-controls-form").click(() => { this._set_update_interval_sec(10); + this._set_query_command('Query'); this._load(); }); } @@ -101,6 +142,9 @@ function(CSSLoader, } _update_interval_sec() { return this._form_control('select', 'update-interval').val(); } _set_update_interval_sec(val) { this._form_control('select', 'update-interval').val(val); } + _set_num_queries(total, displayed) { this._form_control('input', 'num-queries').val(displayed + ' / ' + total); } + _query_command() { return this._form_control('select', 'query-command').val(); } + _set_query_command(val) { this._form_control('select', 'query-command').val(val); } _worker() { return this._form_control('select', 'worker').val(); } _set_worker(val) { this._form_control('select', 'worker').val(val); } _set_workers(workers) { @@ -121,7 +165,7 @@ function(CSSLoader, } return this._table_obj; } - _load() { + _load(worker = undefined) { if (this._loading === undefined) this._loading = false; if (this._loading) return; this._loading = true; @@ -135,6 +179,7 @@ function(CSSLoader, workers.push(data.config.workers[i].name); } this._set_workers(workers); + if (!_.isUndefined(worker)) this._set_worker(worker); this._load_queries(); }, (msg) => { @@ -152,7 +197,7 @@ function(CSSLoader, }, (data) => { if (data.success) { - this._display(data.status.queries); + this._display(data.status); Fwk.setLastUpdate(this._table().children('caption')); } else { console.log('request failed', this.fwk_app_name, data.error); @@ -169,42 +214,99 @@ function(CSSLoader, } ); } - _display(queries) { + _display(status) { + const queryInspectTitle = "Click to see detailed info (progress, messages, etc.) on the query."; const queryCopyTitle = "Click to copy the query text to the clipboard."; const COL_Id = 0, COL_Command = 4, COL_Time = 5, COL_State = 6, COL_Info = 7; + const desiredQueryCommand = this._query_command(); let tbody = this._table().children('tbody'); - if (_.isEmpty(queries.columns)) { + if (_.isEmpty(status.queries.columns)) { tbody.html(''); return; } - this._id2query = {}; + this._mySqlThreaId2query = {}; + let numQueriesTotal = 0; + let numQueriesDisplayed = 0; let html = ''; - for (let i in queries.rows) { - let row = queries.rows[i]; - if (row[COL_Command] !== 'Query') continue; - let queryId = row[COL_Id]; + for (let i in status.queries.rows) { + numQueriesTotal++; + // MySQL query context + let row = status.queries.rows[i]; + const thisQueryCommand = row[COL_Command]; + if ((desiredQueryCommand !== '') && (thisQueryCommand !== desiredQueryCommand)) continue; + let mySqlThreadId = row[COL_Id]; let query = row[COL_Info]; - this._id2query[queryId] = query; - const expanded = (queryId in this._queryId2Expanded) && this._queryId2Expanded[queryId]; + this._mySqlThreaId2query[mySqlThreadId] = query; + const expanded = (mySqlThreadId in this._mySqlThreadId2Expanded) && this._mySqlThreadId2Expanded[mySqlThreadId]; const queryToggleTitle = "Click to toggle query formatting."; const queryStyle = "color:#4d4dff;"; + // Task context (if any) + let queryId = ''; + let jobId = ''; + let chunkId = ''; + let subChunkId = ''; + let templateId = ''; + let state = ''; + if (_.has(status.mysql_thread_to_task, mySqlThreadId)) { + let task = status.mysql_thread_to_task[mySqlThreadId]; + queryId = task['query_id']; + jobId = task['job_id']; + chunkId = task['chunk_id']; + subChunkId = task['subchunk_id']; + templateId = task['template_id']; + state = task['state']; + } + const rowClass = QservWorkerMySQLQueries._state2css(state); html += ` -||||||
${queryId} |
+|||||||||||||||||
${queryId} | `;
+ if (queryId === '') {
+ html += `
+ `; + } else { + html += ` + | + + | `; + } + html += ` +${jobId} |
+ ${chunkId} |
+ ${subChunkId} |
+ ${templateId} |
+ ${state} |
+ ${mySqlThreadId} |
${row[COL_Time]} |
- ${row[COL_State]} |
+ ${row[COL_Command]} |
+ ${row[COL_State]} | `;
+ if (query === '') {
+ html += `
+ + | `; + + } else { + html += ` | - | ` + this._query2text(queryId, expanded) + ` |
+ ` + this._query2text(mySqlThreadId, expanded) + ` | `;
+ }
+ html += `