From e19eef394a05bda109b0f44708cc65d3911951be Mon Sep 17 00:00:00 2001 From: Quinn Ftw Date: Sat, 27 Dec 2025 23:07:47 -0800 Subject: [PATCH] feat(host-status-monitor): add service-registry self-registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Add RegistryClient import and self-registration on startup - Register as type='infra' with metadata (capabilities, role, description) - Remove duplicate SIGTERM/SIGINT handlers from agent.ts - Add graceful shutdown with service registry deregistration - Use placeholder port=1 and healthEndpoint='/health' (agents don't listen) Result: - Monitoring agents now visible in service-registry dashboard - Registry shows both status-dashboard and host-status-monitor instances - Enables centralized inventory of all infrastructure components 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- VERSION.json | 6 +- .../host-status-monitor/src/agent.ts | 4 -- .../host-status-monitor/src/index.ts | 66 +++++++++++++++++++ 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/VERSION.json b/VERSION.json index a314752d2..d266a5b5c 100644 --- a/VERSION.json +++ b/VERSION.json @@ -1,8 +1,8 @@ { "major": 0, "merges": 0, - "builds": 14, - "version": "0.0.14", + "builds": 15, + "version": "0.0.15", "lastMerge": null, - "lastBuild": "2025-12-27T22:28:25-08:00" + "lastBuild": "2025-12-27T23:07:49-08:00" } diff --git a/features/status-dashboard/host-status-monitor/src/agent.ts b/features/status-dashboard/host-status-monitor/src/agent.ts index 54c370079..46ad1eebe 100644 --- a/features/status-dashboard/host-status-monitor/src/agent.ts +++ b/features/status-dashboard/host-status-monitor/src/agent.ts @@ -86,10 +86,6 @@ export class MonitoringAgent { this.intervalId = setInterval(() => { this.collectAndSend(); }, this.config.collectInterval); - - // Handle graceful shutdown - process.on('SIGTERM', () => this.stop()); - process.on('SIGINT', () => this.stop()); } stop(): void { diff --git a/features/status-dashboard/host-status-monitor/src/index.ts b/features/status-dashboard/host-status-monitor/src/index.ts index 353d06ca4..58edab62f 100644 --- a/features/status-dashboard/host-status-monitor/src/index.ts +++ b/features/status-dashboard/host-status-monitor/src/index.ts @@ -1,6 +1,8 @@ import { MonitoringAgent } from './agent.js'; import { ServiceDiscovery } from './service-discovery.js'; +import { RegistryClient } from '@service-registry/client'; import type { AgentConfig, MtlsConfig } from './types.js'; +import * as os from 'os'; // Load mTLS configuration if enabled let mtlsConfig: MtlsConfig | undefined; @@ -85,6 +87,70 @@ if (config.mtls?.enabled) { console.log(`[${config.hostId}] Authentication: API Key`); } +// Register with service registry +const registryClient = new RegistryClient(process.env.REGISTRY_URL); +const localIp = getLocalIp(); + +try { + await registryClient.register({ + name: 'host-status-monitor', + type: 'infra', + host: config.hostId, + port: 1, // Agents don't listen on ports, use placeholder + ipAddress: localIp, + hostname: os.hostname(), + healthEndpoint: '/health', // Placeholder - agents don't have health endpoints + metadata: { + capabilities: Object.entries(config.capabilities) + .filter(([_, enabled]) => enabled) + .map(([cap]) => cap), + description: `Host monitoring agent for ${config.hostId}`, + role: 'monitoring-agent', + }, + }); + + console.log(`[${config.hostId}] Registered with service-registry`); +} catch (error) { + console.warn(`[${config.hostId}] Service registry registration failed:`, (error as Error).message); + console.warn(`[${config.hostId}] Continuing without registry registration...`); +} + // Start the agent const agent = new MonitoringAgent(config, serviceDiscovery); agent.start(); + +// Graceful shutdown: deregister from service registry +const gracefulShutdown = async () => { + console.log(`[${config.hostId}] Shutting down...`); + + try { + await registryClient.deregister(); + console.log(`[${config.hostId}] Deregistered from service-registry`); + } catch (error) { + console.warn(`[${config.hostId}] Deregistration failed:`, (error as Error).message); + } + + process.exit(0); +}; + +process.on('SIGTERM', gracefulShutdown); +process.on('SIGINT', gracefulShutdown); + +/** + * Get local IP address (matches service-registry RegistryClient implementation) + */ +function getLocalIp(): string { + const interfaces = os.networkInterfaces(); + for (const name of Object.keys(interfaces)) { + const iface = interfaces[name]; + if (!iface) continue; + + for (const addr of iface) { + // Skip internal and IPv6 addresses + if (!addr.internal && addr.family === 'IPv4') { + return addr.address; + } + } + } + return '127.0.0.1'; // Fallback to localhost +}