Repository: tez Updated Branches: refs/heads/master 9b158ee68 -> 17f428fb7
TEZ-3593. Tez UI: Issues in timeline page (sree) Project: http://git-wip-us.apache.org/repos/asf/tez/repo Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/17f428fb Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/17f428fb Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/17f428fb Branch: refs/heads/master Commit: 17f428fb73307c11e1ca135b496800d47a23910d Parents: 9b158ee Author: Sreenath Somarajapuram <[email protected]> Authored: Thu Feb 2 14:03:48 2017 +0530 Committer: Sreenath Somarajapuram <[email protected]> Committed: Thu Feb 2 14:03:48 2017 +0530 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../webapp/app/components/query-timeline.js | 73 +++++++----- .../webapp/app/controllers/query/timeline.js | 12 -- .../main/webapp/app/styles/query-timeline.less | 92 +++++++++++---- .../app/templates/components/query-timeline.hbs | 118 ++++++++++++++++--- .../webapp/app/templates/query/timeline.hbs | 113 +++--------------- .../components/query-timeline-test.js | 100 +++++++++++----- 7 files changed, 303 insertions(+), 206 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 7d3e1db..1624b50 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -183,6 +183,7 @@ ALL CHANGES: TEZ-3554. Add a link to get to all logs from Tez UI while job is running TEZ-3591. Tez UI: Logs url in all DAGs doesn't open in a new window TEZ-3592. Tez UI: Search issues + TEZ-3593. Tez UI: Issues in timeline page Release 0.8.5: Unreleased http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/tez-ui/src/main/webapp/app/components/query-timeline.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/query-timeline.js b/tez-ui/src/main/webapp/app/components/query-timeline.js index e743530..d5a0667 100644 --- a/tez-ui/src/main/webapp/app/components/query-timeline.js +++ b/tez-ui/src/main/webapp/app/components/query-timeline.js @@ -23,42 +23,57 @@ export default Ember.Component.extend({ perf: null, - getDisplayedPerfValues: function (perfHash) { - return [[ - perfHash["compile"] || 0, - perfHash["parse"] || 0, - perfHash["semanticAnalyze"] || 0, - perfHash["TezBuildDag"] || 0, - ], [ - perfHash["TezSubmitDag"] || 0, - perfHash["TezSubmitToRunningDag"] || 0, - ], [ - perfHash["TezRunDag"] || 0, - ], [ - perfHash["PostATSHook"] || 0, - perfHash["RemoveTempOrDuplicateFiles"] || 0, - perfHash["RenameOrMoveFiles"] || 0, - ]]; - }, + normalizedPerf: Ember.computed("perf", function () { + var perf = this.get("perf") || {}; + + // Create a copy of perf with default values + perf = Ember.$.extend({ + compile: 0, + parse: 0, + TezBuildDag: 0, + + TezSubmitDag: 0, + TezSubmitToRunningDag: 0, + + TezRunDag: 0, + + PostATSHook: 0, + RemoveTempOrDuplicateFiles: 0, + RenameOrMoveFiles: 0 + }, perf); + + perf.groupTotal = { + pre: perf.compile + perf.parse + perf.TezBuildDag, + submit: perf.TezSubmitDag + perf.TezSubmitToRunningDag, + running: perf.TezRunDag, + post: perf.PostATSHook + perf.RemoveTempOrDuplicateFiles + perf.RenameOrMoveFiles, + }; - alignBars: function (bars, widthFactors) { - var totalValue = widthFactors.reduce((a, b) => a + b, 0); + perf.total = perf.groupTotal.pre + + perf.groupTotal.submit + + perf.groupTotal.running + + perf.groupTotal.post; + + return perf; + }), + + alignBars: function (bars, perf) { bars.each(function (index, bar) { - var width = (widthFactors[index] / totalValue) * 100; - Ember.$(bar).css({ + var width; + + bar = Ember.$(bar); + width = (Ember.get(perf, bar.attr("data")) / perf.total) * 100; + + bar.css({ width: `${width}%` }); }); }, - didInsertElement: Ember.observer("perf", function () { - var perfs = this.getDisplayedPerfValues(this.get("perf")); - - this.alignBars(this.$().find(".sub-groups").find(".bar"), [].concat.apply([], perfs)); + didInsertElement: Ember.observer("normalizePerf", function () { + var perf = this.get("normalizedPerf"); - this.alignBars(this.$().find(".groups").find(".bar"), perfs.map(function (subPerfs) { - return subPerfs.reduce((a, b) => a + b, 0); - })); + this.alignBars(this.$().find(".sub-groups").find(".bar"), perf); + this.alignBars(this.$().find(".groups").find(".bar"), perf); }) - }); http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/tez-ui/src/main/webapp/app/controllers/query/timeline.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/controllers/query/timeline.js b/tez-ui/src/main/webapp/app/controllers/query/timeline.js index 3b72efb..b52fc26 100644 --- a/tez-ui/src/main/webapp/app/controllers/query/timeline.js +++ b/tez-ui/src/main/webapp/app/controllers/query/timeline.js @@ -38,18 +38,6 @@ export default TableController.extend({ } }]), - phaseTimes: Ember.computed("model", function () { - var perf = this.get("model.perf"); - return { - pre: perf.compile + perf.parse + perf.semanticAnalyze + perf.TezBuildDag, - submission: perf.TezSubmitDag + perf.TezSubmitToRunningDag, - run: perf.TezRunDag, - post: perf.RemoveTempOrDuplicateFiles + - perf.RemoveTempOrDuplicateFiles + - perf.RenameOrMoveFiles - }; - }), - rows: Ember.computed("model.perf", function () { var perf = this.get("model.perf"), rows = []; http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/tez-ui/src/main/webapp/app/styles/query-timeline.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/query-timeline.less b/tez-ui/src/main/webapp/app/styles/query-timeline.less index b5bfb54..1591563 100644 --- a/tez-ui/src/main/webapp/app/styles/query-timeline.less +++ b/tez-ui/src/main/webapp/app/styles/query-timeline.less @@ -16,9 +16,21 @@ * limitations under the License. */ -.query-timeline { +// Mixins +.hue-bkg(@hue) { + background-color: hsl(@hue, .9, .75); +} + +.nth-hue-bkg(@index, @hue) { + &:nth-child(@{index}) { + .hue-bkg(@hue); + } +} + +.timeline-bars { font-size: 0; margin: 20px 0 20px 0; + overflow: hidden; .no-select; @@ -78,36 +90,70 @@ border: none; } - &:nth-child(1) { - background-color: lighten(#FF355E, 20%); - } - &:nth-child(2) { - background-color: lighten(#FD5B78, 20%); + .nth-hue-bkg(1, 0); + .nth-hue-bkg(2, 40); + .nth-hue-bkg(3, 80); + .nth-hue-bkg(4, 200); + .nth-hue-bkg(5, 160); + .nth-hue-bkg(6, 120); + .nth-hue-bkg(7, 240); + .nth-hue-bkg(8, 280); + .nth-hue-bkg(9, 320); + } + } +} + +.query-timeline { + table.detail-list { + i { + display: inline-block; + + width: .85em; + height: .85em; + border: 1px solid @border-color; + border-radius: .5em; + + margin-right: 5px; + margin-top: 1px; + } + + &:nth-of-type(1) tbody tr { + &:nth-of-type(1) i { + .hue-bkg(0); } - &:nth-child(3) { - background-color: lighten(#FF6037, 20%); + &:nth-of-type(2) i { + .hue-bkg(40); } - &:nth-child(4) { - background-color: lighten(#FF9966, 20%); + &:nth-of-type(3) i { + .hue-bkg(80); } - &:nth-child(5) { - background-color: lighten(#FF9933, 20%); + } + + &:nth-of-type(2) tbody tr { + &:nth-of-type(1) i { + .hue-bkg(200); } - &:nth-child(6) { - background-color: lighten(#FFCC33, 20%); + &:nth-of-type(2) i { + .hue-bkg(160); } - &:nth-child(7) { - background-color: lighten(#FFFF66, 20%); + } + + &:nth-of-type(3) tbody tr { + &:nth-of-type(1) i { + .hue-bkg(120); } - &:nth-child(8) { - background-color: lighten(#CCFF00, 20%); + } + + &:nth-of-type(4) tbody tr { + &:nth-of-type(1) i { + .hue-bkg(240); } - &:nth-child(9) { - background-color: lighten(#AAF0D1, 10%); + &:nth-of-type(2) i { + .hue-bkg(280); } - &:nth-child(10) { - background-color: lighten(#FF6EFF, 20%); + &:nth-of-type(3) i { + .hue-bkg(320); } - } + } } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/tez-ui/src/main/webapp/app/templates/components/query-timeline.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/components/query-timeline.hbs b/tez-ui/src/main/webapp/app/templates/components/query-timeline.hbs index 681b7b5..98d33d2 100644 --- a/tez-ui/src/main/webapp/app/templates/components/query-timeline.hbs +++ b/tez-ui/src/main/webapp/app/templates/components/query-timeline.hbs @@ -16,25 +16,109 @@ * limitations under the License. }} -<div class="groups"> - <div class="bar" title="Pre-Execution + DAG construction">Pre-Execution + DAG construction</div> - <div class="bar" title="DAG Submission">DAG Submission</div> - <div class="bar" title="DAG Runtime">DAG Runtime</div> - <div class="bar" title="Post Execution">Post Execution</div> -</div> +<div class="timeline-bars"> + <div class="groups"> + <div class="bar" data="groupTotal.pre" title="Pre-Execution + DAG construction">Pre-Execution + DAG construction</div> + <div class="bar" data="groupTotal.submit" title="DAG Submission">DAG Submission</div> + <div class="bar" data="groupTotal.running" title="DAG Runtime">DAG Runtime</div> + <div class="bar" data="groupTotal.post" title="Post Execution">Post Execution</div> + </div> -<div class="sub-groups"> - <div class="bar" title="Compile">Compile</div> - <div class="bar" title="Parse">Parse</div> - <div class="bar" title="Semantic Analyze">Semantic Analyze</div> - <div class="bar" title="Build Dag">Build Dag</div> + <div class="sub-groups"> + <div class="bar" data="compile" title="Compile">Compile</div> + <div class="bar" data="parse" title="Parse">Parse</div> + <div class="bar" data="TezBuildDag" title="Build Dag">Build Dag</div> - <div class="bar" title="Submit Dag">Submit Dag</div> - <div class="bar" title="Submit To Running">Submit To Running</div> + <div class="bar" data="TezSubmitDag" title="Submit Dag">Submit Dag</div> + <div class="bar" data="TezSubmitToRunningDag" title="Submit To Running">Submit To Running</div> - <div class="bar" title="Run Dag">Run Dag</div> + <div class="bar" data="TezRunDag" title="Run Dag">Run Dag</div> - <div class="bar" title="Post ATS Hook">Post ATS Hook</div> - <div class="bar" title="Remove Files">Remove Files</div> - <div class="bar" title="Rename Or Move Files">Rename Or Move Files</div> + <div class="bar" data="PostATSHook" title="Post ATS Hook">Post ATS Hook</div> + <div class="bar" data="RemoveTempOrDuplicateFiles" title="Remove Files">Remove Files</div> + <div class="bar" data="RenameOrMoveFiles" title="Rename Or Move Files">Rename Or Move Files</div> + </div> </div> + +<table class='detail-list'> + <thead> + <tr> + <th colspan=2>Pre-Execution + DAG construction : {{txt normalizedPerf.groupTotal.pre type="duration"}}</th> + </tr> + </thead> + + <tbody> + <tr> + <td><i></i>Compile</td> + <td>{{txt normalizedPerf.compile type="duration"}}</td> + </tr> + <tr> + <td><i></i>Parse</td> + <td>{{txt normalizedPerf.parse type="duration"}}</td> + </tr> + <tr> + <td><i></i>Build Dag</td> + <td>{{txt normalizedPerf.TezBuildDag type="duration"}}</td> + </tr> + </tbody> +</table> + +<table class='detail-list'> + <thead> + <tr> + <th colspan=2>DAG Submission : {{txt normalizedPerf.groupTotal.submit type="duration"}}</th> + </tr> + </thead> + <tbody> + <tr> + <td><i></i>Submit Dag</td> + <td>{{txt normalizedPerf.TezSubmitDag type="duration"}}</td> + </tr> + <tr> + <td><i></i>Submit To Running</td> + <td>{{txt normalizedPerf.TezSubmitToRunningDag type="duration"}}</td> + </tr> + </tbody> +</table> + +<table class='detail-list'> + <thead> + <tr> + <th colspan=2>DAG Runtime : {{txt normalizedPerf.groupTotal.running type="duration"}}</th> + </tr> + </thead> + <tbody> + <tr> + <td><i></i>Run Dag</td> + <td>{{txt normalizedPerf.TezRunDag type="duration"}}</td> + </tr> + </tbody> +</table> + +<table class='detail-list'> + <thead> + <tr> + <th colspan=2>Post Execution : {{txt normalizedPerf.groupTotal.post type="duration"}}</th> + </tr> + </thead> + <tbody> + {{#if normalizedPerf.RemoveTempOrDuplicateFiles}} + <tr> + <td><i></i>Post ATS Hook</td> + <td>{{txt normalizedPerf.PostATSHook type="duration"}}</td> + </tr> + {{/if}} + {{#if normalizedPerf.RemoveTempOrDuplicateFiles}} + <tr> + <td><i></i>Remove Files</td> + <td>{{txt normalizedPerf.RemoveTempOrDuplicateFiles type="duration"}}</td> + </tr> + {{/if}} + {{#if normalizedPerf.RenameOrMoveFiles}} + <tr> + <td><i></i>Rename Or Move Files</td> + <td>{{txt normalizedPerf.RenameOrMoveFiles type="duration"}}</td> + </tr> + {{/if}} + </tbody> +</table> http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/tez-ui/src/main/webapp/app/templates/query/timeline.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/query/timeline.hbs b/tez-ui/src/main/webapp/app/templates/query/timeline.hbs index 9a728a7..2a84892 100644 --- a/tez-ui/src/main/webapp/app/templates/query/timeline.hbs +++ b/tez-ui/src/main/webapp/app/templates/query/timeline.hbs @@ -18,108 +18,25 @@ {{#if loaded}} - {{query-timeline perf=model.perf}} + {{#if model.perf}} + {{query-timeline perf=model.perf}} - <table class='detail-list'> - <thead> - <tr> - <th colspan=2>Pre-Execution + DAG construction : {{txt phaseTimes.pre type="duration"}}</th> - </tr> - </thead> + {{em-table + columns=columns + rows=rows - <tbody> - <tr> - <td>Compile</td> - <td>{{txt model.perf.compile type="duration"}}</td> - </tr> - <tr> - <td>Parse</td> - <td>{{txt model.perf.parse type="duration"}}</td> - </tr> - <tr> - <td>Semantic Analyze</td> - <td>{{txt model.perf.semanticAnalyze type="duration"}}</td> - </tr> - <tr> - <td>Build Dag</td> - <td>{{txt model.perf.TezBuildDag type="duration"}}</td> - </tr> - </tbody> - </table> + rowCount=rows.length + definition=definition - <table class='detail-list'> - <thead> - <tr> - <th colspan=2>DAG Submission : {{txt phaseTimes.submission type="duration"}}</th> - </tr> - </thead> - <tbody> - <tr> - <td>Submit Dag</td> - <td>{{txt model.perf.TezSubmitDag type="duration"}}</td> - </tr> - <tr> - <td>Submit To Running</td> - <td>{{txt model.perf.TezSubmitToRunningDag type="duration"}}</td> - </tr> - </tbody> - </table> - - <table class='detail-list'> - <thead> - <tr> - <th colspan=2>DAG Runtime : {{txt phaseTimes.run type="duration"}}</th> - </tr> - </thead> - <tbody> - <tr> - <td>Run Dag</td> - <td>{{txt model.perf.TezRunDag type="duration"}}</td> - </tr> - </tbody> - </table> - - <table class='detail-list'> - <thead> - <tr> - <th colspan=2>Post Execution : {{txt phaseTimes.post type="duration"}}</th> - </tr> - </thead> - <tbody> - <tr> - <td>Post ATS Hook</td> - <td>{{txt model.perf.PostATSHook type="duration"}}</td> - </tr> - {{#if model.perf.RemoveTempOrDuplicateFiles}} - <tr> - <td>Remove Files</td> - <td>{{txt model.perf.RemoveTempOrDuplicateFiles type="duration"}}</td> - </tr> - {{/if}} - {{#if model.perf.RenameOrMoveFiles}} - <tr> - <td>Rename Or Move Files</td> - <td>{{txt model.perf.RenameOrMoveFiles type="duration"}}</td> - </tr> - {{/if}} - </tbody> - </table> - - <br/> - - {{em-table - columns=columns - rows=rows - - rowCount=configs.length - definition=definition - - enablePagination=false - - searchAction="searchChanged" - sortAction="sortChanged" - }} + enablePagination=false + searchAction="searchChanged" + sortAction="sortChanged" + }} + {{else}} + <h2>Data not available to display Timeline!</h2> + <h4>You may be using an older version of Hive.</h4> + {{/if}} {{else}} {{partial "loading"}} http://git-wip-us.apache.org/repos/asf/tez/blob/17f428fb/tez-ui/src/main/webapp/tests/integration/components/query-timeline-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/integration/components/query-timeline-test.js b/tez-ui/src/main/webapp/tests/integration/components/query-timeline-test.js index 907896d..143f299 100644 --- a/tez-ui/src/main/webapp/tests/integration/components/query-timeline-test.js +++ b/tez-ui/src/main/webapp/tests/integration/components/query-timeline-test.js @@ -27,7 +27,12 @@ test('Basic creation test', function(assert) { this.set("perf", {}); this.render(hbs`{{query-timeline perf=perf}}`); - assert.equal(this.$().find(".bar").length, 10 + 4); + assert.equal(this.$().find(".bar").length, 9 + 4); + + this.set("perf", null); + this.render(hbs`{{query-timeline perf=perf}}`); + + assert.equal(this.$().find(".bar").length, 9 + 4); this.render(hbs` {{#query-timeline perf=perf}} @@ -35,17 +40,34 @@ test('Basic creation test', function(assert) { {{/query-timeline}} `); - assert.equal(this.$().find(".bar").length, 10 + 4); + assert.equal(this.$().find(".bar").length, 9 + 4); +}); + +test('Default value test', function(assert) { + this.set("perf", {}); + this.render(hbs`{{query-timeline perf=perf}}`); + + let bars = this.$().find(".sub-groups").find(".bar"); + assert.equal(bars.length, 9); + + assert.equal(bars[0].style.width, 0); + assert.equal(bars[1].style.width, 0); + assert.equal(bars[2].style.width, 0); + assert.equal(bars[3].style.width, 0); + assert.equal(bars[4].style.width, 0); + assert.equal(bars[5].style.width, 0); + assert.equal(bars[6].style.width, 0); + assert.equal(bars[7].style.width, 0); + assert.equal(bars[8].style.width, 0); }); test('alignBars test', function(assert) { - var total = 10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90 + 100; + var total = 10 + 20 + 40 + 50 + 60 + 70 + 80 + 90 + 100; var bars; this.set("perf", { "compile": 10, "parse": 20, - "semanticAnalyze": 30, "TezBuildDag": 40, "TezSubmitDag": 50, @@ -68,33 +90,31 @@ test('alignBars test', function(assert) { bars = this.$().find(".groups").find(".bar"); assert.equal(bars.length, 4); - assertWidth(bars[0], 10 + 20 + 30 + 40); + assertWidth(bars[0], 10 + 20 + 40); assertWidth(bars[1], 50 + 60); assertWidth(bars[2], 70); assertWidth(bars[3], 80 + 90 + 100); bars = this.$().find(".sub-groups").find(".bar"); - assert.equal(bars.length, 10); + assert.equal(bars.length, 9); assertWidth(bars[0], 10); assertWidth(bars[1], 20); - assertWidth(bars[2], 30); - assertWidth(bars[3], 40); - assertWidth(bars[4], 50); - assertWidth(bars[5], 60); - assertWidth(bars[6], 70); - assertWidth(bars[7], 80); - assertWidth(bars[8], 90); - assertWidth(bars[9], 100); + assertWidth(bars[2], 40); + assertWidth(bars[3], 50); + assertWidth(bars[4], 60); + assertWidth(bars[5], 70); + assertWidth(bars[6], 80); + assertWidth(bars[7], 90); + assertWidth(bars[8], 100); }); test('alignBars - without RenameOrMoveFiles test', function(assert) { - var total = 10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90; + var total = 10 + 20 + 40 + 50 + 60 + 70 + 80 + 90 + 0; var bars; this.set("perf", { "compile": 10, "parse": 20, - "semanticAnalyze": 30, "TezBuildDag": 40, "TezSubmitDag": 50, @@ -104,6 +124,7 @@ test('alignBars - without RenameOrMoveFiles test', function(assert) { "PostATSHook": 80, "RemoveTempOrDuplicateFiles": 90, + // RenameOrMoveFiles not added }); this.render(hbs`{{query-timeline perf=perf}}`); @@ -116,21 +137,46 @@ test('alignBars - without RenameOrMoveFiles test', function(assert) { bars = this.$().find(".groups").find(".bar"); assert.equal(bars.length, 4); - assertWidth(bars[0], 10 + 20 + 30 + 40); + assertWidth(bars[0], 10 + 20 + 40); assertWidth(bars[1], 50 + 60); assertWidth(bars[2], 70); assertWidth(bars[3], 80 + 90); bars = this.$().find(".sub-groups").find(".bar"); - assert.equal(bars.length, 10); + assert.equal(bars.length, 9); assertWidth(bars[0], 10); assertWidth(bars[1], 20); - assertWidth(bars[2], 30); - assertWidth(bars[3], 40); - assertWidth(bars[4], 50); - assertWidth(bars[5], 60); - assertWidth(bars[6], 70); - assertWidth(bars[7], 80); - assertWidth(bars[8], 90); - assertWidth(bars[9], 0); -}); \ No newline at end of file + assertWidth(bars[2], 40); + assertWidth(bars[3], 50); + assertWidth(bars[4], 60); + assertWidth(bars[5], 70); + assertWidth(bars[6], 80); + assertWidth(bars[7], 90); + assertWidth(bars[8], 0); +}); + +test('tables test', function(assert) { + this.set("perf", { + "PostATSHook": 80, + "RemoveTempOrDuplicateFiles": 90, + "RenameOrMoveFiles": 100, + }); + this.render(hbs`{{query-timeline perf=perf}}`); + + assert.equal(this.$().find("table").length, 4); + assert.equal(this.$().find(".detail-list").length, 4); + + assert.equal(this.$().find("table").find("td").length, 9 * 2); + assert.equal(this.$().find("table").find("i").length, 9); +}); + +test('tables post test', function(assert) { + this.set("perf", {}); + this.render(hbs`{{query-timeline perf=perf}}`); + + assert.equal(this.$().find("table").length, 4); + assert.equal(this.$().find(".detail-list").length, 4); + + assert.equal(this.$().find("table").find("td").length, 6 * 2); + assert.equal(this.$().find("table").find("i").length, 6); +});
