Skip to content

Instantly share code, notes, and snippets.

@dound
Last active January 29, 2022 07:14
Show Gist options
  • Save dound/6236849 to your computer and use it in GitHub Desktop.
Save dound/6236849 to your computer and use it in GitHub Desktop.
Augments the Google App Engine (GAE) dashboard with additional cost metrics.
// ==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