Skip to content

Commit c1ff208

Browse files
committed
Add support for minecraft-java and minecraft-bedrock services. Prevent storing custom fields from pulses when custom fields are disabled in config.toml file.
1 parent 1e08d05 commit c1ff208

File tree

6 files changed

+138
-47
lines changed

6 files changed

+138
-47
lines changed

docs/pulsemonitor.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,36 @@ url = "redis://user:pass@redis.example.com:6379"
160160
timeout = 3
161161
```
162162

163+
### Minecraft Java
164+
165+
```toml
166+
[monitors.pulse.minecraft-java]
167+
host = "mc.example.com"
168+
port = 25565
169+
timeout = 3
170+
171+
# Optional: define a custom metric (custom1) to track the current online player count.
172+
[monitors.custom1]
173+
id = "players"
174+
name = "Player Count"
175+
unit = "players"
176+
```
177+
178+
### Minecraft Bedrock
179+
180+
```toml
181+
[monitors.pulse.minecraft-bedrock]
182+
host = "bedrock.example.com"
183+
port = 19132
184+
timeout = 3
185+
186+
# Optional: define a custom metric (custom1) to track the current online player count.
187+
[monitors.custom1]
188+
id = "players"
189+
name = "Player Count"
190+
unit = "players"
191+
```
192+
163193
## Pulse Interval Calculation
164194

165195
The server automatically calculates the pulse interval for PulseMonitor:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "uptimemonitor-server",
33
"module": "src/index.ts",
4-
"version": "0.2.19",
4+
"version": "0.2.20",
55
"type": "module",
66
"private": true,
77
"scripts": {

src/config.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,63 @@ function validatePulseConfig(pulse: unknown, context: string): PulseConfig | und
412412
}
413413
}
414414

415+
// Validate Minecraft Java config
416+
if (pulse["minecraft-java"] !== undefined) {
417+
configCount++;
418+
if (!isObject(pulse["minecraft-java"])) {
419+
errors.push(`${context}.minecraft-java must be an object`);
420+
} else {
421+
const minecraftJava = pulse["minecraft-java"];
422+
if (!isString(minecraftJava.host) || minecraftJava.host.trim().length === 0) {
423+
errors.push(`${context}.minecraft-java.host must be a non-empty string`);
424+
}
425+
if (minecraftJava.port !== undefined && (!isNumber(minecraftJava.port) || minecraftJava.port <= 0 || minecraftJava.port > 65535)) {
426+
errors.push(`${context}.minecraft-java.port must be a valid port number (1-65535)`);
427+
}
428+
if (minecraftJava.timeout !== undefined && (!isNumber(minecraftJava.timeout) || minecraftJava.timeout <= 0)) {
429+
errors.push(`${context}.minecraft-java.timeout must be a positive number`);
430+
}
431+
if (errors.length === 0) {
432+
result["minecraft-java"] = {
433+
host: minecraftJava.host as string,
434+
port: minecraftJava.port as number | undefined,
435+
timeout: minecraftJava.timeout as number | undefined,
436+
};
437+
}
438+
}
439+
}
440+
441+
// Validate Minecraft Bedrock config
442+
if (pulse["minecraft-bedrock"] !== undefined) {
443+
configCount++;
444+
if (!isObject(pulse["minecraft-bedrock"])) {
445+
errors.push(`${context}.minecraft-bedrock must be an object`);
446+
} else {
447+
const minecraftBedrock = pulse["minecraft-bedrock"];
448+
if (!isString(minecraftBedrock.host) || minecraftBedrock.host.trim().length === 0) {
449+
errors.push(`${context}.minecraft-bedrock.host must be a non-empty string`);
450+
}
451+
if (minecraftBedrock.port !== undefined && (!isNumber(minecraftBedrock.port) || minecraftBedrock.port <= 0 || minecraftBedrock.port > 65535)) {
452+
errors.push(`${context}.minecraft-bedrock.port must be a valid port number (1-65535)`);
453+
}
454+
if (minecraftBedrock.timeout !== undefined && (!isNumber(minecraftBedrock.timeout) || minecraftBedrock.timeout <= 0)) {
455+
errors.push(`${context}.minecraft-bedrock.timeout must be a positive number`);
456+
}
457+
if (errors.length === 0) {
458+
result["minecraft-bedrock"] = {
459+
host: minecraftBedrock.host as string,
460+
port: minecraftBedrock.port as number | undefined,
461+
timeout: minecraftBedrock.timeout as number | undefined,
462+
};
463+
}
464+
}
465+
}
466+
415467
// Check that at least one config type is defined
416468
if (configCount === 0) {
417-
errors.push(`${context} must have at least one monitoring type configured (http, ws, tcp, udp, icmp, smtp, imap, mysql, mssql, postgresql, or redis)`);
469+
errors.push(
470+
`${context} must have at least one monitoring type configured (http, ws, tcp, udp, icmp, smtp, imap, mysql, mssql, postgresql, redis, minecraft-java, minecraft-bedrock)`,
471+
);
418472
}
419473

420474
if (errors.length > 0) {

src/index.ts

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,7 @@ app.get(
161161
};
162162

163163
if (monitor.custom1) {
164-
const custom1Value = query.get(monitor.custom1.id) ?? query.get("custom1");
165-
if (custom1Value !== null) {
166-
const parsed = parseFloat(custom1Value);
167-
if (!isNaN(parsed)) {
168-
customMetrics.custom1 = parsed;
169-
}
170-
}
171-
} else {
172-
const custom1Value = query.get("custom1");
164+
const custom1Value = query.get("custom1") ?? query.get(monitor.custom1.id);
173165
if (custom1Value !== null) {
174166
const parsed = parseFloat(custom1Value);
175167
if (!isNaN(parsed)) {
@@ -179,15 +171,7 @@ app.get(
179171
}
180172

181173
if (monitor.custom2) {
182-
const custom2Value = query.get(monitor.custom2.id) ?? query.get("custom2");
183-
if (custom2Value !== null) {
184-
const parsed = parseFloat(custom2Value);
185-
if (!isNaN(parsed)) {
186-
customMetrics.custom2 = parsed;
187-
}
188-
}
189-
} else {
190-
const custom2Value = query.get("custom2");
174+
const custom2Value = query.get("custom2") ?? query.get(monitor.custom2.id);
191175
if (custom2Value !== null) {
192176
const parsed = parseFloat(custom2Value);
193177
if (!isNaN(parsed)) {
@@ -197,15 +181,7 @@ app.get(
197181
}
198182

199183
if (monitor.custom3) {
200-
const custom3Value = query.get(monitor.custom3.id) ?? query.get("custom3");
201-
if (custom3Value !== null) {
202-
const parsed = parseFloat(custom3Value);
203-
if (!isNaN(parsed)) {
204-
customMetrics.custom3 = parsed;
205-
}
206-
}
207-
} else {
208-
const custom3Value = query.get("custom3");
184+
const custom3Value = query.get("custom3") ?? query.get(monitor.custom3.id);
209185
if (custom3Value !== null) {
210186
const parsed = parseFloat(custom3Value);
211187
if (!isNaN(parsed)) {
@@ -586,50 +562,35 @@ app.websocket({
586562

587563
// Custom1
588564
if (monitor.custom1) {
589-
const custom1Value = data[monitor.custom1.id] ?? data.custom1;
565+
const custom1Value = data.custom1 ?? data[monitor.custom1.id];
590566
if (custom1Value !== undefined && custom1Value !== null) {
591567
const parsed = parseFloat(String(custom1Value));
592568
if (!isNaN(parsed)) {
593569
customMetrics.custom1 = parsed;
594570
}
595571
}
596-
} else if (data.custom1 !== undefined && data.custom1 !== null) {
597-
const parsed = parseFloat(String(data.custom1));
598-
if (!isNaN(parsed)) {
599-
customMetrics.custom1 = parsed;
600-
}
601572
}
602573

603574
// Custom2
604575
if (monitor.custom2) {
605-
const custom2Value = data[monitor.custom2.id] ?? data.custom2;
576+
const custom2Value = data.custom2 ?? data[monitor.custom2.id];
606577
if (custom2Value !== undefined && custom2Value !== null) {
607578
const parsed = parseFloat(String(custom2Value));
608579
if (!isNaN(parsed)) {
609580
customMetrics.custom2 = parsed;
610581
}
611582
}
612-
} else if (data.custom2 !== undefined && data.custom2 !== null) {
613-
const parsed = parseFloat(String(data.custom2));
614-
if (!isNaN(parsed)) {
615-
customMetrics.custom2 = parsed;
616-
}
617583
}
618584

619585
// Custom3
620586
if (monitor.custom3) {
621-
const custom3Value = data[monitor.custom3.id] ?? data.custom3;
587+
const custom3Value = data.custom3 ?? data[monitor.custom3.id];
622588
if (custom3Value !== undefined && custom3Value !== null) {
623589
const parsed = parseFloat(String(custom3Value));
624590
if (!isNaN(parsed)) {
625591
customMetrics.custom3 = parsed;
626592
}
627593
}
628-
} else if (data.custom3 !== undefined && data.custom3 !== null) {
629-
const parsed = parseFloat(String(data.custom3));
630-
if (!isNaN(parsed)) {
631-
customMetrics.custom3 = parsed;
632-
}
633594
}
634595

635596
// Parse timing parameters

src/pulsemonitor.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,24 @@ export function buildPulseMonitorConfig(monitor: Monitor): any {
118118
timeout: monitor.pulse.redis.timeout || 3,
119119
};
120120
}
121+
122+
// Minecraft Java monitoring
123+
if (monitor.pulse["minecraft-java"]) {
124+
pulseConfig["minecraft-java"] = {
125+
host: monitor.pulse["minecraft-java"].host,
126+
port: monitor.pulse["minecraft-java"].port,
127+
timeout: monitor.pulse["minecraft-java"].timeout,
128+
};
129+
}
130+
131+
// Minecraft Bedrock monitoring
132+
if (monitor.pulse["minecraft-bedrock"]) {
133+
pulseConfig["minecraft-bedrock"] = {
134+
host: monitor.pulse["minecraft-bedrock"].host,
135+
port: monitor.pulse["minecraft-bedrock"].port,
136+
timeout: monitor.pulse["minecraft-bedrock"].timeout,
137+
};
138+
}
121139
}
122140

123141
return pulseConfig;

src/types.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,30 @@ export interface PulseRedisConfig {
147147
timeout?: number;
148148
}
149149

150+
/**
151+
* Minecraft Java pulse monitoring configuration
152+
*/
153+
export interface MinecraftJavaConfig {
154+
/** Server address */
155+
host: string;
156+
/** Server port */
157+
port?: number;
158+
/** Connection timeout in seconds */
159+
timeout?: number;
160+
}
161+
162+
/**
163+
* Minecraft Bedrock pulse monitoring configuration
164+
*/
165+
export interface MinecraftBedrockConfig {
166+
/** Server address */
167+
host: string;
168+
/** Server port */
169+
port?: number;
170+
/** Connection timeout in seconds */
171+
timeout?: number;
172+
}
173+
150174
/**
151175
* Pulse monitoring configuration - defines what PulseMonitor should check
152176
* Only one type should be configured per monitor
@@ -174,6 +198,10 @@ export interface PulseConfig {
174198
postgresql?: PulsePostgresqlConfig;
175199
/** Redis monitoring */
176200
redis?: PulseRedisConfig;
201+
/** Minecraft Java monitoring */
202+
"minecraft-java"?: MinecraftJavaConfig;
203+
/** Minecraft Bedrock monitoring */
204+
"minecraft-bedrock"?: MinecraftBedrockConfig;
177205
}
178206

179207
/**

0 commit comments

Comments
 (0)