This commit is contained in:
parent
7369ad4d7b
commit
31176e4025
424
grafana-dashboard.json
Normal file
424
grafana-dashboard.json
Normal file
@ -0,0 +1,424 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": 7,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"panels": [],
|
||||
"title": "All Server Stats",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "locale"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 5,
|
||||
"w": 4,
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "10.2.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"query": "from(bucket: \"mc-tracker\")\r\n |> range(start: -1h)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"playerCount\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"playerCount\")\r\n |> last()\r\n |> map(fn: (r) => ({_value: r._value}))\r\n |> group(columns: [])\r\n |> sum()\r\n",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Total Players Online (now)",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisBorderShow": false,
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"insertNulls": false,
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"decimals": 0,
|
||||
"displayName": "${__field.labels.name}",
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "locale"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 16,
|
||||
"x": 4,
|
||||
"y": 1
|
||||
},
|
||||
"id": 1,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": ["min", "max", "mean"],
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true,
|
||||
"sortBy": "Mean",
|
||||
"sortDesc": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"query": "from(bucket: \"mc-tracker\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"playerCount\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"playerCount\")\r\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\r\n |> yield(name: \"mean\")",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Player Counts",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 4,
|
||||
"x": 20,
|
||||
"y": 1
|
||||
},
|
||||
"id": 17,
|
||||
"options": {
|
||||
"code": {
|
||||
"language": "plaintext",
|
||||
"showLineNumbers": false,
|
||||
"showMiniMap": false
|
||||
},
|
||||
"content": "Tracking historical data for Minecraft servers, this was inspired by [Minetrack](https://github.com/Cryptkeeper/Minetrack). <br/>\nPlease contact me on Discord if there is any issues: `fascinated7`.\n\nWant to add a server? Open a PR [here](https://git.fascinated.cc/Fascinated/mc-tracker/pulls)",
|
||||
"mode": "markdown"
|
||||
},
|
||||
"pluginVersion": "10.2.0",
|
||||
"title": "Information",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "locale"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 5,
|
||||
"w": 4,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "10.2.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"query": "from(bucket: \"mc-tracker\")\r\n |> range(start: -1mo)\r\n |> distinct(column: \"ip\")\r\n |> group()\r\n |> count()",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Total Tracked Servers",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 11
|
||||
},
|
||||
"id": 3,
|
||||
"panels": [],
|
||||
"title": "Per Server Stats",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisBorderShow": false,
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"insertNulls": false,
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"decimals": 0,
|
||||
"displayName": "Players Online",
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "locale"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 8,
|
||||
"x": 0,
|
||||
"y": 12
|
||||
},
|
||||
"id": 4,
|
||||
"maxPerRow": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": ["max", "min", "mean"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"repeat": "server",
|
||||
"repeatDirection": "h",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"query": "from(bucket: \"mc-tracker\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"playerCount\")\r\n |> filter(fn: (r) => r[\"_field\"] == \"playerCount\")\r\n |> filter(fn: (r) => r[\"name\"] == \"${server}\")\r\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\r\n |> yield(name: \"mean\")",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Player Count (${server})",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "30s",
|
||||
"schemaVersion": 38,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"selected": true,
|
||||
"text": ["All"],
|
||||
"value": ["$__all"]
|
||||
},
|
||||
"datasource": {
|
||||
"type": "influxdb",
|
||||
"uid": "face5ed9-19c5-419c-ac67-e80ed8945e49"
|
||||
},
|
||||
"definition": "from(bucket: \"mc-tracker\")\r\n |> range(start: -6h)\r\n |> group()\r\n |> distinct(column: \"name\")\r\n",
|
||||
"hide": 2,
|
||||
"includeAll": true,
|
||||
"multi": true,
|
||||
"name": "server",
|
||||
"options": [],
|
||||
"query": "from(bucket: \"mc-tracker\")\r\n |> range(start: -6h)\r\n |> group()\r\n |> distinct(column: \"name\")\r\n",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 0,
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30d",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Mc Tracker",
|
||||
"uid": "c4d923ad-b588-4953-a302-2af1514fddd0",
|
||||
"version": 26,
|
||||
"weekStart": ""
|
||||
}
|
13
src/index.ts
13
src/index.ts
@ -1,20 +1,9 @@
|
||||
import Influx from "./influx/influx";
|
||||
import Scanner from "./scanner/scanner";
|
||||
import ServerManager from "./server/serverManager";
|
||||
|
||||
/**
|
||||
* The server manager instance.
|
||||
*/
|
||||
export const serverManager = new ServerManager();
|
||||
|
||||
/**
|
||||
* The influx database instance.
|
||||
*/
|
||||
export const influx = new Influx();
|
||||
|
||||
(async () => {
|
||||
await serverManager.init();
|
||||
|
||||
// The scanner is responsible for scanning all servers
|
||||
new Scanner();
|
||||
})();
|
||||
new ServerManager();
|
||||
|
@ -1,27 +0,0 @@
|
||||
import cron from "node-cron";
|
||||
|
||||
import { serverManager } from "..";
|
||||
import Config from "../../data/config.json";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
export default class Scanner {
|
||||
constructor() {
|
||||
cron.schedule(Config.scanner.updateCron, () => {
|
||||
this.scanServers();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a server scan to ping all servers.
|
||||
*/
|
||||
private async scanServers(): Promise<void> {
|
||||
logger.info(`Scanning servers ${serverManager.getServers().length}`);
|
||||
|
||||
// ping all servers in parallel
|
||||
await Promise.all(
|
||||
serverManager.getServers().map((server) => server.pingServer())
|
||||
);
|
||||
|
||||
logger.info("Finished scanning servers");
|
||||
}
|
||||
}
|
@ -15,10 +15,6 @@ import { logger } from "../utils/logger";
|
||||
*/
|
||||
export type ServerType = "PC" | "PE";
|
||||
|
||||
export enum ServerStatus {
|
||||
OFFLINE = "Unable to reach host",
|
||||
}
|
||||
|
||||
type ServerOptions = {
|
||||
name: string;
|
||||
ip: string;
|
||||
@ -52,11 +48,6 @@ export default class Server {
|
||||
*/
|
||||
private type: ServerType;
|
||||
|
||||
/**
|
||||
* The favicon of the server.
|
||||
*/
|
||||
private favicon: string | undefined;
|
||||
|
||||
/**
|
||||
* The resolved server information from
|
||||
* DNS records for a PC server.
|
||||
@ -148,12 +139,11 @@ export default class Server {
|
||||
const serverPing = new javaPing.MinecraftServer(ip, port);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
serverPing.ping(Config.scanner.timeout, 765, (err, res) => {
|
||||
serverPing.ping(Config.pinger.timeout, 765, (err, res) => {
|
||||
if (err || res == undefined) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
this.favicon = res.favicon; // Set the favicon
|
||||
resolve({
|
||||
timestamp: Date.now(),
|
||||
ip: ip,
|
||||
@ -224,13 +214,4 @@ export default class Server {
|
||||
public getType(): ServerType {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the favicon of the server.
|
||||
*
|
||||
* @returns the favicon
|
||||
*/
|
||||
public getFavicon(): string | undefined {
|
||||
return this.favicon;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
import cron from "node-cron";
|
||||
import { logger } from "../utils/logger";
|
||||
import Server, { ServerType } from "./server";
|
||||
|
||||
import Config from "../../data/config.json";
|
||||
import Servers from "../../data/servers.json";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
export default class ServerManager {
|
||||
private servers: Server[] = [];
|
||||
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Loads the servers from the config file.
|
||||
*/
|
||||
async init() {
|
||||
logger.info("Loading servers");
|
||||
constructor() {
|
||||
logger.info("Loading servers...");
|
||||
for (const configServer of Servers) {
|
||||
const server = new Server({
|
||||
ip: configServer.ip,
|
||||
@ -21,7 +18,23 @@ export default class ServerManager {
|
||||
});
|
||||
this.servers.push(server);
|
||||
}
|
||||
logger.info(`Loaded ${this.servers.length} servers`);
|
||||
logger.info(`Loaded ${this.servers.length} servers!`);
|
||||
|
||||
cron.schedule(Config.pinger.pingCron, () => {
|
||||
this.pingServers();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping all servers to update their status.
|
||||
*/
|
||||
private async pingServers(): Promise<void> {
|
||||
logger.info(`Pinging servers ${this.servers.length}`);
|
||||
|
||||
// ping all servers in parallel
|
||||
await Promise.all(this.servers.map((server) => server.pingServer()));
|
||||
|
||||
logger.info("Finished pinging servers");
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user