Skip to main content
Glama

Hi-GCloud

by su-record
format.tsβ€’7.92 kB
/** * Format utilities for hi-cloud output */ export interface LogEntry { timestamp: string; severity: string; message: string; resource?: string; labels?: Record<string, string>; } /** * Get severity emoji */ export function getSeverityEmoji(severity: string): string { switch (severity.toUpperCase()) { case 'EMERGENCY': case 'ALERT': case 'CRITICAL': case 'ERROR': return 'πŸ”΄'; case 'WARNING': return '🟑'; case 'NOTICE': case 'INFO': return 'πŸ”΅'; case 'DEBUG': return 'βšͺ'; default: return '⚫'; } } /** * Format log entries for display */ export function formatLogEntries(logs: LogEntry[]): string { if (logs.length === 0) { return 'λ‘œκ·Έκ°€ μ—†μŠ΅λ‹ˆλ‹€.'; } const lines = logs.map((log) => { const emoji = getSeverityEmoji(log.severity); const time = formatTimestamp(log.timestamp); const severity = log.severity.padEnd(8); const message = log.message.substring(0, 200); // Truncate long messages return `${emoji} [${time}] ${severity} ${message}`; }); return lines.join('\n'); } /** * Format timestamp for display */ export function formatTimestamp(timestamp: string): string { try { const date = new Date(timestamp); return date.toLocaleString('ko-KR', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }); } catch { return timestamp; } } /** * Format Cloud Run service status */ export function formatRunStatus(service: any): string { const lines: string[] = []; lines.push(`πŸ“¦ μ„œλΉ„μŠ€: ${service.name || 'Unknown'}`); lines.push(`🌐 URL: ${service.url || 'N/A'}`); lines.push(`πŸ“ 리전: ${service.region || 'N/A'}`); lines.push(`πŸ”„ 리비전: ${service.revision || 'N/A'}`); if (service.status) { const statusEmoji = service.status === 'Ready' ? 'βœ…' : '❌'; lines.push(`${statusEmoji} μƒνƒœ: ${service.status}`); } if (service.traffic) { lines.push(`\nπŸ“Š νŠΈλž˜ν”½ λΆ„λ°°:`); service.traffic.forEach((t: any) => { lines.push(` - ${t.revisionName}: ${t.percent}%`); }); } if (service.lastDeployed) { lines.push(`\nπŸ• λ§ˆμ§€λ§‰ 배포: ${formatTimestamp(service.lastDeployed)}`); } return lines.join('\n'); } /** * Format storage bucket/object list */ export function formatStorageList(items: any[], isBucketList: boolean): string { if (items.length === 0) { return isBucketList ? '버킷이 μ—†μŠ΅λ‹ˆλ‹€.' : '객체가 μ—†μŠ΅λ‹ˆλ‹€.'; } const lines: string[] = []; if (isBucketList) { lines.push('πŸ“¦ 버킷 λͺ©λ‘:'); items.forEach((bucket) => { lines.push(` πŸ“ ${bucket.name}`); if (bucket.location) { lines.push(` β”” μœ„μΉ˜: ${bucket.location}`); } }); } else { lines.push('πŸ“„ 객체 λͺ©λ‘:'); items.forEach((obj) => { const size = formatFileSize(obj.size); lines.push(` πŸ“„ ${obj.name} (${size})`); }); } return lines.join('\n'); } /** * Format file size */ export function formatFileSize(bytes: number): string { if (bytes === 0) return '0 B'; const units = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); const size = (bytes / Math.pow(1024, i)).toFixed(2); return `${size} ${units[i]}`; } /** * Format SQL query result */ export function formatSqlResult(rows: any[], columns: string[]): string { if (rows.length === 0) { return 'κ²°κ³Όκ°€ μ—†μŠ΅λ‹ˆλ‹€.'; } const lines: string[] = []; lines.push(`πŸ“Š κ²°κ³Ό: ${rows.length}ν–‰`); lines.push(''); // Simple table format lines.push('| ' + columns.join(' | ') + ' |'); lines.push('|' + columns.map(() => '---').join('|') + '|'); rows.slice(0, 100).forEach((row) => { const values = columns.map((col) => String(row[col] ?? 'NULL').substring(0, 50)); lines.push('| ' + values.join(' | ') + ' |'); }); if (rows.length > 100) { lines.push(`\n... μ™Έ ${rows.length - 100}개 ν–‰ μƒλž΅`); } return lines.join('\n'); } /** * Format error message for user */ export function formatError(error: any): string { if (error.type && error.suggestion) { return `❌ ${error.message}\n\nπŸ’‘ ${error.suggestion}`; } return `❌ 였λ₯˜: ${error.message || error}`; } /** * Create summary report for hi-ai integration */ export function createErrorReport(logs: LogEntry[]): { summary: string; errors: LogEntry[]; hasErrors: boolean; hiAiHint?: string; } { const errors = logs.filter((log) => ['ERROR', 'CRITICAL', 'ALERT', 'EMERGENCY'].includes(log.severity.toUpperCase()) ); let summary: string; let hiAiHint: string | undefined; if (errors.length > 0) { summary = `πŸ”΄ ${errors.length}개의 μ—λŸ¬κ°€ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€.`; // hi-ai 톡합 힌트 - LLM이 μžμ—°μŠ€λŸ½κ²Œ hi-ai 도ꡬλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ μœ λ„ hiAiHint = getHiAiIntegrationHint('error_analysis', { errorCount: errors.length, errorTypes: [...new Set(errors.map(e => e.severity))], }); } else { summary = 'βœ… μ—λŸ¬κ°€ μ—†μŠ΅λ‹ˆλ‹€.'; } return { summary, errors, hasErrors: errors.length > 0, hiAiHint, }; } /** * hi-ai 톡합 힌트 생성 * hi-ai MCPκ°€ μ„€μΉ˜λ˜μ–΄ μžˆμ„ 경우 LLM이 μžμ—°μŠ€λŸ½κ²Œ ν˜ΈμΆœν•  수 μžˆλ„λ‘ 힌트 제곡 */ export function getHiAiIntegrationHint( context: 'error_analysis' | 'deployment_failure' | 'performance_issue' | 'cost_alert', data?: Record<string, any> ): string { const hints: Record<string, string> = { error_analysis: ` πŸ’‘ hi-ai 연동 κ°€λŠ₯: μ—λŸ¬ 뢄석이 ν•„μš”ν•˜λ©΄ analyze_problem λ„κ΅¬λ‘œ 원인을 λΆ„μ„ν•˜κ³ , κ΄€λ ¨ μ½”λ“œλ₯Ό μ°Ύμ•„ μˆ˜μ • λ°©μ•ˆμ„ μ œμ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ©”λͺ¨λ¦¬μ— μ €μž₯ν•˜λ©΄ 같은 μ—λŸ¬ 재발 μ‹œ λΉ λ₯΄κ²Œ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.`, deployment_failure: ` πŸ’‘ hi-ai 연동 κ°€λŠ₯: 배포 μ‹€νŒ¨ 원인을 step_by_step_analysis둜 단계별 λΆ„μ„ν•˜κ³ , μ½”λ“œ μˆ˜μ •μ΄ ν•„μš”ν•˜λ©΄ suggest_improvements둜 κ°œμ„ μ•ˆμ„ 받을 수 μžˆμŠ΅λ‹ˆλ‹€.`, performance_issue: ` πŸ’‘ hi-ai 연동 κ°€λŠ₯: μ„±λŠ₯ 문제λ₯Ό analyze_complexity둜 λΆ„μ„ν•˜κ³ , 병λͺ© 지점을 μ°Ύμ•„ μ΅œμ ν™” λ°©μ•ˆμ„ μ œμ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€.`, cost_alert: ` πŸ’‘ hi-ai 연동 κ°€λŠ₯: λΉ„μš© 증가 원인을 break_down_problem으둜 λΆ„μ„ν•˜κ³ , λΉ„μš© 절감 λ°©μ•ˆμ„ μ²΄κ³„μ μœΌλ‘œ 정리할 수 μžˆμŠ΅λ‹ˆλ‹€.`, }; return hints[context] || ''; } /** * μ—λŸ¬ λ‘œκ·Έμ— λŒ€ν•œ 상세 뢄석 리포트 생성 (hi-ai μ—°λ™μš©) */ export function createDetailedErrorReport(logs: LogEntry[]): string { const report = createErrorReport(logs); if (!report.hasErrors) { return report.summary; } const lines: string[] = [report.summary, '']; // μ—λŸ¬ μœ ν˜•λ³„ κ·Έλ£Ήν™” const errorsByType = new Map<string, LogEntry[]>(); report.errors.forEach(error => { const type = error.severity.toUpperCase(); if (!errorsByType.has(type)) { errorsByType.set(type, []); } errorsByType.get(type)!.push(error); }); // μœ ν˜•λ³„ μš”μ•½ lines.push('πŸ“‹ μ—λŸ¬ μš”μ•½:'); errorsByType.forEach((errors, type) => { lines.push(` ${getSeverityEmoji(type)} ${type}: ${errors.length}건`); }); lines.push(''); // 졜근 μ—λŸ¬ 상세 (μ΅œλŒ€ 5개) lines.push('πŸ” 졜근 μ—λŸ¬ 상세:'); report.errors.slice(0, 5).forEach((error, idx) => { lines.push(` ${idx + 1}. [${formatTimestamp(error.timestamp)}] ${error.message.substring(0, 150)}`); if (error.resource) { lines.push(` β”” λ¦¬μ†ŒμŠ€: ${error.resource}`); } }); if (report.errors.length > 5) { lines.push(` ... μ™Έ ${report.errors.length - 5}건`); } // hi-ai 힌트 μΆ”κ°€ if (report.hiAiHint) { lines.push(''); lines.push(report.hiAiHint); } return lines.join('\n'); }

Latest Blog Posts

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/su-record/hi-gcloud'

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