AutomationFlowsAI & RAG › Analyze Logs and Correlate Incidents with Openai and Slack

Analyze Logs and Correlate Incidents with Openai and Slack

ByResilNext @rnair1996 on n8n.io

This workflow implements an AI-powered incident investigation and root cause analysis system that automatically analyzes operational signals when a system incident occurs.

Webhook trigger★★★★☆ complexityAI-powered26 nodesHTTP RequestOpenAI EmbeddingsIn-Memory Vector StoreOpenAI ChatOutput Parser StructuredAgentSlackDocument Default Data Loader
AI & RAG Trigger: Webhook Nodes: 26 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #14044 — we link there as the canonical source.

This workflow follows the Agent → Documentdefaultdataloader recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "6fcd8c22-a6d3-4ff4-880c-2ce287b4b044",
      "name": "Incident Trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -672,
        320
      ],
      "parameters": {
        "path": "incident-trigger",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "226c09f3-3d29-49d5-86ce-27dcb4f9a722",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -288,
        320
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "logsApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Logs API endpoint URL__>"
            },
            {
              "id": "id-2",
              "name": "metricsApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Metrics API endpoint URL__>"
            },
            {
              "id": "id-3",
              "name": "deploymentsApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Deployments API endpoint URL__>"
            },
            {
              "id": "id-4",
              "name": "featureFlagsApiUrl",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Feature flags API endpoint URL__>"
            },
            {
              "id": "id-5",
              "name": "timeWindowMinutes",
              "type": "number",
              "value": 30
            },
            {
              "id": "id-6",
              "name": "slackChannel",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Slack channel ID for incident tickets__>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "00e7e3ac-b665-44aa-b289-04a6b2b7860f",
      "name": "Fetch Logs",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        64,
        -176
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.logsApiUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "minutes",
              "value": "={{ $('Workflow Configuration').first().json.timeWindowMinutes }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "4c07f9ae-23e8-4499-8265-8eeb56468660",
      "name": "Fetch Metrics",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        160,
        304
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.metricsApiUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "minutes",
              "value": "={{ $('Workflow Configuration').first().json.timeWindowMinutes }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "d66bbe1a-a06b-4fcd-8e17-a275406f077d",
      "name": "Fetch Recent Deployments",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        160,
        464
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.deploymentsApiUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "minutes",
              "value": "={{ $('Workflow Configuration').first().json.timeWindowMinutes }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "190f0569-4b04-4967-a49e-5d88fbee73bd",
      "name": "Fetch Feature Flags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        160,
        624
      ],
      "parameters": {
        "url": "={{ $('Workflow Configuration').first().json.featureFlagsApiUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "37cf0bea-aa67-4e71-9120-eba1247be59a",
      "name": "Normalize and Denoise Logs",
      "type": "n8n-nodes-base.code",
      "position": [
        256,
        -176
      ],
      "parameters": {
        "jsCode": "// Normalize and Denoise Logs\n// This code processes raw logs to extract meaningful error information\n\nconst items = $input.all();\nconst normalizedLogs = [];\n\n// Define noise patterns to filter out\nconst noisePatterns = [\n  /debug/i,\n  /info/i,\n  /trace/i,\n  /verbose/i\n];\n\n// Process each log entry\nfor (const item of items) {\n  const logData = item.json;\n  \n  // Skip if log level is noise\n  const logLevel = logData.level || logData.severity || '';\n  const isNoise = noisePatterns.some(pattern => pattern.test(logLevel));\n  \n  if (isNoise) {\n    continue;\n  }\n  \n  // Extract key fields\n  const normalizedLog = {\n    timestamp: logData.timestamp || logData.time || logData['@timestamp'] || new Date().toISOString(),\n    level: (logLevel || 'unknown').toLowerCase(),\n    message: logData.message || logData.msg || logData.text || '',\n    sessionId: logData.sessionId || logData.session_id || logData.requestId || logData.request_id || logData.traceId || 'unknown',\n    service: logData.service || logData.serviceName || logData.app || 'unknown',\n    error: logData.error || logData.exception || logData.stack || null,\n    metadata: {\n      host: logData.host || logData.hostname,\n      environment: logData.environment || logData.env,\n      userId: logData.userId || logData.user_id,\n      endpoint: logData.endpoint || logData.path || logData.url\n    }\n  };\n  \n  // Only include logs with error or warning level\n  if (normalizedLog.level === 'error' || normalizedLog.level === 'warn' || normalizedLog.level === 'warning' || normalizedLog.level === 'fatal' || normalizedLog.level === 'critical') {\n    normalizedLogs.push({\n      json: normalizedLog\n    });\n  }\n}\n\n// Group logs by session/request ID\nconst groupedLogs = {};\nfor (const log of normalizedLogs) {\n  const sessionId = log.json.sessionId;\n  if (!groupedLogs[sessionId]) {\n    groupedLogs[sessionId] = [];\n  }\n  groupedLogs[sessionId].push(log.json);\n}\n\n// Create output with grouped logs\nconst output = [];\nfor (const [sessionId, logs] of Object.entries(groupedLogs)) {\n  // Sort logs by timestamp\n  logs.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));\n  \n  output.push({\n    json: {\n      sessionId: sessionId,\n      logCount: logs.length,\n      firstError: logs[0].timestamp,\n      lastError: logs[logs.length - 1].timestamp,\n      service: logs[0].service,\n      errors: logs.map(log => ({\n        timestamp: log.timestamp,\n        level: log.level,\n        message: log.message,\n        error: log.error,\n        metadata: log.metadata\n      }))\n    }\n  });\n}\n\nreturn output.length > 0 ? output : [{ json: { message: 'No error logs found after denoising' } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "fdb0579f-ae62-43e7-8e62-4c724377d84a",
      "name": "Merge Context Data",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        448,
        288
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "6b29f617-ee1c-4186-be4c-43ab69ed2c6a",
      "name": "OpenAI Embeddings",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        720,
        496
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "e80ba28a-1f81-4405-95b3-4748031f19d9",
      "name": "Cluster Log Messages",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
      "position": [
        704,
        288
      ],
      "parameters": {
        "mode": "insert",
        "memoryKey": {
          "__rl": true,
          "mode": "list",
          "value": "vector_store_key"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "13ed20a6-ed88-4971-9458-5e94beada3d0",
      "name": "Identify Failure Patterns",
      "type": "n8n-nodes-base.code",
      "position": [
        1152,
        288
      ],
      "parameters": {
        "jsCode": "// Analyze vector store clusters to identify dominant failure patterns\nconst items = $input.all();\n\n// Group items by cluster or similarity\nconst clusters = {};\nconst errorTypes = {};\n\nfor (const item of items) {\n  const data = item.json;\n  \n  // Extract error information\n  const errorType = data.error_type || data.level || data.severity || 'unknown';\n  const message = data.message || data.log || data.text || '';\n  const timestamp = data.timestamp || data.time || new Date().toISOString();\n  \n  // Count error types\n  if (!errorTypes[errorType]) {\n    errorTypes[errorType] = {\n      count: 0,\n      messages: [],\n      timestamps: []\n    };\n  }\n  errorTypes[errorType].count++;\n  errorTypes[errorType].messages.push(message);\n  errorTypes[errorType].timestamps.push(timestamp);\n  \n  // Group by cluster if available (from vector store)\n  const clusterId = data.cluster_id || data.group || 'default';\n  if (!clusters[clusterId]) {\n    clusters[clusterId] = {\n      id: clusterId,\n      size: 0,\n      errors: [],\n      errorTypes: {}\n    };\n  }\n  clusters[clusterId].size++;\n  clusters[clusterId].errors.push(data);\n  \n  if (!clusters[clusterId].errorTypes[errorType]) {\n    clusters[clusterId].errorTypes[errorType] = 0;\n  }\n  clusters[clusterId].errorTypes[errorType]++;\n}\n\n// Sort error types by frequency\nconst sortedErrorTypes = Object.entries(errorTypes)\n  .map(([type, data]) => ({\n    type,\n    count: data.count,\n    percentage: (data.count / items.length * 100).toFixed(2),\n    sample_messages: data.messages.slice(0, 5),\n    first_occurrence: data.timestamps.sort()[0],\n    last_occurrence: data.timestamps.sort()[data.timestamps.length - 1]\n  }))\n  .sort((a, b) => b.count - a.count);\n\n// Identify dominant patterns in each cluster\nconst clusterAnalysis = Object.values(clusters).map(cluster => {\n  const dominantError = Object.entries(cluster.errorTypes)\n    .sort((a, b) => b[1] - a[1])[0];\n  \n  return {\n    cluster_id: cluster.id,\n    size: cluster.size,\n    dominant_error_type: dominantError ? dominantError[0] : 'unknown',\n    dominant_error_count: dominantError ? dominantError[1] : 0,\n    error_diversity: Object.keys(cluster.errorTypes).length,\n    all_error_types: cluster.errorTypes\n  };\n}).sort((a, b) => b.size - a.size);\n\n// Calculate overall statistics\nconst totalErrors = items.length;\nconst uniqueErrorTypes = Object.keys(errorTypes).length;\nconst largestCluster = clusterAnalysis[0] || { size: 0 };\n\n// Return analysis results\nreturn [{\n  json: {\n    summary: {\n      total_errors: totalErrors,\n      unique_error_types: uniqueErrorTypes,\n      total_clusters: Object.keys(clusters).length,\n      largest_cluster_size: largestCluster.size\n    },\n    top_error_types: sortedErrorTypes.slice(0, 10),\n    cluster_analysis: clusterAnalysis,\n    failure_patterns: {\n      most_frequent_error: sortedErrorTypes[0]?.type || 'none',\n      most_frequent_count: sortedErrorTypes[0]?.count || 0,\n      error_concentration: sortedErrorTypes[0] ? \n        (sortedErrorTypes[0].count / totalErrors * 100).toFixed(2) + '%' : '0%'\n    },\n    raw_data: items.map(item => item.json)\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "9c860f13-1270-44cd-83ae-350ef54b49da",
      "name": "Time-Align Events",
      "type": "n8n-nodes-base.code",
      "position": [
        1360,
        288
      ],
      "parameters": {
        "jsCode": "// Time-align failure patterns with deployments, config changes, and traffic spikes\n// Correlate timestamps and identify causal relationships\n\nconst items = $input.all();\n\n// Extract and categorize events by type\nconst failurePatterns = [];\nconst deployments = [];\nconst configChanges = [];\nconst trafficSpikes = [];\n\nitems.forEach(item => {\n  const data = item.json;\n  \n  if (data.type === 'failure_pattern') {\n    failurePatterns.push(data);\n  } else if (data.type === 'deployment') {\n    deployments.push(data);\n  } else if (data.type === 'config_change') {\n    configChanges.push(data);\n  } else if (data.type === 'traffic_spike') {\n    trafficSpikes.push(data);\n  }\n});\n\n// Function to parse timestamps\nfunction parseTimestamp(ts) {\n  return new Date(ts).getTime();\n}\n\n// Function to find temporal correlations (within time window)\nfunction findCorrelations(failureEvent, events, windowMinutes = 30) {\n  const failureTime = parseTimestamp(failureEvent.timestamp);\n  const windowMs = windowMinutes * 60 * 1000;\n  \n  return events.filter(event => {\n    const eventTime = parseTimestamp(event.timestamp);\n    const timeDiff = failureTime - eventTime;\n    // Event should occur before or around the same time as failure\n    return timeDiff >= 0 && timeDiff <= windowMs;\n  }).map(event => ({\n    ...event,\n    timeDiffMinutes: Math.round((failureTime - parseTimestamp(event.timestamp)) / 60000),\n    correlationStrength: 1 - ((failureTime - parseTimestamp(event.timestamp)) / windowMs)\n  }));\n}\n\n// Correlate each failure pattern with potential causes\nconst correlatedEvents = failurePatterns.map(failure => {\n  const correlatedDeployments = findCorrelations(failure, deployments, 60);\n  const correlatedConfigChanges = findCorrelations(failure, configChanges, 30);\n  const correlatedTrafficSpikes = findCorrelations(failure, trafficSpikes, 15);\n  \n  // Calculate causal likelihood scores\n  const causalRelationships = [];\n  \n  correlatedDeployments.forEach(dep => {\n    causalRelationships.push({\n      type: 'deployment',\n      event: dep,\n      causalScore: dep.correlationStrength * 0.9, // Deployments are highly likely causes\n      reasoning: `Deployment occurred ${dep.timeDiffMinutes} minutes before failure`\n    });\n  });\n  \n  correlatedConfigChanges.forEach(config => {\n    causalRelationships.push({\n      type: 'config_change',\n      event: config,\n      causalScore: config.correlationStrength * 0.85,\n      reasoning: `Config change occurred ${config.timeDiffMinutes} minutes before failure`\n    });\n  });\n  \n  correlatedTrafficSpikes.forEach(spike => {\n    causalRelationships.push({\n      type: 'traffic_spike',\n      event: spike,\n      causalScore: spike.correlationStrength * 0.7,\n      reasoning: `Traffic spike occurred ${spike.timeDiffMinutes} minutes before failure`\n    });\n  });\n  \n  // Sort by causal score\n  causalRelationships.sort((a, b) => b.causalScore - a.causalScore);\n  \n  return {\n    json: {\n      failurePattern: failure,\n      correlatedEvents: {\n        deployments: correlatedDeployments,\n        configChanges: correlatedConfigChanges,\n        trafficSpikes: correlatedTrafficSpikes\n      },\n      causalRelationships: causalRelationships,\n      topLikelyCause: causalRelationships[0] || null,\n      timestamp: failure.timestamp\n    }\n  };\n});\n\nreturn correlatedEvents;"
      },
      "typeVersion": 2
    },
    {
      "id": "fd10f16d-5245-4e1c-9ee1-d69a929ca541",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1616,
        528
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "1fd14fad-204b-4a02-b6f7-e070b74e728e",
      "name": "Root Cause Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1920,
        496
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"rootCauses\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"object\",\n\t\t\t\t\"properties\": {\n\t\t\t\t\t\"hypothesis\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"confidence\": {\n\t\t\t\t\t\t\"type\": \"number\",\n\t\t\t\t\t\t\"minimum\": 0,\n\t\t\t\t\t\t\"maximum\": 100\n\t\t\t\t\t},\n\t\t\t\t\t\"evidence\": {\n\t\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"recommendedAction\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8c782c17-209c-4c83-9ec4-01ab32fd5caf",
      "name": "Root Cause Analysis Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1696,
        288
      ],
      "parameters": {
        "text": "=Analyze the following incident data and generate root cause hypotheses:\n\nFailure Patterns: {{ $json.failurePatterns }}\n\nTime-Aligned Events: {{ $json.correlatedEvents }}\n\nMetrics: {{ $json.metrics }}\n\nDeployments: {{ $json.deployments }}\n\nFeature Flags: {{ $json.featureFlags }}",
        "options": {
          "systemMessage": "You are an expert Site Reliability Engineer specializing in incident analysis and root cause determination.\n\nYour task is to:\n1. Analyze the provided log clusters, failure patterns, and contextual data\n2. Identify probable root causes based on evidence\n3. Assign confidence scores (0-100) to each hypothesis based on strength of evidence\n4. Provide specific evidence supporting each hypothesis\n5. Recommend concrete actions (rollback, config change, scaling, etc.)\n\nConsider:\n- Temporal correlation between failures and deployments/config changes\n- Traffic patterns and resource utilization\n- Error message patterns and frequency\n- Feature flag changes\n- Historical incident patterns\n\nReturn structured output with multiple hypotheses ranked by confidence."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "4ce733c6-4bfa-4c0a-9f9c-149965df3be7",
      "name": "Create Incident Ticket",
      "type": "n8n-nodes-base.slack",
      "position": [
        2224,
        288
      ],
      "parameters": {
        "text": "=\ud83d\udea8 *Incident Alert - Root Cause Analysis*\n\n*Incident ID:* {{ $('Incident Trigger').first().json.body.incidentId || 'N/A' }}\n*Timestamp:* {{ $now.format('yyyy-MM-dd HH:mm:ss') }}\n*Severity:* {{ $('Incident Trigger').first().json.body.severity || 'Unknown' }}\n\n---\n\n*Root Cause Hypotheses:*\n{{ $('Root Cause Analysis Agent').first().json.hypotheses ? $('Root Cause Analysis Agent').first().json.hypotheses.map((h, i) => `\n${i + 1}. *${h.cause}*\n   \u2022 Confidence: ${h.confidence}%\n   \u2022 Evidence: ${h.evidence}\n   \u2022 Impact: ${h.impact}`).join('\n') : 'No hypotheses generated' }}\n\n---\n\n*Recommended Actions:*\n{{ $('Root Cause Analysis Agent').first().json.recommendations ? $('Root Cause Analysis Agent').first().json.recommendations.map((r, i) => `${i + 1}. ${r}`).join('\n') : 'No recommendations available' }}\n\n---\n\n*Analysis Summary:*\n{{ $('Root Cause Analysis Agent').first().json.summary || 'Analysis in progress...' }}\n\n*Affected Services:* {{ $('Root Cause Analysis Agent').first().json.affectedServices ? $('Root Cause Analysis Agent').first().json.affectedServices.join(', ') : 'Unknown' }}\n*Correlation Score:* {{ $('Root Cause Analysis Agent').first().json.correlationScore || 'N/A' }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Workflow Configuration').first().json.slackChannel }}"
        },
        "otherOptions": {
          "includeLinkToWorkflow": true
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "a0342a8b-fa71-4094-a5f5-d13a08cd562c",
      "name": "Document Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        912,
        496
      ],
      "parameters": {
        "options": {},
        "jsonData": "={{ $json.errors }}",
        "jsonMode": "expressionData"
      },
      "typeVersion": 1.1
    },
    {
      "id": "d35db4d9-a6dd-419c-97bc-2b2abd3b83e8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 384,
        "content": "## Incident Trigger\n\nThis workflow starts when an incident alert is received through a webhook.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "896fa1a2-c1c0-4be8-8f98-0fac695ba6df",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 368,
        "content": "## Workflow Configuration\nDefines the API endpoints used to collect logs, metrics, deployments, and feature flag data. It also configures the analysis time window and Slack channel used for incident notifications."
      },
      "typeVersion": 1
    },
    {
      "id": "426b5dca-2a2f-44b8-89ce-da1ad13e5a28",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 704,
        "content": "## Incident Context Collection\n\nThe workflow gathers operational context from multiple sources including logs, metrics, recent deployments, and feature flag changes."
      },
      "typeVersion": 1
    },
    {
      "id": "9b81ffea-c472-4025-a0a2-6023f3da9b0d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -336
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 304,
        "content": "## Log Normalization and Denoising\n\nRaw logs are cleaned and normalized to remove low-value entries such as debug or informational messages."
      },
      "typeVersion": 1
    },
    {
      "id": "ac4ee442-eb76-40bf-91c3-aa41ce922b84",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        128
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 464,
        "content": "## Failure Pattern Clustering\n\nError messages are converted into embeddings and grouped using a vector store."
      },
      "typeVersion": 1
    },
    {
      "id": "55d9a63c-ef73-49f9-96c9-e08d531361b8",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 368,
        "content": "## Event Correlation Analysis\n\nFailure patterns are time-aligned with contextual events such as deployments, configuration changes, and traffic spikes."
      },
      "typeVersion": 1
    },
    {
      "id": "21c8b870-4481-49d1-bdd3-0ff9a70a7e9e",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2112,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 352,
        "content": "The final analysis is posted to Slack as an incident ticket for engineers to review."
      },
      "typeVersion": 1
    },
    {
      "id": "7329f14e-9970-4716-9d80-da445160fce6",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1552,
        112
      ],
      "parameters": {
        "color": 7,
        "width": 528,
        "height": 544,
        "content": "## Root Cause Analysis and Incident Ticket\n\nAn AI agent analyzes all collected signals and generates root cause hypotheses."
      },
      "typeVersion": 1
    },
    {
      "id": "c2a7c381-adda-4003-af89-a581dde6b9bb",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1360,
        80
      ],
      "parameters": {
        "width": 400,
        "height": 336,
        "content": "## AI-Powered Incident Root Cause Analysis\n\nThis workflow automates incident investigation using logs, metrics, deployment data, and configuration changes.\n\nIt clusters error logs, identifies failure patterns, correlates them with system events, and uses an AI agent to generate root cause hypotheses and recommended actions. The results are automatically posted to Slack for rapid incident response."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Fetch Logs": {
      "main": [
        [
          {
            "node": "Normalize and Denoise Logs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Metrics": {
      "main": [
        [
          {
            "node": "Merge Context Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document Loader": {
      "ai_document": [
        [
          {
            "node": "Cluster Log Messages",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Incident Trigger": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Root Cause Analysis Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Embeddings": {
      "ai_embedding": [
        [
          {
            "node": "Cluster Log Messages",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Time-Align Events": {
      "main": [
        [
          {
            "node": "Root Cause Analysis Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Context Data": {
      "main": [
        [
          {
            "node": "Cluster Log Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Feature Flags": {
      "main": [
        [
          {
            "node": "Merge Context Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cluster Log Messages": {
      "main": [
        [
          {
            "node": "Identify Failure Patterns",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Fetch Logs",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Metrics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Recent Deployments",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Feature Flags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Recent Deployments": {
      "main": [
        [
          {
            "node": "Merge Context Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Root Cause Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Root Cause Analysis Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Identify Failure Patterns": {
      "main": [
        [
          {
            "node": "Time-Align Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Root Cause Analysis Agent": {
      "main": [
        [
          {
            "node": "Create Incident Ticket",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize and Denoise Logs": {
      "main": [
        [
          {
            "node": "Merge Context Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow implements an AI-powered incident investigation and root cause analysis system that automatically analyzes operational signals when a system incident occurs.

Source: https://n8n.io/workflows/14044/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Turn unstructured pitch decks and investment memos into polished Due Diligence PDF reports automatically. This n8n workflow handles everything from document ingestion to final delivery, combining inte

HTTP Request, Pinecone Vector Store, OpenAI Embeddings +7
AI & RAG

Transform raw investment memorandums and financial decks into comprehensive, professional Due Diligence (DD) PDF reports. This workflow automates document parsing via LlamaParse, enriches internal dat

HTTP Request, Pinecone Vector Store, OpenAI Embeddings +7
AI & RAG

AI Multi-Document Analyzer with Smart Recommendations & Reporting

Crypto, Agent, OpenAI Chat +8
AI & RAG

Streamline M&A due diligence with AI. This n8n workflow automatically parses financial documents using LlamaIndex, embeds data into Pinecone, and generates comprehensive, AI-driven reports with GPT-5-

HTTP Request, Pinecone Vector Store, OpenAI Embeddings +6
AI & RAG

This Workflow simulates an AI-powered phone agent with RetellAI with two main functions: 📅 Appointment Booking – It can schedule appointments directly into Google Calendar. 🧠 RAG-based Information Ret

OpenAI Chat, Output Parser Structured, Qdrant Vector Store +10