Initial commit

This commit is contained in:
Rob Vella 2020-07-30 18:36:08 -07:00
commit b61ef71cdb
9 changed files with 253 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
yarn-error.log

121
app.js Normal file
View File

@ -0,0 +1,121 @@
Vue.component('lt-startstop', {
template: '<button class="pure-button pure-button-primary" @click="toggleTail" :class="{ \'button-error\': buttonState }">' +
'{{ buttonState ? "Stop" : "Start" }} Tail</button>',
data() {
return {
buttonState: false
}
},
mounted() {
this.toggleTail();
},
methods: {
toggleTail() {
this.buttonState = !this.buttonState;
this.$emit('click', this.buttonState);
}
}
});
let App = new Vue({
el: '#app',
data() {
return {
enabled: false,
intervalTimer: null,
fetchEvery: 2000,
// uri = 'http://www3.winsystem.org/monitor/ajax-logtail.php'
uri: 'testdata.txt',
lastData: null,
logs: [],
nodeTypeLabels: {
0: 'Unknown',
1: 'Allstar',
2: 'IRLP'
},
nodeTypePrefixes: {
'rpt': 1,
'stn': 2
}
}
},
methods: {
toggleTail(state) {
this.enabled = state;
if (this.enabled) {
this.start();
} else {
this.stop();
}
},
start() {
this.intervalTimer = setInterval(() => {
this.fetchLog();
}, this.fetchEvery);
this.fetchLog();
},
stop() {
clearInterval(this.intervalTimer);
},
fetchLog() {
axios.get(this.uri).then(({data}) => {
this.lastData = data;
this.parseLogData();
});
},
parseLogData() {
this.logs = [];
let rows = this.lastData.split("\n").reverse();
rows.forEach((v) => {
let match = v.match(/([A-Za-z]+ [0-9]+ [0-9]+\:[0-9]+\:[0-9]+) (rpt|stn)([A-Za-z0-9]+) .*? (?:\[(?:via) ([0-9]+))?/);
if (!match) return;
let type = this.getNodeType(match[2]);
this.addEntry(
{
node: match[3],
via: match[4],
type: type,
typeLabel: this.getNodeTypeLabel(type),
desc: this.fetchNodeInfo(match[3], type),
dateTime: match[1],
}
);
});
},
getNodeType(type) {
return typeof this.nodeTypePrefixes[type] !== 'undefined' ? this.nodeTypePrefixes[type] : 0;
},
getNodeTypeLabel(type) {
return this.nodeTypeLabels[type];
},
fetchNodeInfo(node, type) {
return type === 1 ? this.fetchNodeInfoAllstar(node)
: (type === 2 ? this.fetchNodeInfoIRLP(node) : null);
},
fetchNodeInfoAllstar(node) {
let info;
return info;
},
fetchNodeInfoIRLP(node) {
let info;
return info;
},
addEntry(log) {
this.logs.push(log);
},
}
});

7
css/grids-responsive-min.css vendored Normal file

File diff suppressed because one or more lines are too long

11
css/pure-min.css vendored Normal file

File diff suppressed because one or more lines are too long

33
css/styles.css Normal file
View File

@ -0,0 +1,33 @@
.header {
padding: 1em;
}
.text-center {
align-items: center;
text-align: center;
}
.content-wrapper {
/* These styles are required for the "scroll-over" effect */
min-height: 12%;
z-index: 2;
background: white;
}
table.logs {
width: 100%;
}
/* We want to give the content area some more padding */
.content {
padding: 1em 1em 3em;
}
.button-error {
color: #fff;
background: rgb(202, 60, 60);
/* this is a maroon */
}
[v-cloak] {display: none}

52
index.html Normal file
View File

@ -0,0 +1,52 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Log Tail - WIN System</title>
<link rel="stylesheet" href="css/pure-min.css"
integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ" crossorigin="anonymous">
<link rel="stylesheet" href="css/grids-responsive-min.css">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div id="app">
<div class="header">
<div class="text-center">
<h1>WIN System Log Tail</h1>
<lt-startstop @click="toggleTail"/>
</div>
</div>
<div class="content-wrapper">
<div class="content">
<table class="pure-table logs">
<thead>
<tr>
<th>Node #</th>
<th>Via Node</th>
<th>Type</th>
<th>Description</th>
<th>Date/Time</th>
</tr>
</thead>
<tbody v-cloak>
<tr v-for="row in logs">
<td>{{ row.node }}</td>
<td>{{ row.via }}</td>
<td>{{ row.typeLabel }}</td>
<td>{{ fetchNodeInfo(row.node) }}</td>
<td>{{ row.dateTime }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.10.2/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="app.js" type="text/javascript"></script>
</body>
</html>

10
package.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "ajax-logtail",
"version": "1.0.0",
"main": "app.js",
"author": "Rob Vella",
"license": "MIT",
"dependencies": {
"moment": "^2.27.0"
}
}

10
testdata.txt Normal file
View File

@ -0,0 +1,10 @@
Jul 30 18:23:23 rpt29600 tx [via 2353]
Jul 30 18:33:11 rpt45073 tx [via 2353]
Jul 30 18:33:24 rpt48697 tx [via 2560]
Jul 30 18:33:33 stn3543 92 packets
Jul 30 18:33:43 rpt28462 tx [via 2560]
Jul 30 18:33:51 rpt28462 tx [via 2560]
Jul 30 18:33:57 rpt28462 tx [via 2560]

8
yarn.lock Normal file
View File

@ -0,0 +1,8 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
moment@^2.27.0:
version "2.27.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==