summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUdo Walter2019-02-26 10:31:45 +0100
committerUdo Walter2019-02-26 10:31:45 +0100
commit4ef7abb2958085e3872ed5f7c433c5ddbd10d79a (patch)
treef0f13e53672cd409763e3c94d379f0c9701abffd
parentSupport serverCount field from dnbd3 RPC (diff)
downloaddnbd3-status-4ef7abb2958085e3872ed5f7c433c5ddbd10d79a.tar.gz
dnbd3-status-4ef7abb2958085e3872ed5f7c433c5ddbd10d79a.tar.xz
dnbd3-status-4ef7abb2958085e3872ed5f7c433c5ddbd10d79a.zip
table.html: (hopefully) fix crashes; keep offline servers greyed out for the timespan;
add ability to display ports (url query parameter 'ports'); fix display bug with ipv6 addresses;
-rw-r--r--static/table.html144
1 files changed, 91 insertions, 53 deletions
diff --git a/static/table.html b/static/table.html
index eb4ca4c..060c6c7 100644
--- a/static/table.html
+++ b/static/table.html
@@ -21,7 +21,7 @@
justify-content: center;
overflow-y: auto;
}
-
+
.server {
border-spacing: 2px 4px;
background-color: #eee;
@@ -30,6 +30,10 @@
max-width: 360px;
margin: 3px;
}
+
+ .server-offline {
+ filter: brightness(50%);
+ }
.first-row {
font-weight: bold;
@@ -56,7 +60,7 @@
<div id="app">
<div class="server-container">
- <table v-for="(server, index) in servers" class="server" :style="{ border: '4px solid ' + GRAPH_COLORS[index] }">
+ <table v-for="server in servers" class="server" :class="{ 'server-offline': server.offline }" :style="{ border: '4px solid ' + server.graphColor }">
<tbody>
<tr class="first-row"><td colspan="2" class="server-ip">{{ server.address }}</td></tr>
<tr><td>Uptime:</td><td class="expand">{{ formatSeconds(server.uptime) }}</td></tr>
@@ -77,7 +81,7 @@
<tr><td>Client count:</td><td>{{ server.clientCount }}</td></tr>
<tr><td>Server count:</td><td>{{ server.serverCount }}</td></tr>
<tr v-for="client in server.clients">
- <td class="client-label">{{ client.address.split( ":" )[0] }}</td>
+ <td class="client-label">{{ formatIpAddress(client.address) }}</td>
<td class="client-speed" :style="calcBackgroundStyle(peak ? client.peakUploadSpeed : client.avgUploadSpeed)">
<span>{{ formatBytes(peak ? client.peakUploadSpeed : client.avgUploadSpeed) }}/s</span>
</td>
@@ -88,7 +92,7 @@
<canvas ref="chart" :width="this.canvasWidth"></canvas>
</div>
-<script src="vue.min.js"></script>
+<script src="vue.js"></script>
<script src="smoothie.js"></script>
<script>
@@ -97,45 +101,83 @@ var app = new Vue({
el: '#app',
data: {
rawData: {},
- servers: [],
- logs: {},
+ serverMap: {},
timespan: 120,
peak: false,
+ ports: false,
canvasWidth: 0,
smoothie: null,
- graphLines: {},
- GRAPH_COLORS: ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"]
+ graphColors: ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"]
+ },
+ computed: {
+ servers () {
+ const servers = Object.values(this.serverMap)
+ servers.sort(this.compareObjectIps)
+ servers.forEach(server => {
+ if (this.rawData.timestamp - server.timestamp > 6000) server.offline = true
+ const clients = Object.values(server.clientMap)
+ if (this.peak) {
+ server.clients = clients.filter(client => client.peakUploadSpeed > 0)
+ server.clients.sort((a, b) => b.peakUploadSpeed - a.peakUploadSpeed)
+ } else {
+ server.clients = clients.filter(client => client.avgUploadSpeed > 0)
+ server.clients.sort((a, b) => b.avgUploadSpeed - a.avgUploadSpeed)
+ }
+ })
+ return servers
+ }
},
watch: {
rawData () {
if (this.rawData.servers) {
- const servers = this.rawData.servers.slice(0)
- servers.sort(this.compareObjectIps)
- const currentTime = new Date().getTime()
- servers.forEach((server, index) => {
- this.calcSpeed(server)
-
- // Update the graph
- if (!this.graphLines[server.address]) {
- Vue.set(this.graphLines, server.address, new TimeSeries({ logarithmicScale: true }))
- this.smoothie.addTimeSeries(this.graphLines[server.address], { lineWidth: 2, strokeStyle: this.GRAPH_COLORS[index] })
+ this.rawData.servers.forEach(serverData => {
+ // Update server
+ var server = this.serverMap[serverData.address]
+ if (server) {
+ Object.assign(server, serverData)
+ } else {
+ server = {
+ ...serverData,
+ log: [],
+ clientMap: {},
+ graphColor: this.graphColors.shift(),
+ graphLine: new TimeSeries({ logarithmicScale: true })
+ }
+ Vue.set(this.serverMap, serverData.address, server)
+ this.smoothie.addTimeSeries(server.graphLine, { lineWidth: 2, strokeStyle: server.graphColor })
}
- this.graphLines[server.address].append(currentTime, server.uploadSpeed)
+ server.log.push(serverData)
+ this.calcSpeed(server)
+ server.graphLine.append(server.timestamp, server.uploadSpeed)
// Update clients
- server.clients.forEach(client => {
- client.timestamp = server.timestamp
+ serverData.clients.forEach(clientData => {
+ clientData.timestamp = server.timestamp
+ var client = server.clientMap[clientData.address]
+ if (client) server.clientMap[clientData.address] = { ...client, ...clientData }
+ else Vue.set(server.clientMap, clientData.address, { ...clientData, log: [] })
+ client = server.clientMap[clientData.address]
+ client.log.push(clientData)
this.calcSpeed(client)
})
- if (this.peak) {
- server.clients = server.clients.filter(client => client.peakUploadSpeed > 0)
- server.clients.sort((a, b) => b.peakUploadSpeed - a.peakUploadSpeed)
- } else {
- server.clients = server.clients.filter(client => client.avgUploadSpeed > 0)
- server.clients.sort((a, b) => b.avgUploadSpeed - a.avgUploadSpeed)
- }
})
- this.servers = servers
+ }
+
+ // Remove outdated values
+ for (let serverIp in this.serverMap) {
+ const server = this.serverMap[serverIp]
+ server.log = server.log.filter(x => x.timestamp > this.rawData.timestamp - this.timespan * 1000)
+ if (server.log.length === 0) {
+ this.smoothie.removeTimeSeries(server.graphLine)
+ this.graphColors.unshift(server.graphColor)
+ Vue.delete(this.serverMap, serverIp)
+ } else {
+ for (let clientIp in server.clientMap) {
+ const client = server.clientMap[clientIp]
+ client.log = client.log.filter(x => x.timestamp > this.rawData.timestamp - this.timespan * 1000)
+ if (client.log.length === 0) Vue.delete(server.clientMap, clientIp)
+ }
+ }
}
}
},
@@ -146,33 +188,25 @@ var app = new Vue({
setTimeout(this.updateData, 2000)
},
calcSpeed (obj) {
- // Create a log for this ip if it doesn't exist already
- if(!this.logs[obj.address]) Vue.set(this.logs, obj.address, [])
- // Remove outdated values
- this.logs[obj.address] = this.logs[obj.address].filter(x => x.timestamp > this.rawData.timestamp - this.timespan * 1000)
- // Get the all the old values accumulated over the timespan
- const log = this.logs[obj.address]
- // Add new values to the log
- if (log.length === 0 || obj.timestamp > log[log.length - 1].timestamp) log.push(obj)
+ // Need a minimum of two values to calculate the speed
+ if (obj.log.length <= 1) return
- if (log.length > 1) {
- // Calculate current speeds
- var a = log[log.length - 2]
- const b = log[log.length - 1]
- var time = (b.timestamp - a.timestamp) / 1000
- obj.uploadSpeed = (b.bytesSent - a.bytesSent) / time
- obj.downloadSpeed = (b.bytesReceived - a.bytesReceived) / time
+ // Calculate current speeds
+ var a = obj.log[obj.log.length - 2]
+ const b = obj.log[obj.log.length - 1]
+ var time = (b.timestamp - a.timestamp) / 1000
+ obj.uploadSpeed = (b.bytesSent - a.bytesSent) / time
+ obj.downloadSpeed = (b.bytesReceived - a.bytesReceived) / time
- // Calculate peak speeds
- obj.peakUploadSpeed = Math.max(...log.map(x => x.uploadSpeed || 0))
- obj.peakDownloadSpeed = Math.max(...log.map(x => x.downloadSpeed || 0))
+ // Calculate peak speeds
+ obj.peakUploadSpeed = Math.max(...obj.log.map(x => x.uploadSpeed || 0))
+ obj.peakDownloadSpeed = Math.max(...obj.log.map(x => x.downloadSpeed || 0))
- // Calculate average speeds
- a = log[0]
- time = (b.timestamp - a.timestamp) / 1000
- obj.avgUploadSpeed = (b.bytesSent - a.bytesSent) / time
- obj.avgDownloadSpeed = (b.bytesReceived - a.bytesReceived) / time
- }
+ // Calculate average speeds
+ a = obj.log[0]
+ time = (b.timestamp - a.timestamp) / 1000
+ obj.avgUploadSpeed = (b.bytesSent - a.bytesSent) / time
+ obj.avgDownloadSpeed = (b.bytesReceived - a.bytesReceived) / time
},
formatBytes (bytes) {
if (bytes < 1024) return bytes.toFixed(2) + ' B'
@@ -206,12 +240,16 @@ var app = new Vue({
},
logScale (value) {
return Math.log(value/100000 + 1)
+ },
+ formatIpAddress (ip) {
+ return this.ports ? ip : ip.substring(0, ip.lastIndexOf(':'))
}
},
created () {
const urlParams = new URLSearchParams(window.location.search)
this.timespan = parseInt(urlParams.get('timespan')) || 120
this.peak = urlParams.get('peak') === 'true' || urlParams.get('peak') === ''
+ this.ports = urlParams.get('ports') === 'true' || urlParams.get('ports') === ''
this.updateData()
},
mounted () {