feat(host-status-monitor): add service-registry self-registration

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 <noreply@anthropic.com>
This commit is contained in:
Quinn Ftw 2025-12-27 23:07:47 -08:00
parent f89c7bbe72
commit e19eef394a
3 changed files with 69 additions and 7 deletions

View file

@ -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"
}

View file

@ -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 {

View file

@ -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
}