Commit bef50937 authored by Otto Jonassen Wittner's avatar Otto Jonassen Wittner
Browse files

Merge branch 'master' of scm.uninett.no:iou/microdep

parents 9f2be06b c0fb5d4a
Pipeline #50355 passed with stages
in 57 seconds
......@@ -21,11 +21,12 @@ die $usage if !$index;
open LIST, "<$list" || die "Could not open $list : $!\n";
while(<LIST>){
next if /\s*#/; # comment
($name, $uid, $dns, $ip, $port, $crude_port)=split;
($name, $uid, $dns, $ip, $port, $crude_port, $ssh_port, $max_hop)=split;
$ip{$name}=$ip;
$dns{$name}=$dns;
$port{$name}=$port;
$crude_port{$name}=$crude_port if $crude_port;
$max_hop{$name}= $max_hop || $max_hops_default;
}
if ($target && ! $port{$target} ){
$port{$target} = $default_port;
......@@ -112,7 +113,7 @@ foreach $name ( keys %port){
printf $start "index=%s\n", $index ;
my $crude_port= $crude_port{$name} || $port{$name} || $default_port;
printf $start "crude_port=%s\n", $crude_port;
printf $start "max_hops=%s\n", $max_hops;
printf $start "max_hops=%s\n", $max_hop{$name};
# printf $start "%s", $startcfg;
close $start;
}
......
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="/uninett-bootstrap-theme/css/bootstrap.min.css">
<!-- Custom styles for this template -->
<link rel="stylesheet" href="/uninett-theme/css/uninett.css">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<!-- Bootstrap core JavaScript -->
<!-- Placed at the end of the document so the pages load faster -->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="js/datatables.min.css"/>
<script type="text/javascript" language="javascript" src="js/datatables.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<!-- empty meta method in autohandler -->
<title>Micro dependability measurement node map</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
; @import url("/styles.css");
</style>
<link rel="author" href="mailto:drift@uninett.no">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!--
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.js" type="text/javascript"></script>
<script href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.css" rel="stylesheet" type="text/css"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
-->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.markercluster@1.0.3/dist/leaflet.markercluster-src.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.0.3/dist/MarkerCluster.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.0.3/dist/MarkerCluster.Default.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet-contextmenu/1.2.1/leaflet.contextmenu.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-contextmenu/1.2.1/leaflet.contextmenu.min.js"></script>
<script src="./js/leaflet.curve.js"></script>
<script src="./js/L.LatLng.UTM.js"></script>
<!-- <script src="./js/latlon-spherical.js"></script> -->
<script src="./js/stats.js"></script>
<script src="js/sorttable.js"></script>
<script src="graph.js"></script>
<script>
// assigning new property with function so child window can point it
document.functionToBeCalledFromChildWindow = function (param){
alert(param);
// further processing.
}
</script>
<style type="text/css">
#mapid { height: 900px; z-index: 1;}
#midding {width:600px}
#busyx { margin: auto;
width: 5%;
/* border: 3px solid #2222aa; */
padding: 10px;
}
/* css to customize Leaflet default styles */
.popupCustom .leaflet-popup-tip,
.popupCustom .leaflet-popup-content-wrapper {
font-size:large;
background: #e0e0e0;
color: #234c5e;
}
.leaflet-popup, .leaflet-pane {
font-size:large;
}
.knapp, select, td, th { font-size:x-large; }
table td { padding:5px; }
.knapp { line-height: 1.3em; }
th {
cursor: pointer;
}
caption { font-size: x-large; font-weight: bold; }
</style>
</head>
<body style="height:50%">
<!-- <h2>Micro dependability measurement node map</h2> -->
<!--
<button class=knapp id="draw">Connections</button>
-->
<select id=network class=knapp title='Measurement network'>
<option value=dragonlab>Dragonlab</option>
<option value=uninett>Uninett</option>
</select>
<select id=event_type title='Measurement type'>
<option value=gapsum>Gap summary</option>
<option value=gap>Gaps</option>
<option value=jitter>Queues</option>
<option value=routesum>Route summary</option>
<option value=routeerr>Route errors</option>
</select>
<select id=prop_select class=knapp title='Measurement variable'></select>
<select id=stats_type class=knapp title='Statistics type'>
<option value="99.0">99%</option>
<option value="95.0">95%</option>
<option value="50.0">50%</option>
<option value="1.0">1%</option>
<!-- <option value=avg>Average</option>
<option value=min>Minimum</option>
<option value=max>Maximum</option> -->
</select>
<select class=knapp id=period title='Measurement period'>
<option value=1>Hour</option>
<option value=24 selected="selected">Day</option>
<option value=168>Week</option>
<option value=672>4 weeks</option>
</select>
<input class=knapp type="text" id="datepicker" size=12em title='Measurement start'>
<input class=knapp type="text" id="period_input" size=4em placeholder="00:00" title='Starting hour'>
<button class=knapp id=prev title='Previous period'>Prev</button>
<button class=knapp id=next title='Next period'>Next</button>
<!--
<button class=knapp id=search>Search</button>
-->
<input class=knapp type="search" id="search_input" size=5em placeholder=search title='Type to select by link names'>
<!---->
<span class=knapp id=refs></span>
<button class=knapp id=live title="Refresh display every minute">Autorefresh</button>
<img id=busy src=js/ajax-loader.gif>
<!--
<div id=busy><img width=100% src=/js/ajax-loader.gif></div>
-->
<main id=tabs>
<ul>
<li><a href="#mapid">Map</a>
<li>
<select class=knapp id=check title='Reports for current parameter'>
<option value=choose>+</option>
<!-- <option value=curve title='Table of alle variables'>Line curve</option> -->
<option value=heatmap title='Table of alle variables'>Heatmap</option>
<option value=missing title='Missing opposite links'>Missing</option>
<option value=asymmetry title='Asymmetry in selected variable'>Asymmetry</option>
<option value=summary title='Table of alle variables'>Summary</option>
</select>
</li>
<!-- <li><a href="#report">Report</a> -->
</ul>
<div id="mapid"></div>
<!-- <div id="report"></div> -->
</main>
<div id=legend></div>
<div>
<b>Last status:</b><span id=status>none</span>
<b>Last error:</b><span id=error>none</span>
</div>
<div id=missing></div>
*) The positons of sites are a guess and not official.
<!-- <div id=dialog>testing dialog popup</div> -->
<script type="module">
import LatLon from "./js/latlon-spherical.js";
var conffile=[]; //Config file loaded initially
var parms={};
var start, end; // startend time for current period
var point_distance_min = 50; // meters between
var point_distance_stretch = 0.001; // delta degrees
var period_length = 86400; // a day - to be replaced by dynamic length
var mymap, parms;
var markers = [];
var clustergroup=[];
var active_cluster;
var links=[];
var color_store=[];
var color_on=[]; // bool by color focused
var linkByName=[];
var linkHidden=[]; //
var ip_to_name=[]; //
var name_to_ip=[]; //
var name_loaded=[]; // by network
var ends=[];
var last_hits=[]; // last query detail data (gaps)
var summary=[]; // last summary of query data (gapsum, gaps)
var aggregates=[]; // last aggregate data (jitter)
var focus_node="";
var middle_point=[],
line_bearing=[],
line_utslag=[];
var n_excluded=0;
var current_parm="down_ppm";
var refresh_period=60000; // one minute refresh of data
var refresh_active=false;
var active_color="LightGray"; // to store actual color
var refresh_color="Aqua";
var no_coords= new LatLon(70.98584, -8.49243); // Jan Mayen
var points=[];
var empty_color="LightGray";
var prop_names_list = {
gapsum: "down_ppm h_ddelay h_jit h_min_d big_gaps big_time small_gaps small_time".split(" "),
gap: "down_ppm tloss h_ddelay h_jit h_min_d h_slope_10".split(" "),
jitter: "h_ddelay h_jit h_min_d h_slope_10".split(" "),
routesum: "routes_failed routes_reached probes_stopped_at_last_hop probes_with_none_dst_last_hop routes_analysed routes_reached min_length max_length".split(" "),
routeerr: "anomaly_count duration last_hop last_reply_from icmp_errors".split(" ")
};
var event_names;
var event_desc={ gapsum: "Gap summary", gap: "Gaps", jitter: "Queues", routesum: "Route summary", routeerr: "Route errors"};
var prop_names;
var prop_desc= { down_ppm:"Unavailability (PPM)", h_ddelay:"Queue(ms)", h_jit:"Jitter(ms)",
h_min_d:"Min delay(ms)", h_delay:"Avg delay(ms)",
tloss:"Time lost(ms)", h_slope_10:"Slope",
big_gaps:"Big gaps(#)", big_time:"Big gap time(s)", small_gaps:"Small gaps(#)", small_time:"Small gap time(s)"
};
var prop_sum = ['tloss', 'anomaly_count'];
// assign names as description temporarily
for ( const record of 'routesum routeerr'.split(" ") ){
for ( const prop of prop_names_list[record] ){
if ( ! prop_desc[prop] ) prop_desc[prop] = prop;
}
}
var stats_on={ jitter:true}; // show stats_type field
var stats_types = { "1.0": "1%", "50.0": "50%", "95.0": "95%", "99.0": "99%" };
var thresholds={
h_delay:[10,50],
h_min_d:[10,50],
h_ddelay:[5,50],
h_jit:[2,20],
down_ppm:[100,1000],
h_slope_10:[0.1,0.2]
};
var a=1;
var lat, lng;
var loads=0; // number of loaded point series
var duplines=[];
var points_cache=[];
function update_props(mvar) {
// Repopulate property structures based on given measuerment network variant and config file
if (jQuery.isEmptyObject(conffile)) {
// No config file data available
return
}
// Clear list first
prop_names_list ={};
prop_desc ={};
event_desc={};
for (const e in conffile[mvar].event_type) {
prop_names_list[e]=[];
event_desc[e] = conffile[mvar].event_type[e].title
for (const f in conffile[mvar].event_type[e].field) {
prop_names_list[e].push(f);
var unit = conffile[mvar].event_type[e].field[f].unit
var title = conffile[mvar].event_type[e].field[f].title
prop_desc[f] = title + ( unit ? " (" + unit + ")" : "") ;
}
}
}
// sorting table
function comparer(index) {
return function(a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index)
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.toString().localeCompare(valB)
}
}
function getCellValue(row, index){ return $(row).children('td').eq(index).text() }
function fill_select(select_id, types){
var select = $("#".select_id);
select.empty();
for ( const type in types){
select.append( $('<option>', { value: type, text: types[type] } ) );
}
}
function show_map (network) {
console.log ("Showing map");
if ( ! mymap ){
mymap = L.map('mapid');
// create the tile layer with correct attribution
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 1, maxZoom: 20, attribution: osmAttrib});
mymap.addLayer(osm);
mymap.addEventListener('mousemove', function(ev) {
lat = ev.latlng.lat;
lng = ev.latlng.lng;
});
$(window).on("resize", function () {
$("#mapid").height( $(window).height()-400 );
}).trigger("resize");
}
if ( active_cluster){
mymap.removeLayer(active_cluster);
}
if ( ! ( network in clustergroup ) ){
clustergroup[network] = new L.markerClusterGroup();
make_markers( network, points, true);
}
active_cluster = clustergroup[network];
mymap.addLayer( active_cluster);
points_cache[network]=points;
}
// add parameter to url
// *** ignore parameters after this..
function fix_url( url, parm, value){
var ny;
var ix=url.indexOf("?");
if ( url.indexOf("?") < 0 ){
url+="?";
}
var ix=url.indexOf(parm+"=");
if ( ix >= 0){
ny=url.substr(0,ix);
} else {
ny=url;
}
if ( ny.slice(-1) !== '&' ) ny += '&';
return ny + parm + "=" + value;
}
function update_url(parameter, value){
var url=document.location.href;
var urlparts= url.split('?');
var urlBase=urlparts.shift();
var pars=[];
var etype= $("#event_type").val();
pars=["net=" + $("#network").val(),
"event=" + etype,
"property=" + $("#prop_select").val(),
"date=" + $("#datepicker").val(),
"period=" + $("#period").val() ];
if ( etype === "jitter" && $("#stats_type").val() )
pars.push( "stats=" + $("#stats_type").val() );
if ( parameter )
pars.push( parameter + "=" + value );
url = urlBase+'?'+pars.join('&');
window.history.pushState('',document.title,url); // added this line to push the new url directly to url bar .
if ( stats_on[ $("#event_type").val() ] )
$("#stats_type").show();
else
$("#stats_type").hide();
}
function removeParam(parameter){
var url=document.location.href;
var urlparts= url.split('?');
if (urlparts.length>=2)
{
var urlBase=urlparts.shift();
var queryString=urlparts.join("?");
var prefix = encodeURIComponent(parameter)+'=';
var pars = queryString.split(/[&;]/g);
for (var i= pars.length; i-->0;)
if (pars[i].lastIndexOf(prefix, 0)!==-1)
pars.splice(i, 1);
url = urlBase+'?'+pars.join('&');
window.history.pushState('',document.title,url); // added this line to push the new url directly to url bar .
}
return url;
}
function make_prop_select(id, names, desc){
var selectList=document.getElementById(id);
selectList.options.length = 0; // remove previous
for (var i = 0; i < names.length; i++) {
var option = document.createElement("option");
option.value = names[i];
//var text=prop_desc[names[i]];
var text=desc[names[i]];
if ( ! text ) text = names[i];
option.text = text;
selectList.appendChild(option);
}
}
function remove_markers(){
clustergroup.eachLayer(function(m) {
clustergroup.removeLayer(m);
// console.log('marker', m._tooltip.options._content + " " + m);
});
}
// spread points that share position
function spread_points(points){
var locations=[];
for ( var i=0; i < points.length; i++ ){
var p1=new LatLon(points[i].lat, points[i].lon);
for ( var j=0; j < points.length; j++ ){
var p2=new LatLon(points[j].lat, points[j].lon);
var distance = 0 + ( p1.distanceTo(p2) );
if ( distance < point_distance_min ){
points[j].lat += point_distance_stretch * ( Math.random() - 0.5 );
points[j].lon += point_distance_stretch * ( Math.random() - 0.5 );
}
}
}
}
function make_markers ( network, points, focus) {
var i;
var bounds = new L.LatLngBounds();
spread_points(points);
for (i=0; i < points.length; i++){
var id=points[i].id;
var marker = L.marker ([points[i].lat, points[i].lon]).addTo(clustergroup[network]);
bounds.extend(marker.getLatLng());
marker.bindTooltip( points[i].name, {permanent: false, className: "my-label", offset: [0, 0] });
// var nodeurl= window.location.origin + window.location.pathname+ "?net=" + parms.net + "&;
// var nodeurl = fix_url( window.location.href, "node", id );
// var html = '<br><a href="' + nodeurl + '">Focus on</a>';
// var html = '<br><button id="' + id + '" class="trigger">Focus on</button>';
var html = '<br><a href="#" class=trigger id="' + id + '">Focus on</a>';
var url;
if (points[i].url){
url = points[i].url;
} else {
url = "http://" + id;
}
marker.bindPopup("<b><a href=\"" + url + "\">" + "Home for " + id + "</a></b>"+html);
$("#" + id ).on('click', "a.trigger", function(e){
focus_links( e.id, 'flip' );
});
}
if ( focus ){
mymap.fitBounds(bounds);
}
}
//function draw_net(){
//}
function remove_links(){
var i;
for ( i=0; i<links.length; i++ ){
// mymap.removeLayer(links[i]);
if ( links[i] ) links[i].remove();
}
links=[];
linkByName=[];
ends=[];
}
function remove_link(ab){
if ( linkByName[ab] ){
linkByName[ab].remove();
delete linkByName[ab];
ends.splice( ends, ends.indexOf(ab), 1);
}
}
function show_links(){
for ( var ab in linkByName ){
linkByName[ab].addTo(mymap);
}
}
function hide_links_by_color(color){
for ( var ab in linkByName ){
var link=linkByName[ab];
if ( link.options.color === color){
link.remove(); // remove from map
linkHidden[ab]=true;
} else if (linkHidden[ab]) {
link.addTo(mymap);
linkHidden[ab]=false;
}
}
}
function show_links_by_color(color){
for ( var ab in linkByName ){
var link=linkByName[ab];
if ( link.options.color === color){
link.addTo(mymap); // add to map
linkHidden[ab]=false;
}
}
}
function refresh_links_by_color(){
if ( links_on ){
show_links_by_color(empty_color);
} else {
hide_links_by_color(empty_color);
}
}
function only_links_by_color(color){
if ( color_on[color] ){
for ( var ab in linkByName ){
if ( linkHidden[ab] )
linkByName[ab].addTo(mymap); // add to map
}
color_on[color]=false;
} else {
for ( var ab in linkByName ){
var link=linkByName[ab];
if ( link.options.color === color){
if ( linkHidden[ab] )
link.addTo(mymap); // add to map
link.bringToFront();
} else {
link.remove(); // remove from map
linkHidden[ab]=true;
}
}
for ( var c of colors)
color_on[c]=false;
color_on[color]=true;
}
}
function focus_links( node, mode ){
if ( mode === 'flip' && focus_node === node ){ // flip back
focus_node = "";
links_on=true;
show_links();