Skip to main content
Glama

OpenManager Vibe V4 MCP Server

by skyasu2
DataSourceAdapter.js11.2 kB
// 실제 프로덕션에서 바로 사용 가능한 어댑터 패턴 export class DataSourceAdapter { constructor(config) { this.config = config; this.dataSource = this.initializeDataSource(); } // 실제 환경에서는 이 부분만 변경 initializeDataSource() { switch (this.config.type) { case 'prometheus': return new PrometheusAdapter(this.config.prometheus); case 'grafana': return new GrafanaAdapter(this.config.grafana); case 'datadog': return new DatadogAdapter(this.config.datadog); case 'cloudwatch': return new CloudWatchAdapter(this.config.cloudwatch); case 'dummy': default: return new DummyDataAdapter(this.config.dummy); } } // 표준화된 인터페이스 (모든 데이터 소스에서 동일) async getServerMetrics(serverId, timeRange = '1h') { return await this.dataSource.fetchMetrics(serverId, timeRange); } async getServerList() { return await this.dataSource.fetchServerList(); } async getAlerts(severity = 'all') { return await this.dataSource.fetchAlerts(severity); } } // 더미 데이터 어댑터 (시연용) class DummyDataAdapter { constructor(config) { this.scenarios = config?.scenarios || this.getDefaultScenarios(); this.simulationSpeed = config?.simulationSpeed || 1; } async fetchMetrics(serverId, timeRange) { // 시연용 더미 데이터 생성 (실제로는 DB 쿼리) const baseMetrics = this.generateBaseMetrics(serverId); const realtimeNoise = this.addRealtimeVariation(baseMetrics); return { server_id: serverId, timestamp: new Date().toISOString(), metrics: realtimeNoise, data_source: 'simulation' }; } generateBaseMetrics(serverId) { // 실제 프로덕션 로직과 동일한 데이터 구조 return { cpu: { usage_percent: this.randomBetween(20, 80), cores_used: this.randomBetween(2, 8), load_average: this.randomBetween(0.5, 4.0) }, memory: { usage_percent: this.randomBetween(30, 85), used_gb: this.randomBetween(8, 28), swap_used_mb: this.randomBetween(0, 500) }, disk: { usage_percent: this.randomBetween(40, 90), read_iops: this.randomBetween(100, 2000), write_iops: this.randomBetween(50, 1500) }, network: { rx_bytes_sec: this.randomBetween(1000000, 100000000), tx_bytes_sec: this.randomBetween(500000, 50000000), latency_ms: this.randomBetween(1, 50), packet_loss_percent: this.randomBetween(0, 0.1) } }; } randomBetween(min, max) { return Math.random() * (max - min) + min; } addRealtimeVariation(baseMetrics) { // 실시간 변동성 추가 const metrics = JSON.parse(JSON.stringify(baseMetrics)); // CPU 변동 metrics.cpu.usage_percent += this.randomBetween(-5, 5); metrics.cpu.load_average += this.randomBetween(-0.3, 0.3); // 메모리 변동 metrics.memory.usage_percent += this.randomBetween(-3, 3); metrics.memory.used_gb += this.randomBetween(-1, 1); // 네트워크 변동 metrics.network.latency_ms += this.randomBetween(-5, 5); return metrics; } getDefaultScenarios() { return [ { id: "high_cpu", probability: 0.05, affectedMetrics: { "cpu.usage_percent": "increase_by_50%" } }, { id: "memory_leak", probability: 0.03, affectedMetrics: { "memory.usage_percent": "increase_linear_by_5%" } } ]; } async fetchServerList() { // 시연용 서버 목록 반환 return [ 'k8s-master-01', 'k8s-master-02', 'k8s-master-03', 'k8s-worker-01', 'k8s-worker-02', 'k8s-worker-03', 'k8s-etcd-01', 'k8s-etcd-02', 'web-server-01', 'web-server-02', 'web-server-03', 'db-server-01', 'redis-server-01', 'monitoring-01' ]; } async fetchAlerts(severity = 'all') { // 시연용 알림 생성 const alerts = []; const severityOptions = ['critical', 'warning', 'info']; const types = ['cpu', 'memory', 'disk', 'network', 'application']; // 5-10개의 랜덤 알림 생성 const count = Math.floor(Math.random() * 6) + 5; for (let i = 0; i < count; i++) { const alertSeverity = severityOptions[Math.floor(Math.random() * severityOptions.length)]; // 특정 심각도만 필터링 if (severity !== 'all' && alertSeverity !== severity) continue; const type = types[Math.floor(Math.random() * types.length)]; const serverId = await this.getRandomServer(); alerts.push({ id: `alert-${Date.now()}-${i}`, timestamp: new Date().toISOString(), server_id: serverId, severity: alertSeverity, type: `${type}_alert`, title: this.getAlertTitle(type, alertSeverity), description: this.getAlertDescription(type, alertSeverity), auto_remediation_available: Math.random() > 0.7 }); } return alerts; } async getRandomServer() { const servers = await this.fetchServerList(); return servers[Math.floor(Math.random() * servers.length)]; } getAlertTitle(type, severity) { const titles = { cpu: { critical: '심각한 CPU 부하', warning: 'CPU 사용량 경고', info: 'CPU 사용량 증가' }, memory: { critical: '메모리 부족 경고', warning: '높은 메모리 사용량', info: '메모리 사용량 증가' }, disk: { critical: '디스크 공간 부족', warning: '디스크 사용량 경고', info: '디스크 사용량 증가' }, network: { critical: '네트워크 연결 실패', warning: '네트워크 지연 발생', info: '네트워크 트래픽 증가' }, application: { critical: '애플리케이션 중단', warning: '애플리케이션 성능 저하', info: '애플리케이션 경고' } }; return titles[type][severity]; } getAlertDescription(type, severity) { const descriptions = { cpu: { critical: 'CPU 사용률이 95%를 초과하여 시스템 성능이 심각하게 저하되고 있습니다.', warning: 'CPU 사용률이 80%를 초과하여 시스템 성능이 저하될 수 있습니다.', info: 'CPU 사용률이 70%를 초과하였습니다.' }, memory: { critical: '메모리 사용률이 95%를 초과하여 시스템 안정성이 위협받고 있습니다.', warning: '메모리 사용률이 85%를 초과하여 성능 저하가 발생할 수 있습니다.', info: '메모리 사용량이 지속적으로 증가하고 있습니다.' }, disk: { critical: '디스크 공간이 95% 이상 사용되어 시스템 기능이 중단될 위험이 있습니다.', warning: '디스크 공간이 85% 이상 사용되었습니다. 불필요한 파일을 정리하세요.', info: '디스크 사용량이 증가 추세입니다.' }, network: { critical: '네트워크 연결이 끊겨 서비스 접근이 불가능합니다.', warning: '네트워크 지연이 500ms를 초과하여 사용자 경험이 저하되고 있습니다.', info: '네트워크 트래픽이 평소보다 50% 증가했습니다.' }, application: { critical: '애플리케이션이 응답하지 않아 서비스가 중단되었습니다.', warning: '애플리케이션 응답 시간이 2초를 초과하여 사용자 경험이 저하되고 있습니다.', info: '애플리케이션에서 비정상적인 패턴이 감지되었습니다.' } }; return descriptions[type][severity]; } } // 실제 프로덕션 어댑터 예시 (구현 준비만) class PrometheusAdapter { constructor(config) { this.baseUrl = config?.url; this.auth = config?.auth; } async fetchMetrics(serverId, timeRange) { // 실제 Prometheus 쿼리 로직 const queries = this.buildPrometheusQueries(serverId, timeRange); const results = await this.executeQueries(queries); return this.normalizePrometheusData(results); } buildPrometheusQueries(serverId, timeRange) { return { cpu: `cpu_usage{instance="${serverId}"}[${timeRange}]`, memory: `memory_usage{instance="${serverId}"}[${timeRange}]`, disk: `disk_usage{instance="${serverId}"}[${timeRange}]`, network: `network_io{instance="${serverId}"}[${timeRange}]` }; } async executeQueries(queries) { // 실제 프로덕션 환경에서 구현 console.log('Prometheus queries:', queries); return {}; } normalizePrometheusData(results) { // 표준 포맷으로 변환 return { server_id: '', timestamp: new Date().toISOString(), metrics: {}, data_source: 'prometheus' }; } async fetchServerList() { // 실제 프로덕션 환경에서 구현 return []; } async fetchAlerts(severity) { // 실제 프로덕션 환경에서 구현 return []; } } class GrafanaAdapter { constructor(config) { this.baseUrl = config?.url; this.apiKey = config?.apiKey; } async fetchMetrics(serverId, timeRange) { // 실제 Grafana API 호출 로직 console.log('Fetching metrics from Grafana for server:', serverId); return { server_id: serverId, timestamp: new Date().toISOString(), metrics: {}, data_source: 'grafana' }; } async fetchServerList() { // 실제 프로덕션 환경에서 구현 return []; } async fetchAlerts(severity) { // 실제 프로덕션 환경에서 구현 return []; } } class DatadogAdapter { constructor(config) { this.apiKey = config?.apiKey; this.appKey = config?.appKey; } async fetchMetrics(serverId, timeRange) { // 실제 Datadog API 호출 로직 console.log('Fetching metrics from Datadog for server:', serverId); return { server_id: serverId, timestamp: new Date().toISOString(), metrics: {}, data_source: 'datadog' }; } async fetchServerList() { // 실제 프로덕션 환경에서 구현 return []; } async fetchAlerts(severity) { // 실제 프로덕션 환경에서 구현 return []; } } class CloudWatchAdapter { constructor(config) { this.region = config?.region; this.credentials = config?.credentials; } async fetchMetrics(serverId, timeRange) { // 실제 AWS CloudWatch API 호출 로직 console.log('Fetching metrics from CloudWatch for server:', serverId); return { server_id: serverId, timestamp: new Date().toISOString(), metrics: {}, data_source: 'cloudwatch' }; } async fetchServerList() { // 실제 프로덕션 환경에서 구현 return []; } async fetchAlerts(severity) { // 실제 프로덕션 환경에서 구현 return []; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/skyasu2/openmanager-vibe-v4'

If you have feedback or need assistance with the MCP directory API, please join our Discord server