Last active
January 29, 2022 07:14
-
-
Save dound/6236849 to your computer and use it in GitHub Desktop.
Augments the Google App Engine (GAE) dashboard with additional cost metrics.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Augment GAE Dashboard | |
// @version 0.3 | |
// @namespace http://www.dound.com/ | |
// @description modifies issue style | |
// @match https://appengine.google.com/dashboard?*app_id=* | |
// @require https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js | |
// ==/UserScript== | |
// Assumes discounted instance hour pricing. | |
window.setTimeout(function() { | |
var DAYS_PER_MONTH = 30.5; | |
var MEGACYCLES_PER_SEC = 600; // 600 MHz | |
var SEC_PER_HR = 60 * 60; | |
// include total runtime and cost per popular endpoint | |
var grandTotalHours = 0; | |
$('#ae-dash-popular tbody tr').each(function(i,e) { | |
var cols = $(e).find('td'); | |
var numRequests = parseFloat(cols[2].innerHTML); | |
if (cols[2].innerHTML.indexOf('M') >= 0) | |
numRequests *= 1000 * 1000; | |
else if (cols[2].innerHTML.indexOf('K') >= 0) | |
numRequests *= 1000; | |
var avgMCycles = parseInt(cols[3].innerHTML); | |
var avgSeconds = avgMCycles / MEGACYCLES_PER_SEC; | |
var totalHours = numRequests * (avgSeconds / SEC_PER_HR); | |
grandTotalHours += totalHours; | |
var costDollars = 0.05 * totalHours; | |
$(e).append('<td style="text-align:right">' + Math.round(totalHours) + 'hr ($' + Math.round(costDollars) + ')</td>'); | |
}); | |
var grandTotalCost = 0.05 * grandTotalHours; | |
// show cost per resource type | |
var actualGrandTotalCost = 0; | |
$('#ae-dash-quota .ae-table:first thead tr:first').append('<th scope="col">Cost</th>'); | |
var totalCost = 0; | |
$('#ae-dash-quota .ae-table:first tbody tr').each(function(i, e) { | |
var row = $(e); | |
var cols = row.find('td'); | |
var colName = cols[0].innerHTML.trim(); | |
var colValueHTML = cols[2].innerHTML; | |
if (colValueHTML.indexOf('span') >= 0) | |
var colValue = parseFloat($(cols[2]).find('span')[0].innerHTML.replace(',', '')); | |
else | |
var colValue = parseFloat(colValueHTML); | |
var costPerUnit = null; | |
switch (colName) { | |
case 'Frontend Instance Hours': costPerUnit = 0.05; actualGrandTotalCost += colValue * costPerUnit; break; // assumes instance hours are reserved (o/w, 0.08) | |
case 'Backend Instance Hours': costPerUnit = 0.08; break; | |
case 'Datastore Stored Data': | |
case 'Logs Stored Data': | |
case 'Task Queue Stored Task Bytes': | |
case 'Blobstore Stored Data': | |
costPerUnit = 0.18 / DAYS_PER_MONTH; | |
break; | |
case 'Dedicated Memcache Use (10k ops/s/GB, 1GB unit)': costPerUnit = 0.12; break; | |
case 'Code and Static File Storage': costPerUnit = 0.13 / DAYS_PER_MONTH; break; | |
case 'Datastore Write Operations': costPerUnit = 9e-7 * 1e6; break; | |
case 'Datastore Read Operations': costPerUnit = 6e-7 * 1e6; break; | |
case 'Datastore Small Operations': costPerUnit = 1e-7 * 1e6; break; | |
case 'Outgoing Bandwidth': costPerUnit = 0.12; break; | |
case 'Recipients Emailed': costPerUnit = 1e-4; break; | |
case 'Stanzas Sent': costPerUnit = 1e-5; break; | |
case 'Channels Created': costPerUnit = 1e-4; break; | |
case 'Logs Read Bandwidth': costPerUnit = 0.05; break; // ?? | |
case 'PageSpeed Outgoing Bandwidth': costPerUnit = 0.39; break; | |
case 'SSL VIPs': costPerUnit = 39.00; break; | |
case 'SSL SNI Certificates': costPerUnit = 39.00; break; | |
case 'Search API Basic Operations': costPerUnit = 0.10 / 10e3; break; | |
case 'Search API Bytes Indexed': costPerUnit = 0.18 / DAYS_PER_MONTH; break; | |
case 'Search API Stored Data': costPerUnit = 0.18 / DAYS_PER_MONTH; break; | |
case 'Search API Complex Searches': costPerUnit = 0.60 / 10e3; break; | |
case 'Search API Simple Searches': costPerUnit = 0.13 / 10e3; break; | |
default: console.log('Unknown column: ' + colName); | |
} | |
if (costPerUnit === null) | |
amount = '???'; | |
else if (costPerUnit == 'n/a') | |
amount = 'n/a'; | |
else { | |
amount = colValue * costPerUnit; | |
totalCost += amount; | |
if(amount < 10) | |
amount = '<span style="color:#888">~0</span>'; | |
else | |
amount = '$' + Math.round(amount); | |
} | |
row.append('<td>' + amount + '</td>'); | |
}); | |
$('#ae-dash-quota .ae-table:first tbody').append('<tr><th colspan="6" style="background-color:#FDD"><b>Total Cost</b> (since midnight): <b>$' + Math.round(totalCost) + '</b></th></tr>'); | |
var percentOfActual = 100.0 * grandTotalCost / actualGrandTotalCost; | |
$('#ae-dash-popular thead tr').append('<th scope="col" style="width:120px">Total Runtime Hr (Cost$)<br/>' + Math.round(grandTotalHours) + 'hr ($' + Math.round(grandTotalCost) + '): ' + Math.round(percentOfActual) + '%' + '<span>last 24 hrs</span></th>'); | |
}, 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment