function parse_messages() { var el_log_messages = document.getElementById('log_messages'); var el_new_chart = document.getElementById('new_chart'); var messages = el_log_messages.innerHTML.split(/\n/); var stats = { "stations" : {}, "assoc_ok" : {}, "assoc_ref" : {}, "login_ok" : {}, "login_fail" : {}, "link_up" : {}, "del_station" : {}, "fail_log" : {}, "test_start" : null }; var assoc_data = { labels: [], //"Association Events", "Association Latency"], series: [ { name: 'test-start', data:[]}, { name: 'test-data', data:[]} ] }; var denied_data = { labels: [], //"Denied Events", "Denied Latency"], series: [ { name: 'test-start', data:[]}, { name: 'test-data', data:[]} ] }; var login_data = { labels: [], //"Login Events", "Login Latency"], series: [ { name: 'test-start', data:[]}, { name: 'test-data', data:[]} ] }; var latency_chart_options = { showLine: false, width: 800, height: 300, axisX: { type: Chartist.FixedScaleAxis, labelInterpolationFnc: function(value) { return moment(value).format('mm:ss'); }, divisor: 12 }, axisY: { labelInterpolationFnc: function(value) { if (value > 1000) { return (value/1000)+"s"; } return value + 'ms'; }, low: 0, divisor:5 }, series: { 'test-start': { showPoint: false }, 'test-data': { showLine: false } } }; // parse the lines for (var i=0; i < messages.length; i++) { var line = messages[i]; var matches = line.match(/(sta\d+)/) || []; var sta = ""; var event_date = null; if (matches.length == 2) { sta = matches[1]; stats.stations[sta]++; matches = []; sta = ""; } // waiting for: messages are more reliably reported, will correspond to test start matches = line.match(/^(\d+\.\d+) # waiting for:/) || []; if (matches.length == 2) { event_date = new Date(matches[1]*1000); if (event_date) { stats.test_start = event_date; assoc_data.series[0].data.push({x:event_date, y: 0}); denied_data.series[0].data.push({x:event_date, y: 0}); login_data.series[0].data.push({x:event_date, y: 0}); //latency_chart_options.axisX["low"] = stats.test_start; event_date = null; } } // skip all things until test-start if (!stats.test_start) { //console.log("skipping|"+line); continue; } // Del station messages indicate a disassociation and might be considered // a resetart point in the process // 1498715632.789 WIFI-EVENT: 1.1: sta1212: del station f0:5c:19:21:a5:f3 matches = line.match(/^(\d+\.\d+) WIFI-EVENT: .\..: (sta\d+): del station/) || []; if (matches.length = 3) { sta = matches[2]; event_date = new Date(matches[1]*1000); if (event_date) { stats.del_station[sta] = event_date; } matches = []; sta = ""; } // Link UP messages is nice but they are not reliably reported // 1498715569.157 EVENT: 2017-06-29 02:51:51.701 eventId:14475 eidType:Port name:sta1000 eid:1.1.4 eventType:Link-Up details:Port sta1000 is Link UP. matches = line.match(/^(\d+\.\d+) EVENT: .*? Port (sta\d+) is Link UP/) || []; if (matches.length == 3) { sta = matches[2]; event_date = new Date(matches[1]*1000); if (event_date) { stats.link_up[sta]=event_date; } matches = []; sta = ""; } // 1498715632.737 WIFI-EVENT: 1.1: sta1227 (phy #1): auth f0:5c:19:21:a5:f3 -> 04:f0:21:88:58:98 status: 0: Successful matches = line.match(/^(\d+\.\d+) WIFI-EVENT: .*? (sta\d+) .*? auth .*? status: 0: Successful/) || []; if (matches.length == 3) { sta = matches[2]; event_date = new Date(matches[1]*1000); stats.assoc_ok[sta]++; if (event_date) { var delta_t = Math.abs(event_date - stats.test_start); if (stats.del_station[sta]) { delta_t = Math.abs(event_date - stats.del_station[sta]); } assoc_data.series[1].data.push({x: event_date, y: delta_t}); //console.log("assoc delta: "+delta_t); } matches = []; sta = ""; } // 1498715637.678 WIFI-EVENT: 1.1: sta1225 (phy #1): failed to connect to f0:5c:19:21:a5:f3, \ // status: 17: Association denied because AP is unable to handle additional associated STA matches = line.match(/^(\d+\.\d+) WIFI-EVENT: .*? (sta\d+) .*?: failed to connect to .*? status: \d+: Association denied/) || []; if (matches.length == 3) { event_date = new Date(matches[1]*1000); sta = matches[2]; stats.assoc_ref[sta]++; if (event_date) { var delta_t = Math.abs(event_date - stats.test_start); if (stats.del_station[sta] && (stats.del_station[sta] < event_date)) { delta_t = Math.abs(event_date - stats.del_station[sta]); } denied_data.series[1].data.push({x: event_date, y: delta_t}); } matches = []; sta = ""; } //1498715601.960 EVENT: 2017-06-29 02:52:25.773 eventId:15335 eidType:Port name:sta1114 eid:1.1.54 \ // eventType:IFUP-OK details:sta1114: OK portal login: OK -LOGIN (6766ms) matches = line.match(/^(\d+\.\d+) EVENT: .*? eventType:IFUP-OK details:(sta\d+): OK portal login: .*?.(\d+)ms.$/) || []; if (matches.length == 4) { event_date = new Date(matches[1]*1000); sta = matches[2]; //console.log("login date: "+event_date+" login_t: "+login_t); if (event_date) { var login_t = matches[3]; login_data.series[1].data.push({x: event_date, y: login_t}); } stats.login_ok[sta]++; matches = []; sta = ""; } // 1498726258.943 EVENT: 2017-06-29 05:51:15.548 eventId:17241 eidType:Port name:sta1114 eid:1.1.56 \ // eventType:IFUP-FAIL details:sta1114: Failed portal login: FAIL:no-redir-response no content from redirect0 matches = line.match(/^(\d+\.\d+) EVENT: .*? eventType:IFUP-FAIL details:(sta\d+): (.*)$/) || []; if (matches.length == 4) { event_date = new Date(matches[1]*1000); sta = matches[2]; stats.login_fail[sta]++; var match2 = matches[3].match(/(.*?) \(\d+ms\)$/) || []; if (match2.length == 2) { stats.fail_log[match2[1]]++; } else { stats.fail_log[matches[3]]++; } matches = []; sta = ""; } } // ~for each line stats["stations_count" ] = Object.keys(stats.stations ).length; stats["login_ok_count" ] = Object.keys(stats.login_ok ).length; stats["login_fail_count"] = Object.keys(stats.login_fail ).length; stats["assoc_ok_count" ] = Object.keys(stats.assoc_ok ).length; stats["assoc_ref_count" ] = Object.keys(stats.assoc_ref ).length; el_new_chart.appendChild(create_bar("Assoc OK", stats.assoc_ok_count, 100.0 * (stats.assoc_ok_count / stats.stations_count))); el_new_chart.appendChild(create_bar("Assoc Fail", stats.assoc_ref_count, 100.0 * (stats.assoc_ref_count / stats.stations_count))); el_new_chart.appendChild(create_bar("Login OK", stats.login_ok_count, 100.0 * (stats.login_ok_count / stats.stations_count))); el_new_chart.appendChild(create_bar("Login Fail", stats.login_fail_count, 100.0 * (stats.login_fail_count / stats.stations_count))); new Chartist.Line('#assoc_1', assoc_data, latency_chart_options); new Chartist.Line('#denied_1', denied_data, latency_chart_options); new Chartist.Line('#login_1', login_data, latency_chart_options); // want to append after new_chart a list of error event types var el_error_types = document.createElement("div"); el_error_types.id = "error_types"; el_new_chart.parentNode.insertBefore(el_error_types, el_new_chart.nextSibling); el_error_types.innerHTML = "