Skip to content

Commit 2b7ec0c

Browse files
authored
[webapp] Add Multi-Path Colors & bug fixes (#81)
* [webapp] Add Multi-Path Colors & bug fixes - Adds deterministic colors for each unique path. - Adds path colors to path selection list. - Adds/changes path colors to bwtest and echo graph data points. - Adds path # hops as a badge next to path selection list. - Adds gray color for graph data points without matching paths. - Changes to faint-red color for graph error data points, not red. - Fixes bwtest failure to match interactive paths due to ANSI escapes. - Fixes bwtest failure to match default path. - Improves regex cases to record echo errors. - Adds stderr to command parsing stream with stdout. - Fixes overlapping continuous switch conditions between user-server. - Fixes #69. * removed erroneous html
1 parent 64cebf3 commit 2b7ec0c

File tree

8 files changed

+141
-48
lines changed

8 files changed

+141
-48
lines changed

webapp/lib/bwcont.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var reErr3 = `(?i:error:\s*)([\s\S]*)`
3434
var reErr4 = `(?i:eror:\s*)([\s\S]*)`
3535
var reErr5 = `(?i:crit:\s*)([\s\S]*)`
3636
var reUPath = `(?i:using path:)`
37+
var reSPath = `(?i:path=*)"(.*?)"`
3738

3839
// ExtractBwtestRespData will parse cmd line output from bwtester for adding BwTestItem fields.
3940
func ExtractBwtestRespData(resp string, d *model.BwTestItem, start time.Time) {
@@ -91,7 +92,11 @@ func ExtractBwtestRespData(resp string, d *model.BwTestItem, start time.Time) {
9192
data[dir]["arrival_max"] = re.FindStringSubmatch(r[i])[1]
9293
}
9394
// save used path (default or interactive) for later user display
94-
if pathNext {
95+
match, _ := regexp.MatchString(reSPath, r[i])
96+
if match {
97+
re := regexp.MustCompile(reSPath)
98+
path = re.FindStringSubmatch(r[i])[1]
99+
} else if pathNext {
95100
path = strings.TrimSpace(r[i])
96101
}
97102
match, _ = regexp.MatchString(reUPath, r[i])

webapp/lib/echocont.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,28 @@ func ExtractEchoRespData(resp string, d *model.EchoItem, start time.Time) {
7676
match1, _ := regexp.MatchString(reErr1, r[i])
7777
match2, _ := regexp.MatchString(reErr2, r[i])
7878
match3, _ := regexp.MatchString(reErr3, r[i])
79+
match4, _ := regexp.MatchString(reErr4, r[i])
80+
match5, _ := regexp.MatchString(reErr5, r[i])
7981

8082
if match1 {
8183
re := regexp.MustCompile(reErr1)
8284
err = re.FindStringSubmatch(r[i])[1]
83-
//log.Info("match1", "err", err)
8485
} else if match2 {
8586
re := regexp.MustCompile(reErr2)
8687
err = re.FindStringSubmatch(r[i])[1]
8788
} else if match3 {
8889
re := regexp.MustCompile(reErr3)
8990
err = re.FindStringSubmatch(r[i])[1]
91+
} else if match4 {
92+
re := regexp.MustCompile(reErr4)
93+
err = re.FindStringSubmatch(r[i])[1]
94+
} else if match5 {
95+
re := regexp.MustCompile(reErr5)
96+
err = re.FindStringSubmatch(r[i])[1]
9097
}
9198
}
9299
log.Info("app response", "data", data)
93100

94-
//log.Info("print parsed result", "error", err)
95-
//log.Info("print parsed result", "path", path)
96-
97101
d.RunTime, _ = data["run_time"]
98102
d.ResponseTime, _ = data["response_time"]
99103
d.PktLoss = int(data["packet_loss"])

webapp/static/css/style-viz.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ ul.tree li.open>ul {
229229
ul.tree li a {
230230
color: black;
231231
text-decoration: none;
232+
padding-left: 5px; /* background shape */
233+
padding-right: 5px; /* background shape */
234+
border-radius: 10px; /* background shape */
232235
}
233236

234237
ul.tree li a:before {

webapp/static/js/asviz.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ function getTab() {
4949
* Creates on-click handler that will draw/hide selected path arcs.
5050
*/
5151
function setupPathSelection() {
52-
// add style to list of paths and segments
53-
$('li[seg-type="CORE"]').children().css("color", colorSegCore);
54-
$('li[seg-type="DOWN"]').children().css("color", colorSegDown);
55-
$('li[seg-type="UP"]').children().css("color", colorSegUp);
56-
$('li[seg-type="PATH"]').children().css("color", colorPaths);
57-
5852
// handle path graph-only selection and color
5953
$("#as-iflist ul > li").click(function() {
6054
var type = $(this).attr("seg-type");

webapp/static/js/tab-paths.js

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var iaLabels;
33
var iaLocations = [];
44
var iaGeoLoc;
55
var g = {};
6+
var jPathColors = [];
67

78
function setupDebug(src, dst) {
89
var src = $('#ia_cli').val();
@@ -15,6 +16,24 @@ function setupDebug(src, dst) {
1516
}
1617
}
1718

19+
var cMissingPath = '#cccccc';
20+
var cPaths = [ "#3366cc", "#dc3912", "#ff9900", "#109618", "#990099",
21+
"#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499",
22+
"#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067",
23+
"#329262", "#5574a6", "#3b3eac" ];
24+
function path_colors(n) {
25+
return cPaths[n % cPaths.length];
26+
}
27+
28+
function getPathColor(hops) {
29+
var idx = jPathColors.indexOf(hops + '');
30+
if (idx < 0) {
31+
return cMissingPath;
32+
} else {
33+
return path_colors(idx);
34+
}
35+
}
36+
1837
function isConfigComplete(data, textStatus, jqXHR) {
1938
console.log(JSON.stringify(data));
2039
g['nodes_xml_url'] = data.nodes_xml_url;
@@ -326,13 +345,42 @@ function drawTopo(src, dst, paths, segs) {
326345
}, width, height);
327346
}
328347

348+
function formatPathJson(paths, idx) {
349+
if (typeof idx === 'undefined') {
350+
return '';
351+
}
352+
var ent = paths[idx].Entry;
353+
var hops = ent.Path.Interfaces;
354+
var path = "[";
355+
for (var i = 0; i < hops.length; i += 2) {
356+
var prev = hops[i];
357+
var next = hops[i + 1];
358+
if (i > 0) {
359+
path += ' ';
360+
}
361+
path += iaRaw2Read(prev.RawIsdas) + ' ' + prev.IfID + '>' + next.IfID;
362+
if (i == (hops.length - 2)) {
363+
path += ' ' + iaRaw2Read(next.RawIsdas);
364+
}
365+
}
366+
path += "]";
367+
return path;
368+
}
369+
329370
function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
330371
var html = "<ul class='tree'>";
331372
for (p in paths) {
332-
html += "<li seg-type='PATH' seg-num=" + p + "><a href='#'>PATH "
333-
+ (parseInt(p) + 1) + "</a>";
373+
334374
var ent = paths[p].Entry;
335375
var exp = new Date(0);
376+
if_ = ent.Path.Interfaces;
377+
var hops = if_.length / 2;
378+
379+
var style = "style='background-color: "
380+
+ getPathColor(formatPathJson(paths, parseInt(p))) + "; '";
381+
html += "<li seg-type='PATH' seg-num=" + p + "><a " + style
382+
+ " href='#'>PATH " + (parseInt(p) + 1)
383+
+ "</a> <span class='badge'>" + hops + "</span>";
336384
exp.setUTCSeconds(ent.Path.ExpTime);
337385
html += "<ul>";
338386
html += "<li><a href='#'>Mtu: " + ent.Path.Mtu + "</a>";
@@ -347,9 +395,6 @@ function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
347395
html += "<li><a href='#'>Port: " + ent.HostInfo.Port + "</a>";
348396
html += "<li><a href='#'>Expiration: " + exp.toLocaleDateString() + " "
349397
+ exp.toLocaleTimeString() + "</a>";
350-
if_ = ent.Path.Interfaces;
351-
var hops = if_.length / 2;
352-
html += "<li><a href='#'>Hops: " + hops + "</a>";
353398
for (i in if_) {
354399
html += "<li><a href='#'>" + iaRaw2Read(if_[i].RawIsdas) + " ("
355400
+ if_[i].IfID + ")</a>";
@@ -365,19 +410,33 @@ function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
365410
return html;
366411
}
367412

413+
// add style to list of paths and segments
414+
function getSegColor(type) {
415+
if (type == "CORE") {
416+
return colorSegCore;
417+
} else if (type == "DOWN") {
418+
return colorSegDown;
419+
} else if (type == "UP") {
420+
return colorSegUp;
421+
} else {
422+
return colorPaths;
423+
}
424+
}
425+
368426
function get_segment_info(segs, type) {
369427
var html = "";
370428
for (s in segs.if_lists) {
371-
html += "<li seg-type='" + type + "' seg-num=" + s + "><a href='#'>"
372-
+ type + " SEGMENT " + (parseInt(s) + 1) + "</a>";
373429
var exp = new Date(0);
374430
exp.setUTCSeconds(segs.if_lists[s].expTime);
431+
if_ = segs.if_lists[s].interfaces;
432+
var hops = if_.length / 2;
433+
var style = "style='color: " + getSegColor(type) + ";'";
434+
html += "<li seg-type='" + type + "' seg-num=" + s + "><a " + style
435+
+ " href='#'>" + type + " SEGMENT " + (parseInt(s) + 1)
436+
+ "</a> <span class='badge'>" + hops + "</span>";
375437
html += "<ul>";
376438
html += "<li><a href='#'>Expiration: " + exp.toLocaleDateString() + " "
377439
+ exp.toLocaleTimeString() + "</a>";
378-
if_ = segs.if_lists[s].interfaces;
379-
var hops = if_.length / 2;
380-
html += "<li><a href='#'>Hops: " + hops + "</a>";
381440
for (i in if_) {
382441
html += "<li><a href='#'>" + if_[i].ISD + "-" + if_[i].AS + " ("
383442
+ if_[i].IFID + ")</a>";
@@ -625,6 +684,14 @@ function requestPaths() {
625684
resUp = resSegs.up_segments;
626685
resDown = resSegs.down_segments;
627686

687+
// store incoming paths
688+
for (var idx = 0; idx < resPath.if_lists.length; idx++) {
689+
var hops = formatPathString(resPath, idx, 'PATH');
690+
if (!jPathColors.includes(hops)) {
691+
jPathColors.push(hops);
692+
}
693+
}
694+
628695
jTopo = get_json_path_links(resPath, resCore, resUp, resDown);
629696
$('#path-info').html(
630697
get_path_html(data.paths, resCore, resUp, resDown, true));

0 commit comments

Comments
 (0)