mirror of https://github.com/bra1n/townsquare.git
added more metrics
This commit is contained in:
parent
3a5a8bfc9a
commit
e2d7fa64f2
|
@ -1,5 +1,11 @@
|
||||||
# Release Notes
|
# Release Notes
|
||||||
|
|
||||||
|
## Version 2.0.3
|
||||||
|
|
||||||
|
- added a few more metrics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Version 2.0.2
|
## Version 2.0.2
|
||||||
- fix nomination history type not detecting travelers
|
- fix nomination history type not detecting travelers
|
||||||
- fix live session domain whitelist
|
- fix live session domain whitelist
|
||||||
|
|
|
@ -1266,6 +1266,11 @@
|
||||||
"file-uri-to-path": "1.0.0"
|
"file-uri-to-path": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bintrees": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ="
|
||||||
|
},
|
||||||
"bluebird": {
|
"bluebird": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
|
@ -6894,6 +6899,14 @@
|
||||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"prom-client": {
|
||||||
|
"version": "13.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.0.0.tgz",
|
||||||
|
"integrity": "sha512-M7ZNjIO6x+2R/vjSD13yjJPjpoZA8eEwH2Bp2Re0/PvzozD7azikv+SaBtZes4Q1ca/xHjZ4RSCuTag3YZLg1A==",
|
||||||
|
"requires": {
|
||||||
|
"tdigest": "^0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"promise-inflight": {
|
"promise-inflight": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
|
||||||
|
@ -8213,6 +8226,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
||||||
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
|
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
|
||||||
},
|
},
|
||||||
|
"tdigest": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz",
|
||||||
|
"integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=",
|
||||||
|
"requires": {
|
||||||
|
"bintrees": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"terser": {
|
"terser": {
|
||||||
"version": "4.8.0",
|
"version": "4.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
||||||
"@fortawesome/vue-fontawesome": "^0.1.10",
|
"@fortawesome/vue-fontawesome": "^0.1.10",
|
||||||
"@vue/cli-service": "^4.5.9",
|
"@vue/cli-service": "^4.5.9",
|
||||||
|
"prom-client": "^13.0.0",
|
||||||
"sass": "^1.30.0",
|
"sass": "^1.30.0",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const https = require("https");
|
const https = require("https");
|
||||||
const WebSocket = require("ws");
|
const WebSocket = require("ws");
|
||||||
|
const client = require("prom-client");
|
||||||
|
|
||||||
|
// Create a Registry which registers the metrics
|
||||||
|
const register = new client.Registry();
|
||||||
|
// Add a default label which is added to all metrics
|
||||||
|
register.setDefaultLabels({
|
||||||
|
app: "clocktower-online"
|
||||||
|
});
|
||||||
|
|
||||||
const PING_INTERVAL = 30000; // 30 seconds
|
const PING_INTERVAL = 30000; // 30 seconds
|
||||||
|
|
||||||
|
@ -29,6 +37,49 @@ function heartbeat() {
|
||||||
// map of channels currently in use
|
// map of channels currently in use
|
||||||
const channels = {};
|
const channels = {};
|
||||||
|
|
||||||
|
// metrics
|
||||||
|
const metrics = {
|
||||||
|
players_concurrent: new client.Gauge({
|
||||||
|
name: "players_concurrent",
|
||||||
|
help: "Concurrent Players",
|
||||||
|
collect() {
|
||||||
|
this.set(wss.clients.size);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
channels_concurrent: new client.Gauge({
|
||||||
|
name: "channels_concurrent",
|
||||||
|
help: "Concurrent Channels",
|
||||||
|
collect() {
|
||||||
|
this.set(Object.keys(channels).length);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
messages_incoming: new client.Counter({
|
||||||
|
name: "messages_incoming",
|
||||||
|
help: "Incoming messages"
|
||||||
|
}),
|
||||||
|
messages_outgoing: new client.Counter({
|
||||||
|
name: "messages_outgoing",
|
||||||
|
help: "Outgoing messages"
|
||||||
|
}),
|
||||||
|
connection_terminated_host: new client.Counter({
|
||||||
|
name: "connection_terminated_host",
|
||||||
|
help: "Terminated connection due to host already present"
|
||||||
|
}),
|
||||||
|
connection_terminated_spam: new client.Counter({
|
||||||
|
name: "connection_terminated_spam",
|
||||||
|
help: "Terminated connection due to message spam"
|
||||||
|
}),
|
||||||
|
connection_terminated_timeout: new client.Counter({
|
||||||
|
name: "connection_terminated_timeout",
|
||||||
|
help: "Terminated connection due to timeout"
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// register metrics
|
||||||
|
for (let metric in metrics) {
|
||||||
|
register.registerMetric(metrics[metric]);
|
||||||
|
}
|
||||||
|
|
||||||
// a new client connects
|
// a new client connects
|
||||||
wss.on("connection", function connection(ws, req) {
|
wss.on("connection", function connection(ws, req) {
|
||||||
// url pattern: clocktower.online/<channel>/<playerId|host>
|
// url pattern: clocktower.online/<channel>/<playerId|host>
|
||||||
|
@ -48,6 +99,7 @@ wss.on("connection", function connection(ws, req) {
|
||||||
) {
|
) {
|
||||||
console.log(ws.channel, "duplicate host");
|
console.log(ws.channel, "duplicate host");
|
||||||
ws.close(1000, `The channel "${ws.channel}" already has a host`);
|
ws.close(1000, `The channel "${ws.channel}" already has a host`);
|
||||||
|
metrics.connection_terminated_host.inc();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ws.isAlive = true;
|
ws.isAlive = true;
|
||||||
|
@ -71,6 +123,7 @@ wss.on("connection", function connection(ws, req) {
|
||||||
});
|
});
|
||||||
// handle message
|
// handle message
|
||||||
ws.on("message", function incoming(data) {
|
ws.on("message", function incoming(data) {
|
||||||
|
metrics.messages_incoming.inc();
|
||||||
// check rate limit (max 5msg/second)
|
// check rate limit (max 5msg/second)
|
||||||
ws.counter++;
|
ws.counter++;
|
||||||
if (ws.counter > (5 * PING_INTERVAL) / 1000) {
|
if (ws.counter > (5 * PING_INTERVAL) / 1000) {
|
||||||
|
@ -79,6 +132,7 @@ wss.on("connection", function connection(ws, req) {
|
||||||
1000,
|
1000,
|
||||||
"Your app seems to be malfunctioning, please clear your browser cache."
|
"Your app seems to be malfunctioning, please clear your browser cache."
|
||||||
);
|
);
|
||||||
|
metrics.connection_terminated_spam.inc();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const messageType = data
|
const messageType = data
|
||||||
|
@ -101,6 +155,7 @@ wss.on("connection", function connection(ws, req) {
|
||||||
dataToPlayer[client.playerId]
|
dataToPlayer[client.playerId]
|
||||||
) {
|
) {
|
||||||
client.send(JSON.stringify(dataToPlayer[client.playerId]));
|
client.send(JSON.stringify(dataToPlayer[client.playerId]));
|
||||||
|
metrics.messages_outgoing.inc();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -116,6 +171,7 @@ wss.on("connection", function connection(ws, req) {
|
||||||
} else {
|
} else {
|
||||||
client.send(data);
|
client.send(data);
|
||||||
}
|
}
|
||||||
|
metrics.messages_outgoing.inc();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -125,7 +181,10 @@ wss.on("connection", function connection(ws, req) {
|
||||||
// start ping interval timer
|
// start ping interval timer
|
||||||
const interval = setInterval(function ping() {
|
const interval = setInterval(function ping() {
|
||||||
wss.clients.forEach(function each(ws) {
|
wss.clients.forEach(function each(ws) {
|
||||||
if (ws.isAlive === false) return ws.terminate();
|
if (ws.isAlive === false) {
|
||||||
|
metrics.connection_terminated_timeout.inc();
|
||||||
|
return ws.terminate();
|
||||||
|
}
|
||||||
ws.isAlive = false;
|
ws.isAlive = false;
|
||||||
ws.pingStart = new Date().getTime();
|
ws.pingStart = new Date().getTime();
|
||||||
ws.ping(noop);
|
ws.ping(noop);
|
||||||
|
@ -142,16 +201,7 @@ if (process.env.NODE_ENV !== "development") {
|
||||||
console.log("server starting");
|
console.log("server starting");
|
||||||
server.listen(8080);
|
server.listen(8080);
|
||||||
server.on("request", (req, res) => {
|
server.on("request", (req, res) => {
|
||||||
res.writeHead(200);
|
res.setHeader("Content-Type", register.contentType);
|
||||||
res.end(
|
register.metrics().then(out => res.end(out));
|
||||||
`# HELP players_concurrent Concurrent players
|
|
||||||
# TYPE players_concurrent gauge
|
|
||||||
players_concurrent{app="clocktower-online"} ${wss.clients.size}
|
|
||||||
|
|
||||||
# HELP channels_concurrent Concurrent channels
|
|
||||||
# TYPE channels_concurrent gauge
|
|
||||||
channels_concurrent{app="clocktower-online"} ${Object.keys(channels).length}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
class LiveSession {
|
class LiveSession {
|
||||||
constructor(store) {
|
constructor(store) {
|
||||||
this._wss = "wss://live.clocktower.online:8080/";
|
this._wss = "wss://live.clocktower.online:8080/";
|
||||||
//this._wss = "wss://baumgart.biz:8080/"; //todo: delete this
|
//this._wss = "wss://localhost:8081/";
|
||||||
//this._wss = "ws://localhost:8081/";
|
|
||||||
this._socket = null;
|
this._socket = null;
|
||||||
this._isSpectator = true;
|
this._isSpectator = true;
|
||||||
this._gamestate = [];
|
this._gamestate = [];
|
||||||
|
|
Loading…
Reference in New Issue