NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name CloudTraceCustomizer
// @namespace 3DS
// @grant none
// @include *CloudTrace*.txt*
// @include *logfiles*cloudtrace*
// @include *CatLog.sh*LOG*
// @include *CatLog.sh*.log*
// @include *CatLog.sh*.trace*
// @include *CloudTrace*.txt
// @include *CloudTrace*.log
// @include *CatLog.sh*PodBuilder-buildprereqs*
// @include *CatLog.sh*PodBuilder*
// @license MIT
// @version 1.0
// @description custo CloudTrace : unite warnings/errors at the top + add anchors + find traces + highlight roles and steps
// @author pne1
// ==/UserScript==
// NB : pour pouvoir charger des fichiers locaux il faut "autoriser l'accès aux URL de fichier" dans les params de l'extention du navigateur
// TODO host script qq part + upgrade URL + test d'upgrade
// TODO mettre les groupes de traces (role, step) dans des div (plutot que style ligne par ligne)
// TODO test avec erreurs dans les roles
//
/***************************************** USER CHOICES **************************************************/
var showWarnings = false;
var showDoublons = false;
var stepColor = '#c3ad85';
var roleColor = '#85c3ad';
/********************************************************************************************************/
var dateStart = new Date();
var oneBoldElem, allBoldElements=[]/*allBoldElements = document.getElementsByTagName('b')*/;
var tempAnchor, anchor = "CloudTraceCustomizer";
var tempIdentifier, currentIdentifier, previousIdentifier;
var oneChild, container = document.createElement("p");
container.style.background='#85c3ad';
container.style.overflow='scroll';
container.innerHTML="<center><h1 style='color:#c3859b'>CloudTraceCustomizer</h1></center><p style='color:black; background:#c3ad85' id='CloudTraceCustomizerTracesLinks'>Links found : <br></p><p style='color:black; background:#c3ad85' id='CloudTraceCustomizerInfos'></p><button id='displayErrors' onClick='document.displayErrors()'>Display Errors</button><button id='displayWarnings' onClick='document.displayWarnings(false)'>Display Warnings</button><button id='displayDoublons' onClick='document.displayDoublons(true)'>Hide Doublons</button><p id='allErrors' /><p id='allWarnings' />";
document.body.insertBefore(container, document.body.firstChild);
var allErrors = document.getElementById('allErrors');
var allWarnings = document.getElementById('allWarnings');
var btnWarnings = document.getElementById('displayWarnings');
var btnErrors = document.getElementById('displayErrors');
var links = document.getElementById('CloudTraceCustomizerTracesLinks');
var firstChild = container.lastChild;
var oneLink, allLinks = document.getElementsByTagName('a');
var linksToTrace = document.createElement("p");
for (var i = 0 ; i < allLinks.length ; i++) {
oneLink = allLinks[i];
oneChild = document.createElement("p");
oneChild.innerHTML = oneLink.outerHTML;
// if (oneLink.innerText.indexOf("Trace") != -1 || oneLink.innerText.indexOf("TRACE") != -1 || oneLink.innerText.indexOf("temporary link") != -1)
if (oneLink.innerText != "BOTTOM" && oneLink.innerText != "REFRESH")
linksToTrace.append(oneChild);
}
function displayTruc(hide,elem,btn){
if (hide || !elem.style.display) {
elem.style.display='none';
btn.innerText=btn.innerText.replace("Hide","Display");
}
else {
elem.style.display='';
btn.innerText=btn.innerText.replace("Display","Hide");
}
}
function displayWarnings(hide){
displayTruc(hide,allWarnings,btnWarnings);
}
function displayErrors(hide,elem){
displayTruc(hide,allErrors,btnErrors);
}
document.displayErrors=displayErrors;
document.displayWarnings=displayWarnings;
displayWarnings(true);
displayErrors(true);
function manageEW(allBoldElements) { // 2020 change : cloudtraces W and E are not bold anymore
for (var i = 0 ; i < allBoldElements.length ; i++) {
tempAnchor = anchor+i;
oneBoldElem = allBoldElements[i];
oneChild = document.createElement("a");
oneChild.type = oneBoldElem.type;//oneBoldElem.innerText.slice(1,2);
oneChild.classList.add("CloudTraceCustomizer");
if (oneChild.type == "W") oneChild.classList.add("warning");
else if(oneChild.type == "E") oneChild.classList.add("error");
else {console.log("Unknown type : "+oneChild.type); oneChild.classList.add("info");}
oneBoldElem.id = tempAnchor;
oneChild.href = "#"+tempAnchor;
tempIdentifier = oneBoldElem.innerText.slice(5,oneBoldElem.innerText.length);
currentIdentifier = tempIdentifier.slice(0,tempIdentifier.indexOf(']'));
oneChild.innerHTML = "<pre>" + (previousIdentifier == currentIdentifier ? '' : '<br><br>') + oneBoldElem.innerHTML + "</pre><hr>";
previousIdentifier = currentIdentifier;
//container.insertBefore(oneChild, firstChild);
if (oneChild.type == "W") {
oneChild.classList.add("warning");
allWarnings.append(oneChild);
}
else if(oneChild.type == "E") {
oneChild.classList.add("error");
allErrors.append(oneChild);
}
else {console.log("Unknown type : "+oneChild.type); oneChild.classList.add("info");}
}
var infos = document.getElementById('CloudTraceCustomizerInfos');
if (allErrors.children.length ||allWarnings.children.length)
infos.innerText = "Found "+document.getElementsByClassName("warning").length+" [W]"+" and "+document.getElementsByClassName("error").length+ " [E]. Click on a line to go to its original place";
if (!allErrors.children.length) btnErrors.style.display="none";
else btnErrors.innerText += " ("+allErrors.children.length+")";
if (!allWarnings.children.length) btnWarnings.style.display="none";
else btnWarnings.innerText += " ("+allWarnings.children.length+")";
}
if (!linksToTrace.children.length) links.style.display='none';
else links.append(linksToTrace);
document.displayDoublons = function (dontDisplay) {
var allCloudTraceCustomizer = document.getElementsByClassName('CloudTraceCustomizer');
var currentElem, currentContent, previousContent;
var doublonFound=false;
for (var i = 0 ; i < allCloudTraceCustomizer.length ; i++) {
currentElem = allCloudTraceCustomizer[i];
if (!showWarnings && currentElem.className.indexOf('warning') != -1) continue;
currentContent = currentElem.getElementsByTagName('font')[0].innerText;
if (!currentContent || previousContent && previousContent.replace(/\s+/g, '') == currentContent.replace(/\s+/g, '')) {
currentElem.style.display = dontDisplay ? "none" : "";
doublonFound = true;
}
previousContent = currentContent;
}
var button = document.getElementById('displayDoublons');
if (!doublonFound) return button.style.display='none';
else button.style.display='';
button.onclick=function(){document.displayDoublons(!dontDisplay);};
button.innerText=dontDisplay ? "Show Doublons" : "Hide Doublons";
};
if (!showDoublons) document.displayDoublons(true);
/*document.displayWarnings = function (dontDisplay) {
showWarnings = !dontDisplay;
var allWarnings = document.getElementsByClassName('warning');
for (var i = 0 ; i < allWarnings.length ; i++)
allWarnings[i].style.display=dontDisplay ? "none" : "";
var button = document.getElementById('displayWarnings');
button.onclick=function(){document.displayWarnings(!dontDisplay);};
button.innerText=dontDisplay ? "Show Warnings" : "Hide Warnings";
document.displayDoublons(!showDoublons);
};
if (!document.getElementsByClassName('warning').length)
document.getElementById('displayWarnings').style.display='none';
else if (!showWarnings) document.displayWarnings(true);*/
///////////////////
var getDateFromTrace = function (trace) {
return new Date(trace.substr(0,23));
};
////////////////////////////////////////
var customTraces = document.createElement('p');
customTraces.id = "customTraces";
var actualTraces = document.getElementsByTagName('pre')[0]; //TODO check if several <pre> and loop
for (var i = 0 ; i < actualTraces.children.length ; i++) // deplace tout ce qui n'est pas du texte (les PodRelocationTable... )
document.body.append(actualTraces.children[i]);
var rolesSummary = document.createElement('p');
rolesSummary.id = "rolesSummary";
var rolesSummaryPostCfg = document.createElement('ul');
rolesSummaryPostCfg.id="rolesSummaryPostCfg";
/*var rolesSummaryDeploy = document.createElement('ul');
rolesSummaryDeploy.id="rolesSummaryDeploy";
var rolesSummaryBuild = document.createElement('ul');
rolesSummaryBuild.id="rolesSummaryBuild";*/
var actualTracesTab = actualTraces.innerText.split('\n');
var oneTrace, oneCustomTrace, roleName, roleNameText, roleLinkToEnd, roleLinkToStart, roleId=0;
var traceInRole = false, traceInStep=false;
var stepName, stepLinkToEnd, stepId=0;
var allRoles = [];
for ( var i = 0 ; i < actualTracesTab.length ; i++ ) {
oneTrace = actualTracesTab[i];
oneCustomTrace = document.createElement('pre');
oneCustomTrace.classList.add("oneCustomTrace");
oneCustomTrace.innerText = oneTrace;
if (oneTrace.indexOf('[W]') != -1) {
oneCustomTrace.type='W';
allBoldElements.push(oneCustomTrace);
} else if (oneTrace.indexOf('[E]') != -1) {
oneCustomTrace.type='E';
allBoldElements.push(oneCustomTrace);
}
//////// find roles
//start role
isDeployRole = oneTrace.indexOf('>addVMRole:') != -1;
isBuildRole = oneTrace.indexOf('getXmlScriptPath:') != -1 && oneTrace.indexOf('.xml') != -1 ;
isPostCfgRole = oneTrace.indexOf('>executePostcfg') != -1;
if (isDeployRole || isBuildRole || isPostCfgRole) {
if (traceInRole) oneCustomTrace.id="EndRole"+roleId; // close previous role (if no '<executeXML:'||'<AddVMRole: end' was found) // pas top pour les multiples rôles dans une opération
if (traceInStep) {
oneCustomTrace.id="step"+stepId; // close previous step (if no '<executeStep:' was found)
traceInStep=false;
}
traceInRole = true;
roleId++;
roleName = document.createElement('h2');
if (isDeployRole)
roleNameText = oneTrace.substr(oneTrace.indexOf('roleName=')+9);
else if (isBuildRole)
roleNameText = oneTrace.substr(oneTrace.lastIndexOf('/')+1).slice(0,-4);
else if (isPostCfgRole)
roleNameText = oneTrace.substr(oneTrace.lastIndexOf('postcfgName=')+12);
roleName.innerText = roleNameText;
roleLinkToEnd = document.createElement("a");
roleLinkToEnd.innerText = " ↓";
roleLinkToEnd.href="#EndRole"+roleId;
roleName.append(roleLinkToEnd);
roleName.id="StartRole"+roleId;
oneCustomTrace.prepend(roleName);
allRoles.push({roleId:roleId,roleNameText:roleNameText,elapsed:0,dateStart:getDateFromTrace(oneTrace),dateEnd:null,isDeployRole:isDeployRole,isBuildRole:isBuildRole,isPostCfgRole:isPostCfgRole});
/* if (isDeployRole) rolesSummaryDeploy.append(roleLI);
else if (isBuildRole) rolesSummaryBuild.append(roleLI);
else if (isPostCfgRole) rolesSummaryPostCfg.append(roleLI);*/
}
//in a role
if (traceInRole) oneCustomTrace.classList.add("traceInRole");
//end role
if (traceInRole)
if (oneTrace.indexOf('<AddVMRole: end') != -1 || oneTrace.indexOf('<executeXML') != -1 || !isBuildRole && oneTrace.indexOf('getXmlScriptPath:') != -1 || oneTrace.indexOf('<ExecutePostConfig: end') != -1) {
traceInRole = false;
traceInStep = false;
oneCustomTrace.id="EndRole"+roleId;
if (allRoles.length) {
if (allRoles[allRoles.length -1].dateEnd) console.error("dateEnd is already set ! "+JSON.stringify(allRoles[allRoles.length -1]));
else allRoles[allRoles.length -1].dateEnd = getDateFromTrace(oneTrace);
allRoles[allRoles.length -1].elapsed = (allRoles[allRoles.length -1].dateEnd - allRoles[allRoles.length -1].dateStart) / 1;
}
}
//////// find steps
if (oneTrace.indexOf('executeStep: EXECUTING step #') != -1) {
if (traceInStep) oneCustomTrace.id="step"+stepId; // close previous step (if no '<executeStep:' was found)
traceInStep = true;
stepId++;
stepName = document.createElement('h3');
stepName.innerText = oneTrace.substr(oneTrace.indexOf('executeStep')+23,oneTrace.length);
stepLinkToEnd = document.createElement("a");
stepLinkToEnd.innerText = " ↓";
stepLinkToEnd.href="#"+"step"+stepId;
stepName.append(stepLinkToEnd);
oneCustomTrace.prepend(stepName);
}
if (traceInStep) oneCustomTrace.classList.add("traceInStep");
if (oneTrace.indexOf('<executeStep:') != -1 || oneTrace.indexOf('<ExecutePostConfig:') != -1) {
traceInStep = false;
oneCustomTrace.id="step"+stepId;
}
else if (oneTrace.indexOf('run (CloudUtils.java): stdout:') != -1 ) {
var parts = oneCustomTrace.innerText.split("stdout:");
oneCustomTrace.innerHTML = parts[0] + '<i>' + parts[1] + '</i>';
}
else if (oneTrace.indexOf('run (CloudUtils.java): stderr:') != -1 ) {
var parts = oneCustomTrace.innerText.split("stderr:");
oneCustomTrace.innerHTML = parts[0] + '<i><font color="red">' + parts[1] + '</font></i>';
}
////////////////////////////
if (oneTrace.indexOf('printStackTrace') != -1) {
oneCustomTrace.classList.add("error");
container.insertBefore(oneCustomTrace, firstChild);
}
customTraces.append(oneCustomTrace);
}
manageEW(allBoldElements);
document.body.append(customTraces);
customTraces.style.background='white';
actualTraces.style.display='none';
console.table(allRoles);
var role;
for (var i in allRoles) { // populate "roles found" menu
role = allRoles[i];
roleLI = document.createElement('li');
roleLI.innerHTML = "<a href='#StartRole"+role.roleId+"'>"+role.roleNameText+"</a><span> "+role.elapsed+"ms</span>";
rolesSummaryPostCfg.append(roleLI);
if (role.isDeployRole) roleLI.classList.add("rolesSummaryDeploy");
else if (role.isBuildRole) roleLI.classList.add("rolesSummaryBuild");
else if (role.isPostCfgRole) roleLI.classList.add("rolesSummaryPostCfg");
}
rolesSummary.append(rolesSummaryPostCfg);
/*rolesSummary.append(rolesSummaryDeploy);
rolesSummary.append(rolesSummaryBuild);*/
var summary = document.createElement('p');
summary.innerHTML = "<a onclick='toggleDisplayRoles()' style='cursor:pointer;'><button id='btnRolist'>Display roles list(<span id='rolesQty'>"+allRoles.length+"</span>)</button></a>";
rolesSummary.style.display = 'none';
summary.append(rolesSummary);
container.append(summary);
var btnRolist = document.getElementById('btnRolist');
toggleDisplayRoles = function () {
if (rolesSummary.style.display == 'none') {
rolesSummary.style.display = "inline-block";
btnRolist.innerText=btnRolist.innerText.replace("Display","Hide");
}
else {
rolesSummary.style.display = 'none';
btnRolist.innerText=btnRolist.innerText.replace("Hide","Display");
}
}
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.oneCustomTrace { margin: 0; white-space: pre-wrap; word-break: break-word }';
style.innerHTML+= '#customTraces { }';
style.innerHTML+= '.traceInRole {background: '+roleColor+';}';
style.innerHTML+= '.traceInStep {background: '+stepColor+'; margin-left:0}';
style.innerHTML+= 'h2,h3 {text-align:center; margin:0}';
style.innerHTML+= 'li.rolesSummaryDeploy a {color : blue}';
style.innerHTML+= 'li.rolesSummaryBuild a {color : lightblue}';
style.innerHTML+= 'li.rolesSummaryPostCfg a {color : darkblue}';
document.getElementsByTagName('head')[0].appendChild(style);
var duration = (new Date()) - dateStart;
console.log("duration : "+duration+"ms");