Log Parser

  • Love the new log parser, would be nice to have a stand-alone one as well that can run locally on my computer?


  • Admin

    You can actually copy/paste the embedded javascript to a standalone html page if you want. Here you go:

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></link>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <div id="parser">
    <h4>Paste log from gateway or node here:</h4>
    <textarea class="form-control" @change="parse" rows="10" v-model="source"></textarea>
    <button @click="parse" class="btn btn-primary">Parse</button>
    <button @click="source=''" class="btn btn-default">Clear</button>
    <h4>Human readable output:</h4>
    <div class="table-responsive">
    <table class="table table-condensed">
    <th>Node Id</th>
    <th>Child Sensor</th>
    <th>Command Type</th>
    <th>Ack Req/Resp</th>
    <tr v-for="r in parsed">
       <td v-for="c in r" v-html="c"></td>
    var types = {
    "internal": [
    command: [
    var match = [
    { re: /^(?:\d+ )?MCO:BGN:INIT (\w+),CP=([^,]+),VER=(.*)/, d: "Core initialization of <b>$1</b>, with capabilities $2, library version $3" },
    { re: /^(?:\d+ )?MCO:BGN:BFR/, d: "Callback before()" },
    { re: /^(?:\d+ )?MCO:BGN:STP/, d: "Callback setup()" },
    { re: /^(?:\d+ )?MCO:BGN:INIT OK,TSP=(.*)/, d: "Core initialized, transport status <b>$1</b>, (1=initialized, 0=not initialized, NA=not available)" },
    { re: /^(?:\d+ )?MCO:BGN:NODE UNLOCKED/, d: "Node successfully unlocked (see signing chapter)" },
    { re: /^(?:\d+ )?!MCO:BGN:TSP FAIL/, d: "Transport initialization failed" },
    { re: /^(?:\d+ )?MCO:REG:REQ/, d: "Registration request" },
    { re: /^(?:\d+ )?MCO:REG:NOT NEEDED/, d: "No registration needed (i.e. GW)" },
    { re: /^(?:\d+ )?!MCO:SND:NODE NOT REG/, d: "Node is not registered, cannot send message" },
    { re: /^(?:\d+ )?MCO:PIM:NODE REG=(\d+)/, d: "Registration response received, registration status <b>$1</b>" },
    { re: /^(?:\d+ )?MCO:PIM:ROUTE N=(\d+),R=(\d+)/, d: "Routing table, messages to node <b>$1</b> are routed via node <b>$2</b>" },
    { re: /^(?:\d+ )?MCO:SLP:MS=(\d+),SMS=(\d+),I1=(\d+),M1=(\d+),I2=(\d+),M2=(\d+)/, d: "Sleep node, duration <b>$1</b> ms, SmartSleep=<b>$2</b>, Int1=<b>$3</b>, Mode1=<b>$4</b>, Int2=<b>$5</b>, Mode2=<b>$6</b>" },
    { re: /^(?:\d+ )?MCO:SLP:TPD/, d: "Sleep node, powerdown transport" },
    { re: /^(?:\d+ )?MCO:SLP:WUP=(-?\d+)/, d: "Node woke-up, reason/IRQ=<b>$1</b> (-2=not possible, -1=timer, >=0 IRQ)" },
    { re: /^(?:\d+ )?!MCO:SLP:FWUPD/, d: "Sleeping not possible, FW update ongoing" },
    { re: /^(?:\d+ )?!MCO:SLP:REP/, d: "Sleeping not possible, repeater feature enabled" },
    { re: /^(?:\d+ )?!MCO:SLP:TNR/, d: " Transport not ready, attempt to reconnect until timeout" },
    { re: /^(?:\d+ )?MCO:NLK:NODE LOCKED. UNLOCK: GND PIN (\d+) AND RESET/, d: "Node locked during booting, see signing documentation for additional information" },
    { re: /^(?:\d+ )?MCO:NLK:TPD/, d: "Powerdown transport" },
    { re: /^(?:\d+ )?TSM:INIT/, d: "Transition to <b>Init</b> state" },
    { re: /^(?:\d+ )?TSM:INIT:STATID=(\d+)/, d: "Init static node id <b>$1</b>" },
    { re: /^(?:\d+ )?TSM:INIT:TSP OK/, d: "Transport device configured and fully operational" },
    { re: /^(?:\d+ )?TSM:INIT:GW MODE/, d: "Node is set up as GW, thus omitting ID and findParent states" },
    { re: /^(?:\d+ )?!TSM:INIT:TSP FAIL/, d: "Transport device initialization failed" },
    { re: /^(?:\d+ )?TSM:FPAR/, d: "Transition to <b>Find Parent</b> state" },
    { re: /^(?:\d+ )?TSM:FPAR:STATP=(\d+)/, d: "Static parent <b>$1</b> has been set, skip finding parent" },
    { re: /^(?:\d+ )?TSM:FPAR:OK/, d: "Parent node identified" },
    { re: /^(?:\d+ )?!TSM:FPAR:NO REPLY/, d: "No potential parents replied to find parent request" },
    { re: /^(?:\d+ )?!TSM:FPAR:FAIL/, d: "Finding parent failed" },
    { re: /^(?:\d+ )?TSM:ID/, d: "Transition to <b>Request Id</b> state" },
    { re: /^(?:\d+ )?TSM:ID:OK,ID=(\d+)/, d: "Node id <b>$1</b> is valid" },
    { re: /^(?:\d+ )?TSM:ID:REQ/, d: "Request node id from controller" },
    { re: /^(?:\d+ )?!TSM:ID:FAIL,ID=(\d+)/, d: "Id verification failed, <b>$1</b> is invalid" },
    { re: /^(?:\d+ )?TSM:UPL/, d: "Transition to <b>Check Uplink</b> state" },
    { re: /^(?:\d+ )?TSM:UPL:OK/, d: "Uplink OK, GW returned ping" },
    { re: /^(?:\d+ )?!TSM:UPL:FAIL/, d: "Uplink check failed, i.e. GW could not be pinged" },
    { re: /^(?:\d+ )?TSM:READY/, d: "Transition to <b>Ready</b> state" },
    { re: /^(?:\d+ )?TSM:READY:SRT/, d: "Save routing table" },
    { re: /^(?:\d+ )?TSM:READY:ID=(\d+),PAR=(\d+),DIS=(\d+)/, d: "Transport ready, node id <b>$1</b>, parent node id <b>$2</b>, distance to GW is <b>$3</b>" },
    { re: /^(?:\d+ )?!TSM:READY:UPL FAIL,SNP/, d: "Too many failed uplink transmissions, search new parent" },
    { re: /^(?:\d+ )?!TSM:READY:FAIL,STATP/, d: "Too many failed uplink transmissions, static parent enforced" },
    { re: /^(?:\d+ )?TSM:FAIL:CNT=(\d+)/, d: "Transition to <b>Failure</b> state, consecutive failure counter is <b>$1</b>" },
    { re: /^(?:\d+ )?TSM:FAIL:PDT/, d: "Power-down transport" },
    { re: /^(?:\d+ )?TSM:FAIL:RE-INIT/, d: "Attempt to re-initialize transport" },
    { re: /^(?:\d+ )?TSF:CKU:OK,FCTRL/, d: "Uplink OK, flood control prevents pinging GW in too short intervals" },
    { re: /^(?:\d+ )?TSF:CKU:OK/, d: "Uplink OK" },
    { re: /^(?:\d+ )?TSF:CKU:DGWC,O=(\d+),N=(\d+)/, d: "Uplink check revealed changed network topology, old distance <b>$1</b>, new distance <b>$2</b>" },
    { re: /^(?:\d+ )?TSF:CKU:FAIL/, d: "No reply received when checking uplink" },
    { re: /^(?:\d+ )?TSF:SID:OK,ID=(\d+)/, d: "Node id <b>$1</b> assigned" },
    { re: /^(?:\d+ )?!TSF:SID:FAIL,ID=(\d+)/, d: "Assigned id <b>$1</b> is invalid" },
    { re: /^(?:\d+ )?TSF:PNG:SEND,TO=(\d+)/, d: "Send ping to destination <b>$1</b>" },
    { re: /^(?:\d+ )?TSF:WUR:MS=(\d+)/, d: "Wait until transport ready, timeout <b>$1</b>" },
    { re: /^(?:\d+ )?TSF:MSG:ACK REQ/, d: "ACK message requested" },
    { re: /^(?:\d+ )?TSF:MSG:ACK/, d: "ACK message, do not proceed but forward to callback" },
    { re: /^(?:\d+ )?TSF:MSG:FPAR RES,ID=(\d+),D=(\d+)/, d: "Response to find parent request received from node <b>$1</b> with distance <b>$2</b> to GW" },
    { re: /^(?:\d+ )?TSF:MSG:FPAR PREF FOUND/, d: "Preferred parent found, i.e. parent defined via MY_PARENT_NODE_ID" },
    { re: /^(?:\d+ )?TSF:MSG:FPAR OK,ID=(\d+),D=(\d+)/, d: "Find parent response from node <b>$1</b> is valid, distance <b>$2</b> to GW" },
    { re: /^(?:\d+ )?TSF:MSG:FPAR INACTIVE/, d: "Find parent response received, but no find parent request active, skip response" },
    { re: /^(?:\d+ )?TSF:MSG:FPAR REQ,ID=(\d+)/, d: "Find parent request from node <b>$1</b>" },
    { re: /^(?:\d+ )?TSF:MSG:PINGED,ID=(\d+),HP=(\d+)/, d: "Node pinged by node <b>$1</b> with <b>$2</b> hops" },
    { re: /^(?:\d+ )?TSF:MSG:PONG RECV,HP=(\d+)/, d: "Pinged node replied with <b>$1</b> hops" },
    { re: /^(?:\d+ )?TSF:MSG:BC/, d: "Broadcast message received" },
    { re: /^(?:\d+ )?TSF:MSG:GWL OK/, d: "Link to GW ok" },
    { re: /^(?:\d+ )?TSF:MSG:FWD BC MSG/, d: "Controlled broadcast message forwarding" },
    { re: /^(?:\d+ )?TSF:MSG:REL MSG/, d: "Relay message" },
    { re: /^(?:\d+ )?TSF:MSG:REL PxNG,HP=(\d+)/, d: "Relay PING/PONG message, increment hop counter to <b>$1</b>" },
    { re: /^(?:\d+ )?!TSF:MSG:LEN,(\d+)!=(\d+)/, d: "Invalid message length, <b>$1</b> (actual) != <b>$2</b> (expected)" },
    { re: /^(?:\d+ )?!TSF:MSG:PVER,(\d+)!=(\d+)/, d: "Message protocol version mismatch, <b>$1</b> (actual) != <b>$2</b> (expected)" },
    { re: /^(?:\d+ )?!TSF:MSG:SIGN VERIFY FAIL/, d: "Signing verification failed" },
    { re: /^(?:\d+ )?!TSF:MSG:REL MSG,NORP/, d: "Node received a message for relaying, but node is not a repeater, message skipped" },
    { re: /^(?:\d+ )?!TSF:MSG:SIGN FAIL/, d: "Signing message failed" },
    { re: /^(?:\d+ )?!TSF:MSG:GWL FAIL/, d: "GW uplink failed" },
    { re: /^(?:\d+ )?TSF:SAN:OK/, d: "Sanity check passed" },
    { re: /^(?:\d+ )?!TSF:SAN:FAIL/, d: "Sanity check failed, attempt to re-initialize radio" },
    { re: /^(?:\d+ )?TSF:CRT:OK/, d: "Clearing routing table successful" },
    { re: /^(?:\d+ )?TSF:LRT:OK/, d: "Loading routing table successful" },
    { re: /^(?:\d+ )?TSF:SRT:OK/, d: "Saving routing table successful" },
    { re: /^(?:\d+ )?!TSF:RTE:FPAR ACTIVE/, d: "Finding parent active, message not sent" },
    { re: /^(?:\d+ )?!TSF:RTE:DST (\d+) UNKNOWN/, d: "Routing for destination <b>$1</b> unknown, sending message to parent" },
    { re: /^(?:\d+ )?!TSF:SND:TNR/, d: "Transport not ready, message cannot be sent" },
    { re: /^(?:\d+ )?TSF:MSG:READ,(\d+)-(\d+)-(\d+),s=(\d+),c=(\d+),t=(\d+),pt=(\d+),l=(\d+),sg=(\d+):(.*)/, d: "<u><b>Received Message</b></u><br><b>Sender</b>: $1<br><b>Last Node</b>: $2<br><b>Destination</b>: $3<br><b>Sensor Id</b>: $4<br><b>Command</b>: {command:$5}<br><b>Message Type</b>: {type:$5:$6}<br><b>Payload Type</b>: {pt:$7}<br><b>Payload Length</b>: $8<br><b>Signing</b>: $9<br><b>Payload</b>: $10" },
    { re: /^(?:\d+ )?TSF:MSG:SEND,(\d+)-(\d+)-(\d+)-(\d+),s=(\d+),c=(\d+),t=(\d+),pt=(\d+),l=(\d+),sg=(\d+),ft=(\d+),st=(\w+):(.*)/, d: "<u><b>Sent Message</b></u><br><b>Sender</b>: $1<br><b>Last Node</b>: $2<br><b>Next Node</b>: $3<br><b>Destination</b>: $4<br><b>Sensor Id</b>: $5<br><b>Command</b>: {command:$6}<br><b>Message Type</b>:{type:$6:$7}<br><b>Payload Type</b>: {pt:$8}<br><b>Payload Length</b>: $9<br><b>Signing</b>: $10<br><b>Failed uplink counter</b>: $11<br><b>Status</b>: $12 (OK=success, NACK=no radio ACK received)<br><b>Payload</b>: $13" },
    { re: /^(?:\d+ )?!TSF:MSG:SEND,(\d+)-(\d+)-(\d+)-(\d+),s=(\d+),c=(\d+),t=(\d+),pt=(\d+),l=(\d+),sg=(\d+),ft=(\d+),st=(\w+):(.*)/, d: "<u><b style='color:red'>Sent Message</b></u><br><b>Sender</b>: $1<br><b>Last Node</b>: $2<br><b>Next Node</b>: $3<br><b>Destination</b>: $4<br><b>Sensor Id</b>: $5<br><b>Command</b>: {command:$6}<br><b>Message Type</b>:{type:$6:$7}<br><b>Payload Type</b>: {pt:$8}<br><b>Payload Length</b>: $9<br><b>Signing</b>: $10<br><b>Failed uplink counter</b>: $11<br><b>Status</b>: $12 (OK=success, NACK=no radio ACK received)<br><b>Payload</b>: $13" },
    new Vue({
       el: "#parser",
       data: function() {
          return {
             source: "",
             parsed: []
       methods: {
           selector: function(cmd) {
                  switch (cmd) {
                     case "0": 
                        return "presentation";
                     case "1":
                     case "2":  
                        return "subtype";
                     case "3":  
                        return "internal";
           match: function(msg) {
                var self = this;
                for (var i=0, len=match.length;i<len; i++) {
                     var r = match[i];
                     if (r.re.test(msg)) {
                          msg = msg.replace(r.re, r.d);
                          msg = msg.replace(/{command:(\d+)}/g, function(match, m1) { return types.command[m1] });
                          msg = msg.replace(/{pt:(\d+)}/g, function(match, m1) { return types.payloadtype[m1] });
                          return msg.replace(/{type:(\d+):(\d+)}/g, function(match, cmd, type) { 
    return types[self.selector(cmd)][type] 
           parse: function() {
              var self = this;
              var rows = this.source.split("\n");
              this.parsed = _.map(rows, function(r) {
                  var p = r.split(";");
                  if (p.length !== 6) {
                      var desc = self.match(r);
                      return ["","","","",desc?"":"Unknown", r,  desc];
                 var sel = self.selector(p[2]);
                  var desc = "";
                  if (p[2] == "3" && p[4] == "9") {
                         desc = self.match(p[5]);
                  return  [

  • Brilliant, THANKS!

Log in to reply

Suggested Topics

  • 3
  • 2
  • 4
  • 3
  • 4
  • 3
  • 3
  • 5