Last active
March 4, 2024 12:47
-
-
Save victorjonsson/f9dc8478df39958ca07ec3f4e4dcbcaf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<!-- CSS only --> | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> | |
</head> | |
<body class="p-5" onload="renderLog(document.getElementById('the-log').value)"> | |
<textarea id="the-log" onchange="renderLog(this.value)" style="width:80%">2022-05-23 15:55:58.6740|INFO|GXApp.Services.Filesystem.LogService+LogServiceInstance|====> MALΓ Controller App starting <==== | |
2022-05-23 15:55:58.7772|INFO|IoActorV2| AppVersion: 10.20512, ComLib v10.02 | |
2022-05-23 15:55:58.7974|INFO|IoActorV2| Device Model: SM-T545, Manufacturer: samsung, DeviceName: Galaxy Tab Active Pro, Version:11, Platform: Android, Idiom: Tablet, DeviceType: Physical | |
2022-05-23 15:55:58.8023|INFO|ActorSystem| Antenna Service initialized. | |
2022-05-23 15:55:58.9335|INFO|ActorSystem| SetComlibDebugFile: Disabled | |
2022-05-23 15:55:58.9557|INFO|ActorSystem| HomeViewModelInstance: New appVersion 10.20512 installed (from previous ). Reset feature tour flag | |
2022-05-23 15:55:58.9598|INFO|ActorSystem| HomeViewModelInstance: Instance initiated | |
2022-05-23 15:56:06.6653|INFO|IoActorV2| MsgConnect from IoActorV2 : New Ip addresses found. lastUsedIpAddress: 0.0.0.0, try ReInitComLib(192.168.210.86) with init delay 1000 | |
2022-05-23 15:56:07.7080|INFO|IoActorV2| MsgConnect from IoActorV2 : ReInitComLib(192.168.210.86) success. | |
2022-05-23 15:56:07.7398|INFO|IoActorV2| CheckGnssStatus: GnssStatus updated from -1 to NoData | |
2022-05-23 15:56:07.7398|INFO|IoActorV2| MsgConnect from ActorSystem : New Ip addresses found. lastUsedIpAddress: 0.0.0.0, try ReInitComLib(192.168.210.86) with init delay 2000 | |
2022-05-23 15:56:09.7481|INFO|IoActorV2| MsgConnect from ActorSystem : ReInitComLib(192.168.210.86) success. | |
2022-05-23 15:56:09.7730|INFO|IoActorV2| MsgConnect from IoActorV2 : New Ip addresses found. lastUsedIpAddress: 0.0.0.0, try ReInitComLib(192.168.210.86) with init delay 3000 | |
2022-05-23 15:56:12.7739|INFO|IoActorV2| MsgConnect from IoActorV2 : ReInitComLib(192.168.210.86) success. | |
2022-05-23 15:56:12.7982|INFO|IoActorV2| MsgConnect from ActorSystem : New Ip addresses found. lastUsedIpAddress: 0.0.0.0, try ReInitComLib(192.168.210.86) with init delay 4000 | |
2022-05-23 15:56:16.7997|INFO|IoActorV2| MsgConnect from ActorSystem : ReInitComLib(192.168.210.86) success. | |
2022-05-23 15:56:17.0418|INFO|IoActorV2| MsgConnect from IoActorV2 : New Ip addresses found. lastUsedIpAddress: 0.0.0.0, try ReInitComLib(192.168.210.86) with init delay 5000 | |
2022-05-23 15:56:22.0430|INFO|IoActorV2| MsgConnect from IoActorV2 : ReInitComLib(192.168.210.86) success. | |
2022-05-23 15:56:22.2849|INFO|IoActorV2| MsgConnect from ActorSystem : New Ip addresses found. lastUsedIpAddress: 0.0.0.0, try ReInitComLib(192.168.210.86) with init delay 6000 | |
2022-05-23 15:56:28.2852|INFO|IoActorV2| MsgConnect from ActorSystem : ReInitComLib(192.168.210.86) success. | |
2022-05-23 15:56:28.3476|INFO|IoActorV2| MsgConnect from ActorSystem : Comlib connect success | |
2022-05-23 15:56:28.5107|INFO|IoActorV2| MsgConnect from ActorSystem : HandleMsgConnect(): SDCardStatus read from settings and set to 0 | |
2022-05-23 15:56:28.5644|INFO|IoActorV2| MsgConnect from ActorSystem : HandleMsgConnect(): SDCardStatus check OK | |
2022-05-23 15:56:28.6601|INFO|IoActorV2| MsgConnect from ActorSystem : Antenna connected | |
2022-05-23 15:56:28.7777|WARN|ActorSystem| timeInterval is zero, setting HorizontalTickInterval = 0.05 | |
2022-05-23 15:56:29.0299|INFO|IoActorV2| MsgGetBatteryVoltage from BoundaryReceiverActor : Internal GPS NMEA output enable success | |
2022-05-23 15:56:29.0892|INFO|ActorSystem| Refresh: Call GetAntennaSettings() and GetBatteryVoltage() | |
2022-05-23 15:56:29.3056|INFO|IoActorV2| CheckGnssStatus: GnssStatus updated from -4 to GPSFix | |
2022-05-23 15:56:29.7426|INFO|IoActorV2| Setting trig type to WHEEL: distanceInterval=0.0248053469303383 m | |
2022-05-23 15:56:29.7576|INFO|IoActorV2| TestPattern mode set to False | |
2022-05-23 15:56:49.1091|INFO|GXApp.Droid.Renderers.LoggingButtonRenderer|"StartupInfoPopupPageSkipButton" | |
2022-05-23 15:56:49.4522|INFO|ActorSystem| ShowProjectChecking: DONE | |
2022-05-23 15:56:50.3724|INFO|GXApp.Droid.Renderers.LoggingButtonRenderer|"2DButton" | |
2022-05-23 15:56:51.5710|INFO|GXApp.Droid.Renderers.LoggingButtonRenderer|"ProjectInfoPopupPageOkButton" | |
2022-05-23 15:56:59.4152|INFO|GXApp.Views.MeasurementSettingsPage|"TriggerPicker","Distance" | |
2022-05-23 15:56:59.4300|INFO|GXApp.Views.MeasurementSettingsPage|"WheelSelectionPicker","Core" | |
2022-05-23 15:56:59.4664|INFO|GXApp.Views.MeasurementSettingsPage|"PositioningSelectionPicker","Internal GPS" | |
2022-05-23 15:56:59.4792|INFO|GXApp.Views.MeasurementSettingsPage|"VerticalScaleSelectionPicker","Depth" | |
2022-05-23 15:56:59.4944|INFO|GXApp.Views.MeasurementSettingsPage|"MeasurementUnitSelectionPicker","Metric" | |
2022-05-23 15:56:59.5125|INFO|GXApp.Views.MeasurementSettingsPage|"MalaVisionModeSelectionPicker","PRODUCTION" | |
2022-05-23 15:56:59.5258|INFO|GXApp.Views.MeasurementSettingsPage|"RepairModeSelectionPicker","On" | |
2022-05-23 15:57:03.9503|INFO|GXApp.Views.MeasurementSettingsPage|"TriggerPicker","Time" | |
2022-05-23 15:57:04.0848|INFO|IoActorV2| Setting trig type to TIME: timeInterval=0.05 s | |
2022-05-23 15:57:09.2228|INFO|ActorSystem| GxPageViewModel(): SDCardStatus check returned OK | |
2022-05-23 15:57:09.4979|INFO|ActorSystem| Antenna Service: StartMeasuring(Random,1,0) ProjectID=5f84b903-cc85-42b6-8a25-30b78eda4507 ProfileID=db7f2692-5bd6-46d4-ba76-91dfc10b160d | |
2022-05-23 15:57:09.5646|INFO|ActorSystem| Start measurement sent: Proj2D-0001 - Profile 1 [1], MonitorID:0, AntennaID:26602001, AntennaModel:GX750, Trig:Time, Interval:0.05 s, Positioning:AntennaGnss, COR:Yes, Voltage: | |
2022-05-23 15:57:09.5646|INFO|GXApp.Droid.Renderers.LoggingButtonRenderer|"StartStopButton" | |
2022-05-23 15:57:09.7736|INFO|IoActorV2| Measuring started | |
2022-05-23 15:57:09.7904|INFO|ActorSystem| OnMeasuringStarted(): Measurement started received | |
2022-05-23 15:57:09.7904|INFO|ActorSystem| Measurement started received | |
2022-05-23 15:57:09.9715|ERROR|ActorSystem| AddTraceTimeData Exception: System.NullReferenceException: Object reference not set to an instance of an object | |
at GXApp.Services.ProjectService+ProjectServiceInstance.AddTraceTimeData (System.UInt32 traceNr, System.DateTime anntennaTraceTime, System.Boolean isPps) [0x00006] in <997ef4725b8b414694455fbe73bbbe13>:0 | |
2022-05-23 15:57:09.9715|ERROR|ActorSystem| AddTraceTimeData Exception: System.NullReferenceException: Object reference not set to an instance of an object | |
at GXApp.Services.ProjectService+ProjectServiceInstance.AddTraceTimeData (System.UInt32 traceNr, System.DateTime anntennaTraceTime, System.Boolean isPps) [0x00006] in <997ef4725b8b414694455fbe73bbbe13>:0 | |
2022-05-23 15:57:09.9995|INFO|IoActorV2| MsgPoll from IoActorV2 : Trace 1 | |
2022-05-23 15:57:12.8216|INFO|ActorSystem| MeasuringCmd: Stop button pressed. Enter stop procedure: Proj2D-0001 - Profile 1 [1] | |
2022-05-23 15:57:12.8216|INFO|GXApp.Droid.Renderers.LoggingButtonRenderer|"StartStopButton" | |
2022-05-23 15:57:12.8293|INFO|ActorSystem| MeasuringCmd: Call _antenna.SyncStopMeasuring() | |
2022-05-23 15:57:13.8789|INFO|IoActorV2| MsgSyncStopMeasuring from ActorSystem : StopMeasurement() returned 0 | |
2022-05-23 15:57:13.8914|INFO|IoActorV2| MsgSyncStopMeasuring from ActorSystem : StopMeasurement() success in HandleMsgSyncMeasuring() | |
2022-05-23 15:57:13.9597|INFO|ActorSystem| MeasuringCmd: SyncStopMeasuring IsSyncReady:True cntSyncStop:0 | |
2022-05-23 15:57:13.9757|INFO|ActorSystem| MeasuringCmd: Ignore call SyncMeasurement since 0 missedTraces | |
2022-05-23 15:57:13.9848|INFO|ActorSystem| MeasuringCmd: Now send stop measurement sent | |
2022-05-23 15:57:13.9932|INFO|ActorSystem| MeasuringCmd: Stop measurement sent | |
2022-05-23 15:57:14.9999|INFO|IoActorV2| MsgStopMeasuring from ActorSystem : HandleMsgStopMeasuring: MsgCorData _lastTraceNrInCorFile=61 _syncInProgress=False Timestamp=23/05/2022 13:57:13 SyncTimestamp=23/05/2022 13:57:13</textarea> | |
<hr> | |
<script type="text/html" id="log-template"> | |
<div class="card" style="width: 90%"> | |
<small style="color: #999; padding:1rem 0 0 1rem">%HEAD%</small> | |
<small class="gps" style="position: absolute; right:15px; top:10px; color: gray">π %GPS_STATUS%</small> | |
<div class="card-body"> | |
<h5 class="card-title" title="%MESSAGE%">%TITLE%</h5> | |
<p class="card-text log-summary"></p> | |
<p style="display:none" class="card-text log-entries"></p> | |
</div> | |
</div> | |
<div class="arrow" style="display: none; font-size:300%; padding-left: 1rem; color:#999"> | |
β | |
<strong style="font-size:30%; margin:25px 0 0; position:absolute">%TIME%</strong> | |
</div> | |
</script> | |
<div id="container"></div> | |
<script> | |
const parseLogLine = (line) => { | |
const parts = line.split('|'); | |
try { | |
return { | |
date: new Date(parts[0].trim()), | |
type: parts[1].trim(), | |
id: parts[2].trim(), | |
message: parts.filter((v,i) => i > 2).join('|'), | |
traceData: '', | |
title: '', | |
children: [] | |
} | |
} catch(err) { | |
console.warn("unable to parse line " + line + ', will return as trace data'); | |
return { | |
date: undefined, | |
type: '', | |
id: '', | |
message: line, | |
traceData: '', | |
title: '', | |
children: [] | |
} | |
} | |
}; | |
const parseLog = logData => { | |
return logData.trim().split('\n').map(line => parseLogLine(line)); | |
} | |
const gpsNoData = 'NoData'; | |
let previousGpsState = gpsNoData; | |
const renderLogSection = (logSection, container) => { | |
const template = document.getElementById('log-template').innerHTML; | |
const element = document.createElement('DIV'); | |
const gpsKeyWords = 'GnssStatus updated from'; | |
if (logSection.message.indexOf('App starting') > -1) { | |
previousGpsState = 'NoData'; | |
} | |
const gpsStatuses = logSection.children | |
.filter(entry => entry.message.indexOf(gpsKeyWords) > -1) | |
.map(entry => entry.message.split(gpsKeyWords)[1].split(' ')[3]); | |
let gpsMessage = gpsStatuses.length === 0 ? previousGpsState : gpsStatuses.join(', ') | |
if (gpsMessage !== gpsNoData) { | |
const internalGps = logSection.children.some(c => c.message.indexOf('Internal GPS NMEA') > -1); | |
if (internalGps) { | |
gpsMessage += ' (internal)'; | |
} | |
} | |
previousGpsState = gpsMessage === gpsNoData ? gpsNoData : (gpsStatuses.length ? gpsStatuses.pop() : gpsMessage); | |
const html = template | |
.replace('%TITLE%', logSection.title) | |
.replace('%MESSAGE%', logSection.message) | |
.replace('%GPS_STATUS%', gpsMessage) | |
.replace('%HEAD%', getNiceDate(logSection.date) + ' ' + getClock(logSection.date)); | |
element.innerHTML = html; | |
container.appendChild(element); | |
element.setAttribute('data-date', logSection.date.toString()); | |
const logEntryContainer = element.querySelector('.log-entries'); | |
let counts = {}, currentStatusColor; | |
logSection.children.forEach(logEntry => { | |
const logEntryElem = document.createElement('DIV'); | |
let message = logEntry.message + '\n' + logEntry.traceData; | |
if (!logEntry.date) { | |
// this is only a new line of last message | |
logEntryElem.innerHTML = '<div style="background: '+currentStatusColor+'">' + message + '</div>'; | |
} else { | |
counts[logEntry.type] = (counts[logEntry.type] || 0) + 1; | |
currentStatusColor = logEntry.type === 'ERROR' ? ('pink') : (logEntry.type === 'WARN' ? 'lightyellow' : '') | |
if (message.indexOf(gpsKeyWords) > -1) { | |
message = 'π ' + message; | |
} | |
logEntryElem.innerHTML = '<div style="background: '+currentStatusColor+'">' +getClock(logEntry.date)+ ' ' +logEntry.type+ ' -> ' + message + '</div>'; | |
} | |
logEntryContainer.appendChild(logEntryElem); | |
}); | |
element.querySelector('.log-summary').innerHTML = '<span>'+JSON.stringify(counts)+'</span> <a href="#" onclick="this.parentNode.parentNode.querySelector(\'.log-entries\').style.display =\'block\'; return false; ">See logs</a>'; | |
if (gpsMessage === 'NoData') { | |
element.querySelector('.gps').style.filter = 'grayscale(100%)'; | |
} | |
return element; | |
} | |
const updateTimePast = (logEntryElem, newDate) => { | |
if (newDate && logEntryElem) { | |
const date = new Date(logEntryElem.getAttribute('data-date')); | |
const arrowElem = logEntryElem.querySelector('.arrow'); | |
if (getNiceDate(date) !== getNiceDate(newDate)) { | |
arrowElem.innerHTML = '<span style="font-weight: bold; padding:25px 0 10px; display:block; font-size: 60%">' + getNiceDate(newDate) + '</span>'; | |
} else { | |
const milliSeconds = newDate.getTime() - date.getTime(); | |
const seconds = Math.round(milliSeconds / 1000); | |
const timePast = seconds > 60 ? (Math.floor(seconds/60) +'min '+ seconds%60 +'s') : seconds + 's' | |
arrowElem.querySelector('strong').innerText = timePast; | |
} | |
arrowElem.style.display = 'block'; | |
} | |
} | |
const getClock = date => { | |
return date.toString().split(' ').filter((v,i) => i > 3 && i <5).join(' '); | |
} | |
const getNiceDate = date => { | |
return date.toString().split(' ').filter((v,i) => i < 3).join(' ') + ' ' | |
} | |
window.renderLog = (someData) => { | |
let logSections = []; | |
let logEntryHtmlNode; | |
let nextLogSectionIndex; | |
const container = document.getElementById('container'); | |
container.innerHTML = ''; | |
parseLog(someData).filter(d => !!d).forEach(d => { | |
if (d.message.indexOf('App starting') > -1) { | |
nextLogSectionIndex = logSections.push(d) - 1; | |
logSections[nextLogSectionIndex].title = 'π‘ App starting'; | |
} else if (d.message.indexOf('Antenna connected') > -1) { | |
nextLogSectionIndex = logSections.push(d) - 1; | |
logSections[nextLogSectionIndex].title = 'π‘ Antenna connected'; | |
} else if (d.message.indexOf('Measuring started') > -1) { | |
nextLogSectionIndex = logSections.push(d) - 1; | |
logSections[nextLogSectionIndex].title = 'βΆοΈ Measuring started'; | |
} else if (d.message.indexOf('MeasuringCmd: Stop measurement sent') > -1) { | |
nextLogSectionIndex = logSections.push(d) - 1; | |
logSections[nextLogSectionIndex].title = 'β Measuring stopped'; | |
} else if (d.message.indexOf('Set connected=false, since lastPing') > -1) { | |
nextLogSectionIndex = logSections.push(d) - 1; | |
logSections[nextLogSectionIndex].title = 'π₯π‘π₯ Lost antenna connection'; | |
} else { | |
if (nextLogSectionIndex === undefined) { | |
nextLogSectionIndex = logSections.push(d) - 1; | |
logSections[nextLogSectionIndex].title = 'Log started...'; | |
} else { | |
logSections[nextLogSectionIndex].children.push(d); | |
} | |
} | |
}); | |
logSections.forEach(logSection => { | |
if (logEntryHtmlNode) { | |
updateTimePast(logEntryHtmlNode, logSection.date); | |
} | |
try { | |
logEntryHtmlNode = renderLogSection(logSection, container); | |
} catch (err) { | |
console.error('Unable to render log section', err, logSection); | |
} | |
}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment