{ "name": "📊 Monitoramento Sistema | Alertas Proativos", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "*/5 * * * *" } ] } }, "id": "cron-monitoring", "name": "Verificar a Cada 5min", "type": "n8n-nodes-base.cron", "typeVersion": 1, "position": [240, 300] }, { "parameters": { "jsCode": "// Lista de serviços para monitorar\nconst services = [\n {\n name: 'BookStack Docs',\n url: 'https://docs.memudecore.com.br',\n type: 'web',\n critical: true,\n timeout: 10000,\n expected_status: 200,\n check_content: 'Documentacão' // Palavra que deve aparecer na página\n },\n {\n name: 'Krayin CRM',\n url: 'https://crm.memudecore.com.br',\n type: 'web',\n critical: true,\n timeout: 15000,\n expected_status: 200,\n check_content: 'Login'\n },\n {\n name: 'N8N Automation',\n url: 'http://n8n.memudecore.com.br',\n type: 'web',\n critical: true,\n timeout: 10000,\n expected_status: 200,\n check_content: 'n8n'\n },\n {\n name: 'Evolution API',\n url: 'https://evolution.memudecore.com.br/manager',\n type: 'web',\n critical: false,\n timeout: 10000,\n expected_status: 200,\n check_content: 'Evolution'\n },\n {\n name: 'Site Principal',\n url: 'https://memudecore.com.br',\n type: 'web',\n critical: false,\n timeout: 8000,\n expected_status: 200,\n check_content: 'MeMude'\n }\n];\n\n// Configurações de monitoramento\nconst config = {\n timestamp: new Date().toISOString(),\n check_id: `monitor_${Date.now()}`,\n total_services: services.length,\n critical_services: services.filter(s => s.critical).length,\n timeout_global: 30000,\n retry_attempts: 2,\n alert_threshold: {\n consecutive_failures: 2,\n response_time_ms: 5000\n }\n};\n\nreturn {\n services: services,\n config: config\n};" }, "id": "prepare-monitoring", "name": "Preparar Lista Serviços", "type": "n8n-nodes-base.code", "typeVersion": 1, "position": [460, 300] }, { "parameters": { "batchSize": 1, "options": {} }, "id": "split-services", "name": "Dividir Serviços", "type": "n8n-nodes-base.splitInBatches", "typeVersion": 3, "position": [680, 300] }, { "parameters": { "jsCode": "// Obter informações do serviço atual\nconst allServices = $node[\"Preparar Lista Serviços\"].json.services;\nconst currentIndex = $node[\"Dividir Serviços\"].json.currentIndex;\nconst currentService = allServices[currentIndex];\n\n// Dados do serviço atual\nconst serviceCheck = {\n service: currentService,\n check_start: Date.now(),\n check_timestamp: new Date().toISOString(),\n attempt: 1,\n max_attempts: $node[\"Preparar Lista Serviços\"].json.config.retry_attempts\n};\n\nreturn serviceCheck;" }, "id": "get-current-service", "name": "Obter Serviço Atual", "type": "n8n-nodes-base.code", "typeVersion": 1, "position": [900, 300] }, { "parameters": { "method": "GET", "url": "={{$node[\"Obter Serviço Atual\"].json[\"service\"][\"url\"]}}", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "User-Agent", "value": "MeMude-Monitor/1.0 (Health Check)" }, { "name": "Accept", "value": "text/html,application/json" } ] }, "options": { "timeout": "={{$node[\"Obter Serviço Atual\"].json[\"service\"][\"timeout\"]}}" } }, "id": "check-service", "name": "Testar Serviço", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [1120, 300], "continueOnFail": true }, { "parameters": { "jsCode": "// Processar resultado da verificação\nconst serviceData = $node[\"Obter Serviço Atual\"].json;\nconst checkResult = $node[\"Testar Serviço\"].json;\nconst checkError = $node[\"Testar Serviço\"].json.error;\n\n// Calcular tempo de resposta\nconst responseTime = Date.now() - serviceData.check_start;\n\n// Determinar status do serviço\nlet isHealthy = false;\nlet statusMessage = 'OFFLINE';\nlet statusDetails = '';\n\nif (!checkError && checkResult) {\n const statusCode = checkResult.status || checkResult.statusCode || 0;\n const responseBody = checkResult.body || checkResult.data || '';\n \n // Verificar código HTTP\n const expectedStatus = serviceData.service.expected_status;\n const statusCodeOk = statusCode === expectedStatus;\n \n // Verificar conteúdo esperado\n const expectedContent = serviceData.service.check_content;\n const contentOk = expectedContent ? \n responseBody.toString().toLowerCase().includes(expectedContent.toLowerCase()) : true;\n \n // Verificar tempo de resposta\n const responseTimeOk = responseTime < 10000; // Máximo 10 segundos\n \n if (statusCodeOk && contentOk && responseTimeOk) {\n isHealthy = true;\n statusMessage = 'ONLINE';\n statusDetails = `HTTP ${statusCode} - ${responseTime}ms`;\n } else {\n statusMessage = 'DEGRADED';\n statusDetails = `HTTP ${statusCode} - ${responseTime}ms`;\n if (!statusCodeOk) statusDetails += ` (Expected ${expectedStatus})`;\n if (!contentOk) statusDetails += ` (Content missing: ${expectedContent})`;\n if (!responseTimeOk) statusDetails += ` (Slow response)`;\n }\n} else {\n statusMessage = 'OFFLINE';\n statusDetails = checkError?.message || 'Connection failed';\n}\n\n// Resultado da verificação\nconst result = {\n service_name: serviceData.service.name,\n service_url: serviceData.service.url,\n service_type: serviceData.service.type,\n is_critical: serviceData.service.critical,\n is_healthy: isHealthy,\n status: statusMessage,\n details: statusDetails,\n response_time_ms: responseTime,\n timestamp: serviceData.check_timestamp,\n check_id: $node[\"Preparar Lista Serviços\"].json.config.check_id,\n \n // Emojis para notificação\n status_emoji: isHealthy ? '✅' : statusMessage === 'DEGRADED' ? '⚠️' : '❌',\n priority_emoji: serviceData.service.critical ? '🚨' : '📊',\n \n // Cores para Slack\n color: isHealthy ? '#28a745' : statusMessage === 'DEGRADED' ? '#ffc107' : '#dc3545'\n};\n\nreturn result;" }, "id": "process-check-result", "name": "Processar Resultado", "type": "n8n-nodes-base.code", "typeVersion": 1, "position": [1340, 300] }, { "parameters": { "conditions": { "boolean": [ { "value1": "={{$node[\"Processar Resultado\"].json[\"is_healthy\"]}}", "value2": false } ], "string": [ { "value1": "={{$node[\"Processar Resultado\"].json[\"is_critical\"]}}", "value2": true } ] }, "combineOperation": "any" }, "id": "needs-alert", "name": "Precisa Alertar?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [1560, 300] }, { "parameters": { "channel": "#tech-alerts", "text": "{{$node[\"Processar Resultado\"].json[\"status_emoji\"]}} {{$node[\"Processar Resultado\"].json[\"priority_emoji\"]}} **{{$node[\"Processar Resultado\"].json[\"status\"]}}** - {{$node[\"Processar Resultado\"].json[\"service_name\"]}}", "attachments": [ { "color": "{{$node[\"Processar Resultado\"].json[\"color\"]}}", "fields": [ { "title": "🔗 Serviço", "value": "<{{$node[\"Processar Resultado\"].json[\"service_url\"]}}|{{$node[\"Processar Resultado\"].json[\"service_name\"]}}>", "short": true }, { "title": "⏱️ Tempo Resposta", "value": "{{$node[\"Processar Resultado\"].json[\"response_time_ms\"]}}ms", "short": true }, { "title": "🎯 Criticidade", "value": "{{$node[\"Processar Resultado\"].json[\"is_critical\"] ? 'CRÍTICO' : 'Normal'}}", "short": true }, { "title": "📋 Detalhes", "value": "`{{$node[\"Processar Resultado\"].json[\"details\"]}}`", "short": false } ], "actions": [ { "type": "button", "text": "🔍 Verificar Serviço", "url": "{{$node[\"Processar Resultado\"].json[\"service_url\"]}}", "style": "{{$node[\"Processar Resultado\"].json[\"is_healthy\"] ? 'primary' : 'danger'}}" } ], "footer": "Sistema de Monitoramento MeMude Core", "ts": "{{Math.floor(Date.now() / 1000)}}" } ], "otherOptions": { "username": "Monitor Bot", "icon_emoji": ":satellite_antenna:" } }, "id": "send-alert", "name": "Enviar Alerta", "type": "n8n-nodes-base.slack", "typeVersion": 1, "position": [1780, 200], "credentials": { "slackApi": { "id": "slack-memude-workspace", "name": "Slack MeMude Workspace" } } }, { "parameters": { "conditions": { "boolean": [ { "value1": "={{$node[\"Dividir Serviços\"].json[\"isDone\"]}}", "value2": true } ] } }, "id": "check-if-done", "name": "Verificação Completa?", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [1780, 400] }, { "parameters": { "jsCode": "// Coletar todos os resultados de verificação\nconst allItems = $input.all();\nconst config = $node[\"Preparar Lista Serviços\"].json.config;\n\n// Processar estatísticas\nconst stats = {\n total_services: allItems.length,\n healthy_services: allItems.filter(item => item.json.is_healthy).length,\n unhealthy_services: allItems.filter(item => !item.json.is_healthy).length,\n critical_unhealthy: allItems.filter(item => !item.json.is_healthy && item.json.is_critical).length,\n avg_response_time: Math.round(allItems.reduce((sum, item) => sum + (item.json.response_time_ms || 0), 0) / allItems.length),\n check_timestamp: new Date().toLocaleString('pt-BR'),\n check_id: config.check_id\n};\n\n// Serviços com problema\nconst problematicServices = allItems\n .filter(item => !item.json.is_healthy)\n .map(item => ({\n name: item.json.service_name,\n status: item.json.status,\n details: item.json.details,\n is_critical: item.json.is_critical\n }));\n\n// Status geral do sistema\nconst systemStatus = {\n is_healthy: stats.critical_unhealthy === 0,\n status_text: stats.critical_unhealthy === 0 ? 'SISTEMA OPERACIONAL' : \n stats.critical_unhealthy === 1 ? 'PROBLEMA CRÍTICO' : 'MÚLTIPLOS PROBLEMAS',\n status_emoji: stats.critical_unhealthy === 0 ? '✅' : \n stats.critical_unhealthy === 1 ? '⚠️' : '🚨',\n color: stats.critical_unhealthy === 0 ? '#28a745' : \n stats.critical_unhealthy === 1 ? '#ffc107' : '#dc3545'\n};\n\nreturn {\n stats: stats,\n problematic_services: problematicServices,\n system_status: systemStatus,\n detailed_results: allItems.map(item => item.json)\n};" }, "id": "generate-summary", "name": "Gerar Resumo", "type": "n8n-nodes-base.code", "typeVersion": 1, "position": [2000, 500] }, { "parameters": { "conditions": { "number": [ { "value1": "={{$node[\"Gerar Resumo\"].json[\"stats\"][\"unhealthy_services\"]}}", "operation": "larger", "value2": 0 } ] } }, "id": "has-issues", "name": "Tem Problemas?", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [2220, 500] }, { "parameters": { "channel": "#tech-summary", "text": "{{$node[\"Gerar Resumo\"].json[\"system_status\"][\"status_emoji\"]}} **{{$node[\"Gerar Resumo\"].json[\"system_status\"][\"status_text\"]}}**", "attachments": [ { "color": "{{$node[\"Gerar Resumo\"].json[\"system_status\"][\"color\"]}}", "title": "📊 Relatório de Monitoramento", "fields": [ { "title": "✅ Serviços Online", "value": "{{$node[\"Gerar Resumo\"].json[\"stats\"][\"healthy_services\"]}}/{{$node[\"Gerar Resumo\"].json[\"stats\"][\"total_services\"]}}", "short": true }, { "title": "⏱️ Tempo Médio", "value": "{{$node[\"Gerar Resumo\"].json[\"stats\"][\"avg_response_time\"]}}ms", "short": true }, { "title": "🚨 Críticos Offline", "value": "{{$node[\"Gerar Resumo\"].json[\"stats\"][\"critical_unhealthy\"]}}", "short": true }, { "title": "📅 Verificação", "value": "{{$node[\"Gerar Resumo\"].json[\"stats\"][\"check_timestamp\"]}}", "short": true } ], "footer": "Monitoramento Automático MeMude Core", "ts": "{{Math.floor(Date.now() / 1000)}}" } ] }, "id": "send-summary", "name": "Enviar Resumo", "type": "n8n-nodes-base.slack", "typeVersion": 1, "position": [2440, 400], "credentials": { "slackApi": { "id": "slack-memude-workspace", "name": "Slack MeMude Workspace" } } } ], "connections": { "Verificar a Cada 5min": { "main": [ [ { "node": "Preparar Lista Serviços", "type": "main", "index": 0 } ] ] }, "Preparar Lista Serviços": { "main": [ [ { "node": "Dividir Serviços", "type": "main", "index": 0 } ] ] }, "Dividir Serviços": { "main": [ [ { "node": "Obter Serviço Atual", "type": "main", "index": 0 } ] ] }, "Obter Serviço Atual": { "main": [ [ { "node": "Testar Serviço", "type": "main", "index": 0 } ] ] }, "Testar Serviço": { "main": [ [ { "node": "Processar Resultado", "type": "main", "index": 0 } ] ] }, "Processar Resultado": { "main": [ [ { "node": "Precisa Alertar?", "type": "main", "index": 0 }, { "node": "Verificação Completa?", "type": "main", "index": 0 } ] ] }, "Precisa Alertar?": { "main": [ [ { "node": "Enviar Alerta", "type": "main", "index": 0 } ] ] }, "Verificação Completa?": { "main": [ [ { "node": "Gerar Resumo", "type": "main", "index": 0 } ] ] }, "Gerar Resumo": { "main": [ [ { "node": "Tem Problemas?", "type": "main", "index": 0 } ] ] }, "Tem Problemas?": { "main": [ [ { "node": "Enviar Resumo", "type": "main", "index": 0 } ], [ { "node": "Enviar Resumo", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "timezone": "America/Sao_Paulo", "saveManualExecutions": true }, "createdAt": "2026-01-21T19:45:00.000Z", "updatedAt": "2026-01-21T19:45:00.000Z", "id": "monitoramento-sistema-completo", "tags": [ { "id": "monitoring", "name": "Monitoramento" }, { "id": "health-check", "name": "Health Check" }, { "id": "alerts", "name": "Alertas" } ] }