Initial Checkin
This commit is contained in:
177
RivBedAuto.tempermonkey - 2018-12-26.js
Normal file
177
RivBedAuto.tempermonkey - 2018-12-26.js
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
// ==UserScript==
|
||||||
|
// @name AutoPerfReports
|
||||||
|
// @namespace http://tampermonkey.net/
|
||||||
|
// @version 0.1
|
||||||
|
// @description Automatically pull data out of Riverbed for the previous day.
|
||||||
|
// @author joe.tretter@kcc.com
|
||||||
|
// @match https://ttw.gws.kcc.com/*
|
||||||
|
// @grant window.close
|
||||||
|
// ==/UserScript==
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
console.log("Start");
|
||||||
|
let today = new Date();
|
||||||
|
let simulateDate = new Date();
|
||||||
|
|
||||||
|
// simulation is using yesterday's date.
|
||||||
|
simulateDate.setDate(today.getDate() - 1);
|
||||||
|
simulateDate = new Date(simulateDate.getFullYear(), simulateDate.getMonth(), simulateDate.getDate());
|
||||||
|
|
||||||
|
let timestamp = simulateDate.getTime() / 1000;
|
||||||
|
|
||||||
|
let rivUrl = "https://ttw.gws.kcc.com/#search:time=" + timestamp + "+1435&search=Hello&server=ustca089.kcc.com&serverTableKey=ustca089.kcc.com";
|
||||||
|
|
||||||
|
window.location.href = rivUrl;
|
||||||
|
|
||||||
|
// no cleartext password
|
||||||
|
function encryptXor(text, key) {
|
||||||
|
return Array.from(
|
||||||
|
text,
|
||||||
|
(c, i) => String.fromCharCode(c.charCodeAt() ^ key.charCodeAt(i % key.length))
|
||||||
|
).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the login dialog pops up -> log in.
|
||||||
|
function loginThread(credentials) {
|
||||||
|
let myInterval;
|
||||||
|
myInterval= window.setInterval(()=>{
|
||||||
|
if (document.getElementById("usernameField") !== null) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
document.getElementById("usernameField").value=credentials.username;
|
||||||
|
document.getElementById("passwordField").value=encryptXor(credentials.passwordCrypt, '5346245634634765377');
|
||||||
|
document.getElementById("loginSubmitBtn").click();
|
||||||
|
}
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// I have not found a reliable way to see if the page is ready than polling...
|
||||||
|
function execQuery(theQuery) {
|
||||||
|
let myInterval;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
myInterval = window.setInterval(() => {
|
||||||
|
if (document.getElementsByClassName("gwt-SuggestBox EKM0XQC-tb-f").length === 1) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
// even if the screen is loaded, if we are too fast it will be too fast for the javascript of the page...
|
||||||
|
window.setTimeout(function(){
|
||||||
|
console.log("ExecQuery ",theQuery);
|
||||||
|
let theSearchField = document.getElementsByClassName("gwt-SuggestBox EKM0XQC-tb-f")[0];
|
||||||
|
|
||||||
|
theSearchField.value = theQuery;
|
||||||
|
|
||||||
|
let theSearchButton = document.getElementsByClassName("gwt-Button EKM0XQC-e-d")[0];
|
||||||
|
theSearchButton.click();
|
||||||
|
resolve();
|
||||||
|
},5000);
|
||||||
|
} else {
|
||||||
|
console.log("Waiting for Query field",theQuery);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// I have not found a reliable way to see if the data is ready than polling...
|
||||||
|
function downloadResultsCsv(theName) {
|
||||||
|
let myInterval;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
myInterval = window.setInterval(() => {
|
||||||
|
let pTag = document.getElementsByTagName("P");
|
||||||
|
if (pTag.length > 0) {
|
||||||
|
console.log("Ready", theName, pTag);
|
||||||
|
clearInterval(myInterval);
|
||||||
|
let theCsvUrl = pTag[0].firstChild.href;
|
||||||
|
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
console.log("Length of response ",this.responseText.length);
|
||||||
|
// to be able to give the file a custom name I load it into a blob first, otherwise it will always save with the generic name.
|
||||||
|
let blob = new Blob([this.responseText], {
|
||||||
|
type: 'text/plain'
|
||||||
|
});
|
||||||
|
let anchor = document.createElement('a');
|
||||||
|
|
||||||
|
anchor.download = theName + "-" + simulateDate.getFullYear() + "-" + (1+simulateDate.getMonth()) + "-" + simulateDate.getDate() + ".csv";
|
||||||
|
anchor.href = window.URL.createObjectURL(blob);
|
||||||
|
anchor.dataset.downloadurl = ['text/plain', anchor.download, anchor.href].join(':');
|
||||||
|
anchor.click();
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhttp.open("GET", theCsvUrl, true);
|
||||||
|
xhttp.send();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log("Waiting for Results",theName);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let allQueriesAndNames = [
|
||||||
|
{
|
||||||
|
name: 'PrmMainBo.Save',
|
||||||
|
query: " ! ( class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Activate' ) and ! ( class.method = 'Cas.BusinessLogic.Prm.PrmMainBo.Copy' ) and ( class.method = 'Cas.BusinessLogic.Prm.PrmMainBo.Save' ) and ( instance = 'ACNCASWebSite#LAOProdServer' ) | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmMainBo.Save -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayMainBo.Save',
|
||||||
|
query: " class.method = 'Cas.BusinessLogic.Pay.PayMainBo.Save' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Pay.PayMainBo.Save -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ClcCalculationBo.Calculation',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Calculation' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Calculation -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmTacticView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmTacticView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmTacticView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmTacticView.AddViewItem',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmTacticView.AddViewItem' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmTacticView.AddViewItem -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmProductAllView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmProductAllView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmProductAllView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmProductAllView.AddViewItem',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmProductAllView.AddViewItem' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmProductAllView.AddViewItem -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BpaMyPaymentMassCreationView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Bpa.BpaMyPaymentMassCreationView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Bpa.BpaMyPaymentMassCreationView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Password is encrypted with XOR to preent "accidental" revelation
|
||||||
|
let credentials={username:"U15020",passwordCrypt:"wYTFFUX"};
|
||||||
|
loginThread(credentials);
|
||||||
|
|
||||||
|
let allDone = new Promise((allResolve,allReject)=>{
|
||||||
|
// Loop over all queries one by one considering the promise resolution: have to execute them in sequence!
|
||||||
|
for (let i=0,p=Promise.resolve();i<allQueriesAndNames.length; i++){
|
||||||
|
p = p.then(_ => new Promise(resolve => {let theQueryAndName=allQueriesAndNames[i];
|
||||||
|
console.log("Executing", theQueryAndName);
|
||||||
|
execQuery(theQueryAndName.query).then(() => {
|
||||||
|
downloadResultsCsv(theQueryAndName.name).then(() => {
|
||||||
|
console.log("Done ", theQueryAndName,i,allQueriesAndNames.length)
|
||||||
|
resolve();
|
||||||
|
if (i===(allQueriesAndNames.length-1)) {
|
||||||
|
console.log("All Done.");
|
||||||
|
allResolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
};}
|
||||||
|
);
|
||||||
|
|
||||||
|
// if we are all finished then we can close the window.
|
||||||
|
allDone.then(()=>{
|
||||||
|
console.log("Closing window");
|
||||||
|
// this doesn't work, Chrome doesn't allow me to close the last window, worked around that by killing the task in the scheduling...
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
206
RivBedAuto.tempermonkey - 2018-12-27.js
Normal file
206
RivBedAuto.tempermonkey - 2018-12-27.js
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
// ==UserScript==
|
||||||
|
// @name AutoPerfReports
|
||||||
|
// @namespace http://tampermonkey.net/
|
||||||
|
// @version 0.2
|
||||||
|
// @description Automatically pull data out of Riverbed for the previous day.
|
||||||
|
// @author joe.tretter@kcc.com
|
||||||
|
// @match https://ttw.gws.kcc.com/*
|
||||||
|
// @grant window.close
|
||||||
|
// ==/UserScript==
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
console.log("Start");
|
||||||
|
let today = new Date();
|
||||||
|
let simulateDate = new Date();
|
||||||
|
|
||||||
|
// simulation is using yesterday's date.
|
||||||
|
simulateDate.setDate(today.getDate() - 1);
|
||||||
|
|
||||||
|
// To overwrite the simulate date uncomment the below and change the date (remember that the month starts at 0!
|
||||||
|
//simulateDate = new Date(2018,11,1);
|
||||||
|
|
||||||
|
simulateDate = new Date(simulateDate.getFullYear(), simulateDate.getMonth(), simulateDate.getDate());
|
||||||
|
|
||||||
|
let timestamp = simulateDate.getTime() / 1000;
|
||||||
|
|
||||||
|
let rivUrl = "https://ttw.gws.kcc.com/#search:time=" + timestamp + "+1435&search=Hello&server=ustca089.kcc.com&serverTableKey=ustca089.kcc.com";
|
||||||
|
|
||||||
|
window.location.href = rivUrl;
|
||||||
|
|
||||||
|
// no cleartext password
|
||||||
|
function encryptXor(text, key) {
|
||||||
|
return Array.from(
|
||||||
|
text,
|
||||||
|
(c, i) => String.fromCharCode(c.charCodeAt() ^ key.charCodeAt(i % key.length))
|
||||||
|
).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the login dialog pops up -> log in.
|
||||||
|
function loginThread(credentials) {
|
||||||
|
let myInterval;
|
||||||
|
myInterval= window.setInterval(()=>{
|
||||||
|
// if the login dialog comes up again in less than 10 seconds we assume the password changed and don't retry automatically to prevent account locking.
|
||||||
|
if ((localStorage.getItem("LastLoginDate") !== null) && ((new Date().getTime() - localStorage.getItem("LastLoginDate")) / 1000 < 10 )) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
window.document.title="[RiverRobot] Login unsuccessful.";
|
||||||
|
console.log("Login unsuccessful.");
|
||||||
|
} else {
|
||||||
|
window.document.title="[RiverRobot] Logging In";
|
||||||
|
localStorage.setItem("LastLoginDate",new Date().getTime())
|
||||||
|
if (document.getElementById("usernameField") !== null) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
document.getElementById("usernameField").value=credentials.username;
|
||||||
|
document.getElementById("passwordField").value=encryptXor(credentials.passwordCrypt, '5346245634634765377');
|
||||||
|
document.getElementById("loginSubmitBtn").click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// I have not found a reliable way to see if the page is ready other than polling...
|
||||||
|
function execQuery(theQuery) {
|
||||||
|
let myInterval;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
myInterval = window.setInterval(() => {
|
||||||
|
if (document.getElementsByClassName("gwt-SuggestBox EKM0XQC-tb-f").length === 1) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
// even if the screen is loaded, if we are too fast it will be too fast for the javascript of the page...
|
||||||
|
window.setTimeout(function(){
|
||||||
|
window.document.title="[RiverRobot] Executing Query " + theQuery;
|
||||||
|
console.log("ExecQuery ",theQuery);
|
||||||
|
let theSearchField = document.getElementsByClassName("gwt-SuggestBox EKM0XQC-tb-f")[0];
|
||||||
|
|
||||||
|
theSearchField.value = theQuery;
|
||||||
|
|
||||||
|
let theSearchButton = document.getElementsByClassName("gwt-Button EKM0XQC-e-d")[0];
|
||||||
|
theSearchButton.click();
|
||||||
|
resolve();
|
||||||
|
},5000);
|
||||||
|
} else {
|
||||||
|
window.document.title="[RiverRobot] Waiting for Query field " + theQuery;
|
||||||
|
console.log("Waiting for Query field",theQuery);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// I have not found a reliable way to see if the data is ready than polling...
|
||||||
|
function downloadResultsCsv(theName) {
|
||||||
|
let myInterval;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
myInterval = window.setInterval(() => {
|
||||||
|
let clsErrorEle = document.getElementsByClassName("pluginErrorStringBlack");
|
||||||
|
if (clsErrorEle.length > 0) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
let errText=clsErrorEle[0].innerText ;
|
||||||
|
console.log("While waiting for results of " + theName + " Page shows error: " + errText + " -> Proceeding to next");
|
||||||
|
resolve(errText);
|
||||||
|
}
|
||||||
|
let pTag = document.getElementsByTagName("P");
|
||||||
|
if (pTag.length > 0) {
|
||||||
|
console.log("Ready", theName, pTag);
|
||||||
|
window.document.title="[RiverRobot] Downloading Results " + theName;
|
||||||
|
clearInterval(myInterval);
|
||||||
|
let theCsvUrl = pTag[0].firstChild.href;
|
||||||
|
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
console.log("Length of response ",this.responseText.length);
|
||||||
|
// to be able to give the file a custom name I load it into a blob first, otherwise it will always save with the generic name.
|
||||||
|
let blob = new Blob([this.responseText], {
|
||||||
|
type: 'text/plain'
|
||||||
|
});
|
||||||
|
let anchor = document.createElement('a');
|
||||||
|
|
||||||
|
anchor.download = theName + "-" + simulateDate.getFullYear() + "-" + (1+simulateDate.getMonth()) + "-" + simulateDate.getDate() + ".csv";
|
||||||
|
anchor.href = window.URL.createObjectURL(blob);
|
||||||
|
anchor.dataset.downloadurl = ['text/plain', anchor.download, anchor.href].join(':');
|
||||||
|
anchor.click();
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhttp.open("GET", theCsvUrl, true);
|
||||||
|
xhttp.send();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
window.document.title="[RiverRobot] Waiting for Results " + theName;
|
||||||
|
console.log("Waiting for Results",theName);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let allQueriesAndNames = [
|
||||||
|
{
|
||||||
|
name: 'PrmMainBo.Save',
|
||||||
|
query: " ! ( class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Activate' ) and ! ( class.method = 'Cas.BusinessLogic.Prm.PrmMainBo.Copy' ) and ( class.method = 'Cas.BusinessLogic.Prm.PrmMainBo.Save' ) and ( instance = 'ACNCASWebSite#LAOProdServer' ) | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmMainBo.Save -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayMainBo.Save',
|
||||||
|
query: " class.method = 'Cas.BusinessLogic.Pay.PayMainBo.Save' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Pay.PayMainBo.Save -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ClcCalculationBo.Calculation',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Calculation' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Calculation -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ClcCalculationEngineBo.UpdateSummaryForPeriod',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.UpdateSummaryForPeriod' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Clc.ClcCalculationEngineBo.UpdateSummaryForPeriod -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmTacticView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmTacticView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmTacticView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmTacticView.AddViewItem',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmTacticView.AddViewItem' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmTacticView.AddViewItem -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmProductAllView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmProductAllView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmProductAllView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmProductAllView.AddViewItem',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmProductAllView.AddViewItem' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmProductAllView.AddViewItem -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BpaMyPaymentMassCreationView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Bpa.BpaMyPaymentMassCreationView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Bpa.BpaMyPaymentMassCreationView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Password is encrypted with XOR to preent "accidental" revelation
|
||||||
|
let credentials={username:"U15020",passwordCrypt:"wYTFFUX"};
|
||||||
|
loginThread(credentials);
|
||||||
|
|
||||||
|
let allDone = new Promise((allResolve,allReject)=>{
|
||||||
|
// Loop over all queries one by one considering the promise resolution: have to execute them in sequence!
|
||||||
|
for (let i=0,p=Promise.resolve();i<allQueriesAndNames.length; i++){
|
||||||
|
p = p.then(_ => new Promise(resolve => {let theQueryAndName=allQueriesAndNames[i];
|
||||||
|
console.log("Executing", theQueryAndName);
|
||||||
|
execQuery(theQueryAndName.query).then(() => {
|
||||||
|
downloadResultsCsv(theQueryAndName.name).then(() => {
|
||||||
|
console.log("Done ", theQueryAndName,i,allQueriesAndNames.length)
|
||||||
|
resolve();
|
||||||
|
if (i===(allQueriesAndNames.length-1)) {
|
||||||
|
console.log("All Done.");
|
||||||
|
allResolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
};}
|
||||||
|
);
|
||||||
|
|
||||||
|
// if we are all finished then we can close the window.
|
||||||
|
allDone.then(()=>{
|
||||||
|
window.document.title="[RiverRobot] DONE";
|
||||||
|
console.log("Closing window");
|
||||||
|
// this doesn't work, Chrome doesn't allow me to close the last window, worked around that by killing the task in the scheduling...
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
223
RivBedAuto.tempermonkey.js
Normal file
223
RivBedAuto.tempermonkey.js
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
// ==UserScript==
|
||||||
|
// @name AutoPerfReports
|
||||||
|
// @namespace http://tampermonkey.net/
|
||||||
|
// @version 0.4
|
||||||
|
// @description Automatically pull data out of Riverbed for the previous day.
|
||||||
|
// @author joe.tretter@kcc.com
|
||||||
|
// @match https://ttw.gws.kcc.com/*
|
||||||
|
// @grant window.close
|
||||||
|
// ==/UserScript==
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
console.log("Start");
|
||||||
|
let today = new Date();
|
||||||
|
let simulateDate = new Date();
|
||||||
|
|
||||||
|
// simulation is using yesterday's date.
|
||||||
|
simulateDate.setDate(today.getDate() - 1);
|
||||||
|
|
||||||
|
// To overwrite the simulate date uncomment the below and change the date (remember that the month starts at 0!
|
||||||
|
//simulateDate = new Date(2018,11,1);
|
||||||
|
|
||||||
|
simulateDate = new Date(simulateDate.getFullYear(), simulateDate.getMonth(), simulateDate.getDate());
|
||||||
|
|
||||||
|
let timestamp = simulateDate.getTime() / 1000;
|
||||||
|
|
||||||
|
let rivUrl = "https://ttw.gws.kcc.com/#search:time=" + timestamp + "+1435&search=Hello&server=ustca089.kcc.com&serverTableKey=ustca089.kcc.com";
|
||||||
|
|
||||||
|
window.location.href = rivUrl;
|
||||||
|
|
||||||
|
// no cleartext password
|
||||||
|
function encryptXor(text, key) {
|
||||||
|
return Array.from(
|
||||||
|
text,
|
||||||
|
(c, i) => String.fromCharCode(c.charCodeAt() ^ key.charCodeAt(i % key.length))
|
||||||
|
).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the login dialog pops up -> log in.
|
||||||
|
function loginThread(credentials) {
|
||||||
|
let myInterval;
|
||||||
|
myInterval= window.setInterval(()=>{
|
||||||
|
if (document.getElementById("usernameField") !== null) {
|
||||||
|
// If we don't have credentials saved we ask for credentials.
|
||||||
|
// If the login dialog comes up again in less than 10 seconds we assume the password changed and don't retry automatically to prevent account locking.
|
||||||
|
if ((credentials === null) || ((localStorage.getItem("LastLoginDate") !== null) && ((new Date().getTime() - localStorage.getItem("LastLoginDate")) / 1000 < 10 ))) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
window.document.title="[RiverRobot] Login unsuccessful.";
|
||||||
|
console.log("Login unsuccessful.");
|
||||||
|
document.getElementById("loginSubmitBtn").value="RiverRobot - Save Credentials + Login";
|
||||||
|
|
||||||
|
// change the Form tag to a div tag so that we can run some javascript rather than submit the form.
|
||||||
|
var theForm = document.getElementsByTagName('form')[0];
|
||||||
|
var theContainer = document.createElement('div');
|
||||||
|
theContainer.classList="module";
|
||||||
|
theContainer.innerHTML = theForm.innerHTML;
|
||||||
|
theForm.parentNode.replaceChild(theContainer, theForm);
|
||||||
|
|
||||||
|
// Credentials are stored encrypted in the Browsen's localstorage (yes, it's NOT safe, but it's a hurdle)
|
||||||
|
document.getElementById("loginSubmitBtn").onclick=function(){
|
||||||
|
credentials={username:document.getElementById("usernameField").value,passwordCrypt:encryptXor(document.getElementById("passwordField").value, '5346245634634765377')};
|
||||||
|
localStorage.setItem("riverRobotCredentials",JSON.stringify(credentials));
|
||||||
|
alert('Credentials Saved.');
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
document.getElementById("loginSubmitBtn").onkeydown=onclick;
|
||||||
|
} else {
|
||||||
|
window.document.title="[RiverRobot] Logging In";
|
||||||
|
localStorage.setItem("LastLoginDate",new Date().getTime())
|
||||||
|
clearInterval(myInterval);
|
||||||
|
document.getElementById("usernameField").value=credentials.username;
|
||||||
|
document.getElementById("passwordField").value=encryptXor(credentials.passwordCrypt, '5346245634634765377');
|
||||||
|
document.getElementById("loginSubmitBtn").click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// I have not found a reliable way to see if the page is ready other than polling...
|
||||||
|
function execQuery(theQuery) {
|
||||||
|
let myInterval;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
myInterval = window.setInterval(() => {
|
||||||
|
if (document.getElementsByClassName("gwt-SuggestBox EKM0XQC-tb-f").length === 1) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
// even if the screen is loaded, if we are too fast it will be too fast for the javascript of the page...
|
||||||
|
window.setTimeout(function(){
|
||||||
|
window.document.title="[RiverRobot] Executing Query " + theQuery;
|
||||||
|
console.log("ExecQuery ",theQuery);
|
||||||
|
let theSearchField = document.getElementsByClassName("gwt-SuggestBox EKM0XQC-tb-f")[0];
|
||||||
|
|
||||||
|
theSearchField.value = theQuery;
|
||||||
|
|
||||||
|
let theSearchButton = document.getElementsByClassName("gwt-Button EKM0XQC-e-d")[0];
|
||||||
|
theSearchButton.click();
|
||||||
|
resolve();
|
||||||
|
},5000);
|
||||||
|
} else {
|
||||||
|
window.document.title="[RiverRobot] Waiting for Query field " + theQuery;
|
||||||
|
console.log("Waiting for Query field",theQuery);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// I have not found a reliable way to see if the data is ready than polling...
|
||||||
|
function downloadResultsCsv(theName) {
|
||||||
|
let myInterval;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
myInterval = window.setInterval(() => {
|
||||||
|
let clsErrorEle = document.getElementsByClassName("pluginErrorStringBlack");
|
||||||
|
if (clsErrorEle.length > 0) {
|
||||||
|
clearInterval(myInterval);
|
||||||
|
let errText=clsErrorEle[0].innerText ;
|
||||||
|
console.log("While waiting for results of " + theName + " Page shows error: " + errText + " -> Proceeding to next");
|
||||||
|
resolve(errText);
|
||||||
|
}
|
||||||
|
let pTag = document.getElementsByTagName("P");
|
||||||
|
if (pTag.length > 0) {
|
||||||
|
console.log("Ready", theName, pTag);
|
||||||
|
window.document.title="[RiverRobot] Downloading Results " + theName;
|
||||||
|
clearInterval(myInterval);
|
||||||
|
let theCsvUrl = pTag[0].firstChild.href;
|
||||||
|
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
console.log("Length of response ",this.responseText.length);
|
||||||
|
// to be able to give the file a custom name I load it into a blob first, otherwise it will always save with the generic name.
|
||||||
|
let blob = new Blob([this.responseText], {
|
||||||
|
type: 'text/plain'
|
||||||
|
});
|
||||||
|
let anchor = document.createElement('a');
|
||||||
|
|
||||||
|
anchor.download = theName + "-" + simulateDate.getFullYear() + "-" + ("0"+(1+simulateDate.getMonth())).slice(-2) + "-" + ("0"+simulateDate.getDate()).slice(-2) + ".csv";
|
||||||
|
anchor.href = window.URL.createObjectURL(blob);
|
||||||
|
anchor.dataset.downloadurl = ['text/plain', anchor.download, anchor.href].join(':');
|
||||||
|
anchor.click();
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhttp.open("GET", theCsvUrl, true);
|
||||||
|
xhttp.send();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
window.document.title="[RiverRobot] Waiting for Results " + theName;
|
||||||
|
console.log("Waiting for Results",theName);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let allQueriesAndNames = [
|
||||||
|
{
|
||||||
|
name: 'PrmMainBo.Save',
|
||||||
|
query: " ! ( class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Activate' ) and ! ( class.method = 'Cas.BusinessLogic.Prm.PrmMainBo.Copy' ) and ( class.method = 'Cas.BusinessLogic.Prm.PrmMainBo.Save' ) and ( instance = 'ACNCASWebSite#LAOProdServer' ) | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmMainBo.Save -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayMainBo.Save',
|
||||||
|
query: " class.method = 'Cas.BusinessLogic.Pay.PayMainBo.Save' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Pay.PayMainBo.Save -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ClcCalculationBo.Calculation',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Calculation' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Clc.ClcCalculationEngineBo.Calculation -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ClcCalculationEngineBo.UpdateSummaryForPeriod',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Clc.ClcCalculationEngineBo.UpdateSummaryForPeriod' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Clc.ClcCalculationEngineBo.UpdateSummaryForPeriod -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmTacticView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmTacticView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmTacticView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmTacticView.AddViewItem',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmTacticView.AddViewItem' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmTacticView.AddViewItem -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmProductAllView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmProductAllView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmProductAllView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PrmProductAllView.AddViewItem',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Prm.PrmProductAllView.AddViewItem' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Prm.PrmProductAllView.AddViewItem -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BpaMyPaymentMassCreationView.GetView',
|
||||||
|
query: "class.method = 'Cas.BusinessLogic.Bpa.BpaMyPaymentMassCreationView.GetView' and instance = 'ACNCASWebSite#LAOProdServer' | calls -type class.method -class.method Cas.BusinessLogic.Bpa.BpaMyPaymentMassCreationView.GetView -include_call_count -visualization transactions -limit 10000 -sort_by total_duration"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Password is encrypted with XOR to preent "accidental" revelation
|
||||||
|
let credentials=localStorage.getItem("riverRobotCredentials");
|
||||||
|
if (credentials!==null) { credentials=JSON.parse(credentials); }
|
||||||
|
loginThread(credentials);
|
||||||
|
|
||||||
|
let allDone = new Promise((allResolve,allReject)=>{
|
||||||
|
// Loop over all queries one by one considering the promise resolution: have to execute them in sequence!
|
||||||
|
for (let i=0,p=Promise.resolve();i<allQueriesAndNames.length; i++){
|
||||||
|
p = p.then(_ => new Promise(resolve => {let theQueryAndName=allQueriesAndNames[i];
|
||||||
|
console.log("Executing", theQueryAndName);
|
||||||
|
execQuery(theQueryAndName.query).then(() => {
|
||||||
|
downloadResultsCsv(theQueryAndName.name).then(() => {
|
||||||
|
console.log("Done ", theQueryAndName,i,allQueriesAndNames.length)
|
||||||
|
resolve();
|
||||||
|
if (i===(allQueriesAndNames.length-1)) {
|
||||||
|
console.log("All Done.");
|
||||||
|
allResolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
};}
|
||||||
|
);
|
||||||
|
|
||||||
|
// if we are all finished then we can close the window.
|
||||||
|
allDone.then(()=>{
|
||||||
|
window.document.title="[RiverRobot] DONE";
|
||||||
|
console.log("Closing window");
|
||||||
|
// this doesn't work, Chrome doesn't allow me to close the last window, worked around that by killing the task in the scheduling...
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
})();
|
||||||
BIN
_PerformanceData.xlsx
Normal file
BIN
_PerformanceData.xlsx
Normal file
Binary file not shown.
1
header.template
Normal file
1
header.template
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Date,Completion Time,Response Time,Function,Transaction Type,Server,Instance,URL,Client IP,Total Processing Time (s),Processing Time/call (s),Maximum Processing Time (s),Duration/call (s),Maximum Duration (s),Total Duration (s),Number of Calls
|
||||||
19
process.sh
Normal file
19
process.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
rm outSeg.tmp
|
||||||
|
thisPath=$PWD
|
||||||
|
netPath=//ustca239.kcc.com/JoesHop/RiverbedExports/
|
||||||
|
pushd $netPath
|
||||||
|
ls *.csv | while read theFile
|
||||||
|
do
|
||||||
|
tmp=${theFile#*-}
|
||||||
|
date=${tmp:0:10}
|
||||||
|
funct=${theFile%%-*}
|
||||||
|
echo $theFile - $date - $funct
|
||||||
|
awk -F , -e 'FNR > 1 {print "'${date}',"$2","$3",'${funct}',"$5","$6","$7","$8","$9","$10","$11","$12","$13","$14","$15","$16 }' $theFile >> "${thisPath}/outSeg.tmp"
|
||||||
|
mv ${netPath}$theFile "${thisPath}/archive/" 2> /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
cat outSeg.tmp >> PerfData.csv
|
||||||
|
|
||||||
15
riverRobot.sh
Normal file
15
riverRobot.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo executing the robot browser
|
||||||
|
"/cygdrive/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" --profile-directory="Profile 1"
|
||||||
|
|
||||||
|
while [[ ! $(ls input/PrmProductAllView.AddViewItem* 2>/dev/null) ]]
|
||||||
|
do echo waiting for robot browser to finish by polling existence of last file created.
|
||||||
|
sleep 30
|
||||||
|
done
|
||||||
|
|
||||||
|
echo robot browser finished, converting and adding to output.
|
||||||
|
|
||||||
|
./process.sh
|
||||||
|
|
||||||
|
echo killing the browser window.
|
||||||
|
taskkill /FI "WINDOWTITLE eq Riverbed SteelCentral Appinternals - Google Chrome"
|
||||||
Reference in New Issue
Block a user