Skip to content

Commit

Permalink
Add waterfall filter and KB_REPLACE config setting
Browse files Browse the repository at this point in the history
- Waterfall now has a text filter and various 'type' filters
- The KB_REPLACE setting is used to rename Kibana items during upgrades
  • Loading branch information
mverkerk-godaddy committed Jan 4, 2018
1 parent e171596 commit d39cbde
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .config_sample.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
env:
ES_PROTOCOL: http
ES_HOST: localhost
ES_HOST: ~
ES_PORT: 9200
ES_USER: ~
ES_PASS: ~
ES_SSL_CERT: ~
ES_SSL_KEY: ~
KB_HOST: localhost
KB_HOST: ~
KB_PORT: 5601
KB_INDEX: ~
HTTP_PORT: 80
Expand Down
49 changes: 46 additions & 3 deletions public/js/waterfall.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* javascript:(function(){var el=document.createElement('script');el.type='text/javascript';el.src='http://andydavies.me/sandbox/waterfall.js';document.getElementsByTagName('body')[0].appendChild(el);})();
*/

function waterfall(div, resources) {
function waterfall(div, resources, fltr) {
$(div).empty();

var xmlns = "http://www.w3.org/2000/svg";
Expand All @@ -37,7 +37,23 @@ function waterfall(div, resources) {
function drawWaterfall(entries) {

var maxTime = 0;
for (var n = 0; n < entries.length; n++) {
for (var n = entries.length -1; n >= 0; n--) {
if (fltr && entries[n].hasOwnProperty("initiatorType")) {
if (fltr.indexOf("fltr_") === 0) {
// this is a type filter
var fltrType = fltr.replace("fltr_", "");
if (entryFilter(entries[n], fltrType) === true) {
entries.splice(n, 1);
continue;
}
} else {
// must be a text filter
if (entries[n].uri.indexOf(fltr) < 0) {
entries.splice(n, 1);
continue;
}
}
}
if (entries[n].hasOwnProperty("status") && (entries[n].sla_pageLoadTime <= (entries[n].act_pageLoadTime * 2)) ) {
maxTime = Math.max(maxTime, entries[n].sla_pageLoadTime) + 50;
} else if (!entries[n].hasOwnProperty("status")) {
Expand Down Expand Up @@ -403,7 +419,7 @@ function waterfall(div, resources) {

if (w.performance !== undefined && (w.performance.getEntriesByType !== undefined || w.performance.webkitGetEntriesByType !== undefined)) {

var timings = resources;
var timings = Array.from(resources);

drawWaterfall(timings);
} else {
Expand Down Expand Up @@ -588,3 +604,30 @@ function getQueryStringParameterVal(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
};

function entryFilter(entry, fltrType) {
var result = false;
switch (fltrType) {
case "xhr":
if (entry.initiatorType !== "xmlhttprequest") {
result = true;
}
break;
case "js":
if (entry.initiatorType !== "link") {
result = true;
}
break;
case "css":
if (entry.initiatorType !== "link") {
result = true;
}
break;
case "img":
if (entry.initiatorType !== "img") {
result = true;
}
break;
}
return result;
};
60 changes: 56 additions & 4 deletions public/waterfall.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,33 @@
<body style="display: hidden;">
<div class="col-sm-12">
<div class="row">
<table id="title" class="table table-condensed table-bordered" width="100%">
<table id="title" class="table table-condensed table-bordered" width="100%" style="margin: 0px;">
<tbody>
<tr class="info h2">
<td colspan="42">Waterfall</td>
<tr class="info">
<td colspan="42">
<div class="col-sm-2 h2"><strong>Waterfall</strong></div>
<div class="col-sm-3 h2">
<div class="input-group input-group-sm" style="width: 100%;">
<span class="input-group-addon" id="sizing-addon1">Filter: </span>
<input id="srch-term" name="srch-term" type="text" class="form-control" placeholder="Search" aria-describedby="sizing-addon3">
</div>
</div>
<div class="col-sm-7 h2">
<h4 style="margin: 0px;">
<span id="fltr_all" class="btn btn-sm btn-info btn-default">All</span>
<span id="fltr_xhr" class="btn btn-sm btn-default">XHR</span>
<span id="fltr_js" class="btn btn-sm btn-default">JS</span>
<span id="fltr_css" class="btn btn-sm btn-default">CSS</span>
<span id="fltr_img" class="btn btn-sm btn-default">IMG</span>
<span id="fltr_med" class="btn btn-sm btn-default">Media</span>
<span id="fltr_fnt" class="btn btn-sm btn-default">Font</span>
<span id="fltr_doc" class="btn btn-sm btn-default">Doc</span>
<span id="fltr_ws" class="btn btn-sm btn-default">WS</span>
<span id="fltr_mft" class="btn btn-sm btn-default">Manifest</span>
<span id="fltr_oth" class="btn btn-sm btn-default">Other</span>
</h4>
</div>
</td>
</tr>
<tr class="warning">
<td class="h6" width='75%'><strong>Page URL</strong></td>
Expand Down Expand Up @@ -88,6 +111,19 @@
$('#title tbody>tr:nth-child(3)>td:nth-child(1)').text('No ID specified').css('color', 'red');
};

$("[id^=fltr_]").on("click", function() {
$("[id^=fltr_]").removeClass("btn-info");
$(this).addClass("btn-info");
const fltr = this.id;
waterfall('#svg_canvas', window.resources, fltr);
fillTable('#tbl_resources', window.resources, fltr);
})

$("#srch-term").on("change paste keyup", function() {
const fltr = this.value;
waterfall('#svg_canvas', window.resources, fltr);
fillTable('#tbl_resources', window.resources, fltr);
})

$(window).on('resize', function() {
drawPage(id);
Expand Down Expand Up @@ -124,8 +160,9 @@
}
};

function fillTable(div, resources) {
function fillTable(div, resources, fltr) {
$('#info').css('visibility', '');
$('#filter').css('visibility', '');
$(div).empty();
var tbl_header = '<thead><tr>';
tbl_header += '<th>#</th>';
Expand All @@ -143,6 +180,21 @@

for (var n = 0; n < resources.length; n++) {
var entry = resources[n];
if (fltr && entry.hasOwnProperty("initiatorType")) {
if (fltr.indexOf("fltr_") === 0) {
// this is a type filter
var fltrType = fltr.replace("fltr_", "");
if (this.entryFilter(entry, fltrType) === true) {
continue;
}
} else {
// must be a text filter
if (entry.uri.indexOf(fltr) < 0) {
continue;
}
}
}
var entryFilter = this.entryFilter(entry);
if (typeof entry === 'object' && !entry.hasOwnProperty("status")) {
// This entry is from the 'resources' data
if ("loadEventStart" in entry) {
Expand Down
34 changes: 20 additions & 14 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ nconf
})
.env({
lowerCase: true,
whitelist: ['configfile', 'node_env', 'http_port', 'debug', 'es_upgrade', 'es_host', 'es_port',
'es_protocol', 'es_user', 'es_passwd', 'es_ssl_cert', 'es_ssl_key', 'kb_host', 'kb_port'
whitelist: ['configfile', 'node_env', 'http_port', 'debug', 'kb_index', 'kb_rename', 'es_upgrade', 'es_host',
'es_port', 'es_protocol', 'es_user', 'es_passwd', 'es_ssl_cert', 'es_ssl_key', 'kb_host', 'kb_port'
],
parseValues: true
});
Expand Down Expand Up @@ -92,6 +92,7 @@ const cfgNconf = {
KB_HOST: nconf.get('kb_host') || cfgConfig.env.KB_HOST || nconf.get('es_host') || cfgConfig.env.ES_HOST || '',
KB_PORT: nconf.get('kb_port') || cfgConfig.env.KB_PORT || 5601,
KB_INDEX: nconf.get('kb_index') || cfgConfig.env.KB_INDEX || '.kibana',
KB_RENAME: nconf.get('kb_rename') || cfgConfig.env.KB_RENAME || '',
HTTP_PORT: nconf.get('http_port') || cfgConfig.env.HTTP_PORT || 80,
DEBUG: nconf.get('debug') || cfgConfig.env.DEBUG || false,
APP_NAME: pkg.name,
Expand All @@ -107,17 +108,17 @@ const cfgNconf = {
params: {
required: cfgConfig.params.required || ['log.test_info', 'log.env_tester', 'log.team', 'log.browser', 'log.env_target'],
defaults: {
baseline: { // These settings are used to calculate the baseline
days: cfgConfig.params.defaults.baseline.days || 7, // Number of days to calculate the baseline for
perc: cfgConfig.params.defaults.baseline.perc || 75, // Percentile to calculate
padding: cfgConfig.params.defaults.baseline.padding || 1.2 // Extra padding on top of the calculated baseline (gives some wiggle-room)
baseline: {
days: cfgConfig.params.defaults.baseline.days || 7,
perc: cfgConfig.params.defaults.baseline.perc || 75,
padding: cfgConfig.params.defaults.baseline.padding || 1.2
},
flags: { // These booleans determine the output and other actions to be performed
assertBaseline: cfgConfig.params.defaults.flags.assertBaseline || true, // Whether or not to compare against baseline
debug: cfgConfig.params.defaults.flags.debug || false, // Request extra debug info from the API
esTrace: cfgConfig.params.defaults.flags.esTrace || false, // Request elasticsearch output from API
esCreate: cfgConfig.params.defaults.flags.esCreate || false, // Save results to elasticsearch
passOnFailedAssert: cfgConfig.params.defaults.flags.passOnFailedAssert || false // Pass the test, even when the performance is above the threshold
flags: {
assertBaseline: cfgConfig.params.defaults.flags.assertBaseline || true,
debug: cfgConfig.params.defaults.flags.debug || false,
esTrace: cfgConfig.params.defaults.flags.esTrace || false,
esCreate: cfgConfig.params.defaults.flags.esCreate || false,
passOnFailedAssert: cfgConfig.params.defaults.flags.passOnFailedAssert || false
}
}
}
Expand Down Expand Up @@ -167,7 +168,7 @@ async function setupES(es) {

if (currTemplate.hasOwnProperty(env.INDEX_PERF)) {
const currentVersion = currTemplate[env.INDEX_PERF].version;
if (newVersion > currentVersion) {
if (!currentVersion || (newVersion > currentVersion)) {
logger.debug(` >> upgrading API from v.${currentVersion} - installing v.${newVersion} ...`);
needUpgrade = true;
}
Expand All @@ -188,7 +189,12 @@ async function setupES(es) {
// upgr.delIndexPattern('cicd-perf-errorlog');

// Import/update latest visualizations and dashboards
const importJson = JSON.parse(fs.readFileSync('./.kibana_items.json'));
let importFile = fs.readFileSync('./.kibana_items.json', 'utf8');
const replText = nconf.get('env:KB_RENAME');
if (replText && typeof replText === 'string') {
importFile = importFile.replace(/TIMINGS/g, replText.toUpperCase());
}
const importJson = JSON.parse(importFile);
let esResponse = await es.kbImport(importJson);
if (esResponse === true) {
await es.defaultIndex(env.INDEX_PERF + '*', '5.6.2')
Expand Down
15 changes: 8 additions & 7 deletions src/v2/es-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class ESClass {
const esConfig = {
host: this.env.ES_PROTOCOL + '://' + this.env.ES_HOST + ':' + this.env.ES_PORT,
requestTimeout: 5000,
log: 'error'
log: 'error',
apiVersion: '5.x'
};

// Check if user/passwd are provided - configure basic auth
Expand Down Expand Up @@ -77,13 +78,13 @@ class ESClass {

async defaultIndex(name, version) {
const response = await this.client
.index({ index: (nconf.get('env:KB_INDEX') || '.kibana'), type: 'config', id: version, body: { defaultIndex: name }});
.index({ index: (this.env.KB_INDEX || '.kibana'), type: 'config', id: version, body: { defaultIndex: name }});
return response;
}

async delIndexPattern(pattern) {
const response = await this.client
.delete({ index: '.kibana', type: 'index-pattern', id: pattern });
.delete({ index: (this.env.KB_INDEX || '.kibana'), type: 'index-pattern', id: pattern });
return response.acknowledged;
}

Expand Down Expand Up @@ -117,7 +118,7 @@ class ESClass {
if (id) {
// Check if it already exists
exists = await this.client
.exists({ index: index, type: type, id: id })
.exists({ index: index, type: type, id: id });
}
if (!exists) {
const response = await this.client
Expand All @@ -141,11 +142,11 @@ class ESClass {

if (item._type === 'index-pattern' && item._id === 'cicd-perf*') {
const apiHost = (this.env.HTTP_PORT !== 80) ? this.env.HOST + ':' + this.env.HTTP_PORT : this.env.HOST;
_source.fieldFormatMap = _source.fieldFormatMap.replace('__api__hostname', apiHost);
_source.fieldFormatMap = _source.fieldFormatMap.replace('__api__hostname', apiHost.toLowerCase());
}

const response = await this.index('.kibana', item._type, item._id, _source);
this.checkEsResponse(response, 'import [' + item._type + ']', item._id);
const response = await this.index((this.env.KB_INDEX || '.kibana'), item._type, item._id, _source);
this.checkEsResponse(response, 'import [' + item._type + ']', item._source.title);
}
return true;
} catch (err) {
Expand Down

0 comments on commit d39cbde

Please sign in to comment.