resource usage
This commit is contained in:
@@ -29,19 +29,176 @@ stage.addChild(graphics);
|
|||||||
|
|
||||||
var clusters = []
|
var clusters = []
|
||||||
|
|
||||||
|
const FACTORS = {
|
||||||
|
'm': 1/1000,
|
||||||
|
'Ki': 1000,
|
||||||
|
'Mi': 1000 * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseResource(v) {
|
||||||
|
const match = v.match(/^(\d*)(\D*)$/)
|
||||||
|
const factor = FACTORS[match[2]] || 1
|
||||||
|
return parseInt(match[1]) * factor
|
||||||
|
}
|
||||||
|
|
||||||
|
class Tooltip extends PIXI.Graphics {
|
||||||
|
constructor () {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
draw () {
|
||||||
|
var tooltip = this
|
||||||
|
tooltip.lineStyle(2, 0xaaaaff, 1)
|
||||||
|
tooltip.beginFill(0x999999, 0.5)
|
||||||
|
tooltip.drawRect(0, 0, 200, 400)
|
||||||
|
tooltip.endFill()
|
||||||
|
var text = new PIXI.Text('', {fontSize: 12, fill: 0xffffff})
|
||||||
|
text.x = 2
|
||||||
|
text.y = 2
|
||||||
|
tooltip.addChild(text)
|
||||||
|
tooltip.text = text
|
||||||
|
tooltip.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Node extends PIXI.Graphics {
|
||||||
|
constructor (node, tooltip) {
|
||||||
|
super()
|
||||||
|
this.node = node
|
||||||
|
this.tooltip = tooltip
|
||||||
|
}
|
||||||
|
isMaster() {
|
||||||
|
return this.node.labels.master == 'true'
|
||||||
|
}
|
||||||
|
getResourceUsage() {
|
||||||
|
const resources = {}
|
||||||
|
for (let key of Object.keys(this.node.status.capacity)) {
|
||||||
|
resources[key] = {'capacity': parseResource(this.node.status.capacity[key]), 'used': 0}
|
||||||
|
}
|
||||||
|
for (let pod of this.node.pods) {
|
||||||
|
for (let container of pod.spec.containers) {
|
||||||
|
if (container.resources && container.resources.requests) {
|
||||||
|
for (let key of Object.keys(container.resources.requests)) {
|
||||||
|
resources[key].used += parseResource(container.resources.requests[key])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resources['pods'].used = this.node.pods.length
|
||||||
|
return resources
|
||||||
|
}
|
||||||
|
draw () {
|
||||||
|
var nodeBox = this
|
||||||
|
nodeBox.lineStyle(2, 0xaaaaff, 1);
|
||||||
|
nodeBox.beginFill(0x999999, 0.5)
|
||||||
|
nodeBox.drawRect(0, 0, 105, 100)
|
||||||
|
nodeBox.endFill()
|
||||||
|
nodeBox.lineStyle(2, 0xaaaaaa, 1);
|
||||||
|
nodeBox.interactive = true
|
||||||
|
nodeBox.on('mouseover', function() {
|
||||||
|
var s = this.node.name
|
||||||
|
for (let key of Object.keys(this.node.labels)) {
|
||||||
|
s += '\n' + key + ': ' + this.node.labels[key]
|
||||||
|
}
|
||||||
|
this.tooltip.text.text = s
|
||||||
|
this.tooltip.x = this.toGlobal(new PIXI.Point(0, 0)).x
|
||||||
|
this.tooltip.y = this.toGlobal(new PIXI.Point(0,0)).y
|
||||||
|
this.tooltip.visible = true
|
||||||
|
})
|
||||||
|
nodeBox.on('mouseout', function() {
|
||||||
|
this.tooltip.visible = false
|
||||||
|
})
|
||||||
|
const resources = this.getResourceUsage()
|
||||||
|
for (var i=0; i<resources.cpu.capacity; i++) {
|
||||||
|
nodeBox.drawRect(5, 90 - i * 5, 5, 5)
|
||||||
|
}
|
||||||
|
nodeBox.beginFill(0xaaffaa, 1)
|
||||||
|
nodeBox.drawRect(5, 95 - resources.cpu.used * 5, 5, resources.cpu.used * 5)
|
||||||
|
nodeBox.endFill()
|
||||||
|
|
||||||
|
const scale = 1000*1000*200
|
||||||
|
nodeBox.drawRect(14, 95 - resources.memory.capacity/scale, 5, resources.memory.capacity/scale)
|
||||||
|
nodeBox.lineStyle(2, 0xaaffaa, 1)
|
||||||
|
nodeBox.beginFill(0xaaffaa, 1)
|
||||||
|
nodeBox.drawRect(15, 95 - resources.memory.used/scale, 3, resources.memory.used/scale)
|
||||||
|
nodeBox.endFill()
|
||||||
|
var text = new PIXI.Text('', {fontSize: 10, fill: 0xffffff})
|
||||||
|
nodeBox.addChild(text)
|
||||||
|
|
||||||
|
var px = 24
|
||||||
|
var py = 5
|
||||||
|
for (let pod of this.node.pods) {
|
||||||
|
if (pod.metadata.namespace != 'kube-system') {
|
||||||
|
var podBox = new Pod(pod)
|
||||||
|
podBox.x = px
|
||||||
|
podBox.y = py
|
||||||
|
nodeBox.addChild(podBox.draw())
|
||||||
|
px += 13
|
||||||
|
if (px > 90) {
|
||||||
|
px = 24
|
||||||
|
py += 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
var px = 24
|
||||||
|
var py = 85
|
||||||
|
for (let pod of this.node.pods) {
|
||||||
|
if (pod.metadata.namespace == 'kube-system') {
|
||||||
|
var podBox = new Pod(pod)
|
||||||
|
podBox.x = px
|
||||||
|
podBox.y = py
|
||||||
|
nodeBox.addChild(podBox.draw())
|
||||||
|
px += 13
|
||||||
|
if (px > 90) {
|
||||||
|
px = 24
|
||||||
|
py -= 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nodeBox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pod extends PIXI.Graphics {
|
||||||
|
constructor (pod) {
|
||||||
|
super()
|
||||||
|
this.pod = pod
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
var podBox = this
|
||||||
|
podBox.lineStyle(2, 0xaaaaaa, 1);
|
||||||
|
var i = 0
|
||||||
|
var w = 10 / this.pod.spec.containers.length
|
||||||
|
for (let container of this.pod.spec.containers) {
|
||||||
|
podBox.drawRect(0 + i * w, 0, w, 10)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
var ready = true
|
||||||
|
for (let containerStatus of this.pod.status.containerStatuses) {
|
||||||
|
if (!containerStatus.ready) {
|
||||||
|
ready = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.pod.status.phase == 'Running' && ready) {
|
||||||
|
podBox.lineStyle(2, 0xaaffaa, 1);
|
||||||
|
} else if (this.pod.status.phase == 'Pending') {
|
||||||
|
podBox.lineStyle(2, 0xffffaa, 1);
|
||||||
|
} else {
|
||||||
|
podBox.lineStyle(2, 0xff9999, 1);
|
||||||
|
}
|
||||||
|
podBox.beginFill(0x999999, 0.5)
|
||||||
|
podBox.drawRect(0, 0, 10, 10)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tooltip = new Tooltip()
|
||||||
|
tooltip.draw()
|
||||||
|
|
||||||
function update(clusters) {
|
function update(clusters) {
|
||||||
var tooltip = new PIXI.Graphics()
|
graphics.removeChildren();
|
||||||
tooltip.lineStyle(2, 0xaaaaff, 1)
|
|
||||||
tooltip.beginFill(0x999999, 0.5)
|
|
||||||
tooltip.drawRect(0, 0, 200, 400)
|
|
||||||
tooltip.endFill()
|
|
||||||
var text = new PIXI.Text('', {fontSize: 12, fill: 0xffffff})
|
|
||||||
text.x = 2
|
|
||||||
text.y = 2
|
|
||||||
tooltip.addChild(text)
|
|
||||||
tooltip.text = text
|
|
||||||
tooltip.visible = false
|
|
||||||
graphics.clear();
|
|
||||||
graphics.lineStyle(2, 0xaaaaff, 1);
|
graphics.lineStyle(2, 0xaaaaff, 1);
|
||||||
var x = 50;
|
var x = 50;
|
||||||
for (let cluster of clusters) {
|
for (let cluster of clusters) {
|
||||||
@@ -49,82 +206,41 @@ function update(clusters) {
|
|||||||
clusterBox.x = x
|
clusterBox.x = x
|
||||||
clusterBox.y = 50
|
clusterBox.y = 50
|
||||||
graphics.addChild(clusterBox)
|
graphics.addChild(clusterBox)
|
||||||
var innerX = 10;
|
var rows = [10, 10]
|
||||||
for (let node of cluster.nodes) {
|
for (let node of cluster.nodes) {
|
||||||
var nodeBox = new PIXI.Graphics()
|
var nodeBox = new Node(node, tooltip)
|
||||||
nodeBox.x = innerX
|
nodeBox.draw()
|
||||||
nodeBox.y = 10
|
if (nodeBox.isMaster()) {
|
||||||
nodeBox.lineStyle(2, 0xaaaaff, 1);
|
nodeBox.x = rows[0]
|
||||||
nodeBox.beginFill(0x999999, 0.5)
|
rows[0] += nodeBox.width + 5
|
||||||
nodeBox.drawRect(0, 0, 100, 100)
|
nodeBox.y = 10
|
||||||
nodeBox.endFill()
|
} else {
|
||||||
nodeBox.lineStyle(2, 0x00ff00, 1);
|
nodeBox.x = rows[1]
|
||||||
for (var i=0; i<parseInt(node.status.capacity.cpu); i++) {
|
rows[1] += nodeBox.width + 5
|
||||||
nodeBox.drawRect(5, 5 + i * 8, 5, 5)
|
nodeBox.y = nodeBox.height + 15
|
||||||
}
|
}
|
||||||
nodeBox.interactive = true
|
|
||||||
nodeBox.hitArea = new PIXI.Rectangle(0, 0, 50, 50)
|
|
||||||
nodeBox.on('mouseover', function() {
|
|
||||||
var s = node.name
|
|
||||||
for (let key of Object.keys(node.labels)) {
|
|
||||||
s += '\n' + key + ': ' + node.labels[key]
|
|
||||||
}
|
|
||||||
tooltip.text.text = s
|
|
||||||
tooltip.x = this.toGlobal(new PIXI.Point(0, 0)).x
|
|
||||||
tooltip.y = this.toGlobal(new PIXI.Point(0,0)).y
|
|
||||||
tooltip.visible = true
|
|
||||||
})
|
|
||||||
nodeBox.on('mouseout', function() {
|
|
||||||
tooltip.visible = false
|
|
||||||
})
|
|
||||||
var mem = parseInt(node.status.capacity.memory.replace('Ki', ''))
|
|
||||||
nodeBox.drawRect(12, 5, 5, mem/(1024*512))
|
|
||||||
clusterBox.addChild(nodeBox)
|
clusterBox.addChild(nodeBox)
|
||||||
var text = new PIXI.Text('', {fontSize: 10, fill: 0xffffff})
|
|
||||||
nodeBox.addChild(text)
|
|
||||||
|
|
||||||
|
|
||||||
var px = 20
|
|
||||||
var py = 10
|
|
||||||
for (let pod of node.pods) {
|
|
||||||
var podBox = new PIXI.Graphics()
|
|
||||||
podBox.x = px
|
|
||||||
podBox.y = py
|
|
||||||
if (pod.status.phase == 'Running') {
|
|
||||||
podBox.lineStyle(2, 0xaaffaa, 1);
|
|
||||||
} else if (pod.status.phase == 'Pending') {
|
|
||||||
podBox.lineStyle(2, 0xffffaa, 1);
|
|
||||||
} else {
|
|
||||||
podBox.lineStyle(2, 0xff9999, 1);
|
|
||||||
}
|
|
||||||
podBox.beginFill(0x999999, 0.5)
|
|
||||||
podBox.drawRect(0, 0, 10, 10)
|
|
||||||
nodeBox.addChild(podBox)
|
|
||||||
px += 13
|
|
||||||
if (px > 50) {
|
|
||||||
px = 20
|
|
||||||
py += 13
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
innerX += nodeBox.width + 5
|
|
||||||
}
|
}
|
||||||
clusterBox.lineStyle(2, 0xaaaaff, 1);
|
clusterBox.lineStyle(2, 0xaaaaff, 1);
|
||||||
clusterBox.drawRect(0, 0, innerX, 200);
|
clusterBox.drawRect(0, 0, Math.max(rows[0], rows[1]), nodeBox.height * 2 + 20);
|
||||||
x += 250;
|
x += 250;
|
||||||
}
|
}
|
||||||
graphics.addChild(tooltip)
|
graphics.addChild(tooltip)
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch('/kubernetes-clusters')
|
function fetchData() {
|
||||||
.then(function(response) {
|
fetch('/kubernetes-clusters')
|
||||||
return response.json()
|
.then(function(response) {
|
||||||
})
|
return response.json()
|
||||||
.then(function(json) {
|
})
|
||||||
clusters = json.kubernetes_clusters;
|
.then(function(json) {
|
||||||
update(clusters)
|
clusters = json.kubernetes_clusters;
|
||||||
console.log(json);
|
update(clusters)
|
||||||
});
|
});
|
||||||
|
window.setTimeout(fetchData, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchData()
|
||||||
|
|
||||||
function state() {
|
function state() {
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user