Skip to content

Commit

Permalink
Proof of Concept: Interactive log viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
perlpunk committed Aug 13, 2024
1 parent 747a55e commit 933fdc9
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 3 deletions.
108 changes: 106 additions & 2 deletions assets/javascripts/test_result.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,14 +578,102 @@ function setupResult(jobid, state, result, status_url) {
setInfoPanelClassName(state, result);
}

function loadEmbeddedLogFiles() {
function delay(callback, ms) {
let timer = 0;
return function () {
const input = this;
const args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
callback.apply(input, args);
}, ms || 0);
};
}

function filterLogLines(input) {
if (input === undefined) {
return;
}
const string = input.value;
let regex = undefined;
const match = string.match(/^\/(.*)\/([i]*)$/);
if (match) {
regex = new RegExp(match[1], match[2]);
}
displaySearchInfo('Searching…');
$('.embedded-logfile').each(function (index, logFileElement) {
let content = logFileElement.dataset.content;
if (content === undefined) {
return;
}
if (string.length > 0) {
const lines = content.split(/\r?\n/);
const wanted = [];
for (let i = 0; i < lines.length; i++) {
if (regex) {
if (lines[i].match(regex)) {
wanted.push(lines[i]);
}
continue;
}
if (lines[i].includes(string)) {
wanted.push(lines[i]);
}
}
content = wanted.join('\n');
displaySearchInfo('Showing ' + wanted.length + ' / ' + lines.length + ' lines');
} else {
displaySearchInfo('');
}
logFileElement.innerHTML = ansiToHtml(content);
});
const fullCurrentUrl = window.location.href;
const currentUrl = fullCurrentUrl.split('#')[0];
const fragment = fullCurrentUrl.split('#')[1];
if (string.length > 0) {
window.location.href = `${currentUrl}#filter=${encodeURIComponent(string)}`;
} else {
if (fragment) {
// leaving off the # here would reload the page
window.location.href = currentUrl + '#';
}
}
}

function filterEmbeddedLogFiles() {
const searchBox = document.getElementById('search-log-file');
if (searchBox) {
const currentUrl = window.location.href;
const fragment = currentUrl.split('#')[1];
if (fragment) {
const params = fragment.split('&');
for (let i = 0; i < params.length; i++) {
const keyval = params[i].split('=');
if (keyval[0] === 'filter') {
searchBox.value = decodeURIComponent(keyval[1]);
}
}
}
}
const filter = function () {
filterLogLines(searchBox);
};
loadEmbeddedLogFiles(filter);
}

function loadEmbeddedLogFiles(filter) {
$('.embedded-logfile').each(function (index, logFileElement) {
if (logFileElement.dataset.contentsLoaded) {
return;
}
$.ajax(logFileElement.dataset.src)
.done(function (response) {
logFileElement.innerHTML = ansiToHtml(response);
logFileElement.dataset.content = response;
if (filter) {
filter();
} else {
logFileElement.innerHTML = ansiToHtml(response);
}
logFileElement.dataset.contentsLoaded = true;
})
.fail(function (jqXHR, textStatus, errorThrown) {
Expand All @@ -594,6 +682,22 @@ function loadEmbeddedLogFiles() {
});
}

window.onload = function () {
const searchBox = document.getElementById('search-log-file');
if (!searchBox) {
return;
}
const filter = function () {
filterLogLines(searchBox);
};
searchBox.addEventListener('keyup', delay(filter), 1000);
searchBox.addEventListener('change', filter, false);
};

function displaySearchInfo(text) {
document.getElementById('search-info').innerHTML = text;
}

function setCurrentPreviewFromStepLinkIfPossible(stepLink) {
if (tabConfiguration.details.hasContents && !stepLink.parent().is('.current_preview')) {
setCurrentPreview(stepLink.parent());
Expand Down
4 changes: 3 additions & 1 deletion templates/webapi/test/logfile.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
%= asset $_ for qw(test_result.js anser.js ansi-colors.css)
% end
% content_for 'ready_function' => begin
loadEmbeddedLogFiles();
filterEmbeddedLogFiles();
% end

% my $url = url_for('test_file', testid => $testid, filename => $filename);
<div class="corner-buttons" style="margin-top: -5px;">
<span id="search-info"></span>
<input id="search-log-file" placeholder="substring or /regex/i" type="search">
<a class="btn btn-light" href=".#downloads">
<i class="fa fa-chevron-left"></i> Back to job <%= $testid %>
</a>
Expand Down

0 comments on commit 933fdc9

Please sign in to comment.