Skip to content

Commit

Permalink
Merge pull request #948 from gbrmachado/Bug1108764
Browse files Browse the repository at this point in the history
Bug 1108764 - Allow easy sharing of links to a specific log line in the log viewer
  • Loading branch information
tojon committed Sep 28, 2015
2 parents 82f45f7 + 4b1c450 commit 5af5d2e
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 11 deletions.
26 changes: 22 additions & 4 deletions ui/css/logviewer.css
Expand Up @@ -77,6 +77,24 @@ body {
white-space: pre;
}

.lv-line-num {
white-space: pre;
float: left;
align-items: center;
border-right: solid thin #e6e6e6;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
color: rgba(0, 0, 0, 0.3);
}

.lv-line-num:hover {
color: black;
background-color: #F8EEC7;
cursor: pointer;
}

.lv-error-line {
background-color: white;
color: #333333;
Expand All @@ -89,7 +107,7 @@ body {

.lv-log-container {
flex: 1;
overflow: auto;
overflow-x: auto;
font-family: monospace;
font-size: small;
background: #f8f8f8;
Expand All @@ -100,12 +118,12 @@ body {
}

/* Equal weight selector needs to follow the above nth-child() */
.lv-log-container > div.text-danger {
.lv-log-container > .lv-log-line > .text-danger {
background: #fbe3e3;
}

.lv-log-line {
padding: 0 18px;
.lv-log-container > div.lv-log-line > div.lv-line-text.lv-selected-lines {
background: #F8EEC7;
}

.lv-line-highlight {
Expand Down
90 changes: 87 additions & 3 deletions ui/js/controllers/logviewer.js
Expand Up @@ -25,14 +25,14 @@ logViewerApp.controller('LogviewerCtrl', [
$scope.job_id= query_string.job_id;
LogSlice = new ThLogSliceModel($scope.job_id, LINE_BUFFER_SIZE);
}

$scope.displayedLogLines = [];
$scope.loading = false;
$scope.logError = false;
$scope.jobExists = true;
$scope.currentLineNumber = 0;
$scope.highestLine = 0;
$scope.showSuccessful = true;
$scope.willScroll = false;

$scope.$watch('artifact', function () {
if (!$scope.artifact) {
Expand All @@ -41,6 +41,50 @@ logViewerApp.controller('LogviewerCtrl', [
$scope.showSuccessful = !$scope.hasFailedSteps();
});

$scope.$watch('[selectedBegin, selectedEnd]', function(newVal, oldVal) {
var newHash = (newVal[0] === newVal[1]) ? newVal[0] : newVal[0] + "-L" + newVal[1];
if (!isNaN(newVal[0])) {
$location.hash("L" + newHash);
} else if ($scope.artifact) {
$location.hash("");
}
});

$scope.$on("$locationChangeSuccess", function($event, $artifact) {
var oldLine = parseInt($scope.currentLineNumber);
getSelectedLines();

var newLine = parseInt($scope.selectedBegin);
var range = LINE_BUFFER_SIZE / 2;
if ((newLine <= (oldLine - range) || newLine >= oldLine + range) && !$scope.willScroll) {
if ($scope.artifact) {
$scope.displayedStep = getStepFromLine(newLine);
moveScrollToLineNumber(newLine, $event);
}
}
$scope.willScroll = false;
});

$scope.click = function(line, $event) {
$scope.willScroll = true;
if ($event.shiftKey) {
if (line.index < $scope.selectedBegin) {
$scope.selectedEnd = $scope.selectedBegin;
$scope.selectedBegin = line.index;
} else {
$scope.selectedEnd = line.index;
}
} else {
$scope.selectedBegin = $scope.selectedEnd = line.index;
}
};

// Erase the value of selectedBegin, used to erase the hash value when
// the user clicks on the error step button
$scope.eraseSelected = function() {
$scope.selectedBegin = 'undefined';
};

$scope.hasFailedSteps = function () {
var steps = $scope.artifact.step_data.steps;
for (var i = 0; i < steps.length; i++) {
Expand Down Expand Up @@ -213,7 +257,7 @@ logViewerApp.controller('LogviewerCtrl', [
// Make the log and job artifacts available
ThJobArtifactModel.get_list({job_id: $scope.job_id, name__in: 'text_log_summary,Job Info'})
.then(function(artifactList) {
artifactList.forEach(function(artifact) {
artifactList.forEach(function(artifact, $event) {
if (artifact.name === 'text_log_summary') {
$scope.artifact = artifact.blob;
$scope.step_data = artifact.blob.step_data;
Expand All @@ -229,7 +273,12 @@ logViewerApp.controller('LogviewerCtrl', [
});
} else {
$timeout(function() {
angular.element('.lv-error-line').first().trigger('click');
if (isNaN($scope.selectedBegin)) {
angular.element('.lv-error-line').first().trigger('click');
} else {
$scope.displayedStep = getStepFromLine($scope.selectedBegin);
moveScrollToLineNumber($scope.selectedBegin, $event);
}
}, 100);
}
}
Expand All @@ -243,6 +292,41 @@ logViewerApp.controller('LogviewerCtrl', [

/** utility functions **/

function moveScrollToLineNumber(linenumber, $event) {
$scope.currentLineNumber = linenumber;

$scope.loadMore({}).then(function () {
$timeout(function () {
var raw = $('.lv-log-container')[0];
var line = $('.lv-log-line[line="' + linenumber + '"]');
raw.scrollTop += line.offset().top - $('.run-data').outerHeight() -
$('.navbar').outerHeight() - 120;
});
});
}

function getStepFromLine(linenumber) {
var steps = $scope.artifact.step_data.steps;
for (var i = 1; i < steps.length; i++) {
if (steps[i].started_linenumber >= linenumber) {
return steps[i-1];
}
}
}

function getSelectedLines () {
var urlHash = $location.hash();
var regexSelectedlines = /L(\d+)(-L(\d+))?$/;
if (regexSelectedlines.test(urlHash)) {
var matchSelectedLines = urlHash.match(regexSelectedlines);
if (isNaN(matchSelectedLines[3])) {
matchSelectedLines[3] = matchSelectedLines[1];
}
$scope.selectedBegin = matchSelectedLines[1];
$scope.selectedEnd = matchSelectedLines[3];
}
}

function logFileLineCount () {
var steps = $scope.artifact.step_data.steps;
return steps[ steps.length - 1 ].finished_linenumber + 1;
Expand Down
7 changes: 4 additions & 3 deletions ui/partials/logviewer/lvLogLines.html
Expand Up @@ -2,9 +2,10 @@
ng-if="loading"> Loading... </div>

<div ng-repeat="lv_line in displayedLogLines"
ng-class="{'text-danger': (lv_line.hasError == true),
'lv-selected-lines': (displayedStep.order === lv_line.index)}"
class="lv-log-line"
line="{{ ::lv_line.index }}">
<span class="lv-line-text">{{ ::lv_line.text }}</span>
<div class="lv-line-num" ng-click="click(lv_line, $event)"> {{::lv_line.index}} </div>
<div ng-class="{'text-danger': (lv_line.hasError == true),
'lv-selected-lines': (lv_line.index >= selectedBegin && lv_line.index <= selectedEnd)}"
class="lv-line-text"> {{::lv_line.text}}</div>
</div>
2 changes: 1 addition & 1 deletion ui/partials/logviewer/lvLogSteps.html
Expand Up @@ -21,7 +21,7 @@
ng-mouseover="check=(step==displayedStep)"
ng-mouseleave="check=false"
ng-class="{'lv-line-highlight': check}"
ng-click="scrollTo($event, step, error.linenumber);"
ng-click="scrollTo($event, step, error.linenumber); eraseSelected()"
class="text-left pull-left lv-error-line">
<span class="label label-default lv-line-no text-left">
{{::error.linenumber}}
Expand Down

0 comments on commit 5af5d2e

Please sign in to comment.