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");