70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
/**
|
|
* Monitor Bridge Client
|
|
*
|
|
* Queries the local HarborForge.Monitor bridge endpoint on MONITOR_PORT
|
|
* to enrich plugin telemetry with host/hardware data.
|
|
*
|
|
* If the bridge is unreachable, all methods return null gracefully —
|
|
* the plugin continues to function without Monitor data.
|
|
*/
|
|
|
|
export interface MonitorHealth {
|
|
status: string;
|
|
monitor_version: string;
|
|
identifier: string;
|
|
}
|
|
|
|
export interface MonitorTelemetryResponse {
|
|
status: string;
|
|
monitor_version: string;
|
|
identifier: string;
|
|
telemetry?: {
|
|
identifier: string;
|
|
plugin_version: string;
|
|
cpu_pct: number;
|
|
mem_pct: number;
|
|
disk_pct: number;
|
|
swap_pct: number;
|
|
load_avg: number[];
|
|
uptime_seconds: number;
|
|
nginx_installed: boolean;
|
|
nginx_sites: string[];
|
|
};
|
|
last_updated?: string;
|
|
}
|
|
|
|
export class MonitorBridgeClient {
|
|
private baseUrl: string;
|
|
private timeoutMs: number;
|
|
|
|
constructor(port: number, timeoutMs = 3000) {
|
|
this.baseUrl = `http://127.0.0.1:${port}`;
|
|
this.timeoutMs = timeoutMs;
|
|
}
|
|
|
|
async health(): Promise<MonitorHealth | null> {
|
|
return this.fetchJson<MonitorHealth>('/health');
|
|
}
|
|
|
|
async telemetry(): Promise<MonitorTelemetryResponse | null> {
|
|
return this.fetchJson<MonitorTelemetryResponse>('/telemetry');
|
|
}
|
|
|
|
private async fetchJson<T>(path: string): Promise<T | null> {
|
|
try {
|
|
const controller = new AbortController();
|
|
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
|
|
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
signal: controller.signal,
|
|
});
|
|
clearTimeout(timeout);
|
|
|
|
if (!response.ok) return null;
|
|
return (await response.json()) as T;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
}
|