Step 8: n8n 연결, 워크플로 자동화

n8n이란

워크플로우 자동화 플랫폼. 여러 시스템을 연결해 반복 작업을 자동화하며, UI로 워크플로우를 시각적으로 파악할 수 있다.

  • log-analysis는 로그 텍스트를 분석하는 Python(FastAPI) 서비스
  • 운영에서는 보통 메일로 로그가 들어오거나 다른 시스템이 자동으로 분석을 요청
  • n8n은 “누가, 언제, 어떤 순서로 API를 호출할지”를 코드 없이 연결
  • 메일 수신 → 첨부 추출 → 분석 API 호출 → 결과 회신 흐름을 JSON 워크플로로 정의 가능

시스템 아키텍처 내 n8n의 역할

기본 호출 경로:

n8n → mail-classifier → log-analysis → ai-agent-engine

시나리오:

  1. 이메일 등 외부 요청이 수신되면 n8n 워크플로우가 이를 트리거.
  2. 수신 메일 내용을 메일 분류기(mail-classifier)에 전달
  3. 최초에 메일을 수신하였을 때 log-analysis를 이용하여 로그 분석을 수행
  4. 로그 분석에 대한 추가 분석 요청 시 LLM 모델이 내부 문서를 파악하여 제안

Docker 환경 구성

n8n 서비스는 로컬 개발 및 실행 환경을 위해 docker-compose.yml에 구성

Docker 서비스 설정

  • 이미지: docker/n8n/Dockerfile을 기반으로 커스텀 빌드 (FROM n8nio/n8n:2.10.3 사용)
  • 포트: 5678 외부 포트 바인딩
  • 볼륨: n8n-data:/home/node/.n8n을 사용하여 워크플로우 및 자격 증명 영속화
  • 타임존: Asia/Seoul

이메일 스레딩(Threading)을 위한 커스텀 패치

n8n 공식 이미지 빌드 시, docker/n8n/patch-email-send-thread-headers.mjs 스크립트를 적용하여 컨테이너 내부의 EmailSend 노드(v2) 코드를 패치

  • 패치 이유: 메일 송수신 시, 메일이 하나의 쓰레드로 묶이지 않아 가시성이 좋지 않았음.
  • 수정 사항: 메일 전송 옵션(mailOptions)에 In-Reply-ToReferences 헤더 정보를 명시적으로 추가하여, 회신 메일이 스레드 내에 정상적으로 묶이도록 개선
services:
  n8n:
    image: n8nio/n8n:2.10.3
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - TZ=Asia/Seoul
      - GENERIC_TIMEZONE=Asia/Seoul
      - N8N_PROTOCOL=http
      - N8N_SECURE_COOKIE=false
      - N8N_ENCRYPTION_KEY=change-this-to-long-random-string
      - N8N_RUNNERS_ENABLED=true
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
    volumes:
      - ./n8n_data:/home/node/.n8n
docker compose up -d
# http://localhost:5678 접속

워크플로우 설계

역할 분담

단계내용
1Outlook을 통해 로그 전달
2로그 내용 추출 (title, content, attachments)
3로그 타입 자동 판별
4적절한 로그 분석기 호출
5결과 정규화
6필요 시 RAG 적용
7Bedrock으로 사용자 친화적 설명 생성
8메일/웹훅/채팅 형태로 결과 반환

처리 흐름

전체 흐름은 최초 로그 분석후속 질문(답장) 두 경로로 나뉜다.

최초 분석 플로우 — 이메일 수신 → 기본 로그 분석 → 회신 image-2026-6-9_14-41-8.png

특히, 2번의 수신자 검증의 경우 개인 Gmail을 이용하기 때문에 모든 gmail이 아닌 테스트 계정으로부터만 수신되도록 설정

핵심 단계관련 노드명동작 및 설명
1. 이메일 수신 및 준비Gmail IMAP Trigger, Extract Mail Log Content지정된 이메일함에서 메일과 첨부파일을 수집하여 텍스트 데이터로 정제합니다.
2. 수신자 검증Recipient Allowed?허가된 사용자 혹은 모니터링 주소 기반의 안전한 요청인지 필터링합니다.
3. 로그 판별Has Log Content?메일에 분석 대상 로그가 들어있는지에 따라 최초 분석과 후속 질의(추가 질문) 경로로 분기합니다.
4-(1). 최초 요청 경로Call tools/invok규칙 파서를 통해 신속하게 로그 타입을 진단하며, 필요 시 사내 RAG 문서(참조 지식)를 검색해 매핑합니다.
4-(2). 추가 질문 경로Find Previous Analysis, Call agent-engine/invoke이전 분석 결과와 사용자의 신규 질문을 매핑하여 Bedrock LLM 기반 에이전트에게 맞춤 조치 답변을 생성하도록 합니다.
5. 답장 메일 발송Send Analysis Email겹침이 방지되고 여백이 깔끔하게 정돈된 프리미엄 HTML 메일 템플릿으로 사용자에게 최종 답장을 회신합니다.

이메일이 수신되면 정적 규칙 분석(analyze)을 거쳐 곧바로 분석 결과를 메일로 회신한다. (RAG 미사용)

후속 질문 플로우 — 답장으로 추가 분석 요청 → RAG 기반 Bedrock 답변 image-2026-6-9_14-46-59.png

노드명 (Node Name)핵심 한 줄 역할 요약
Extract Mail Log Content이메일 본문 및 첨부된 로그 파일에서 정제된 텍스트 로그 데이터 추출
Apply Config숨은참조(BCC) 루프 가드 적용 및 스레드 매핑용 메타 설정 설정
Normalize (Bundle) Analysis Result파서 결과에서 심각도 가중치를 추출하고 결과 JSON 구조를 균등 정규화
Format Selection Reply로그 종류를 판별하지 못했을 때 사용자가 분석기를 선택할 수 있도록 안내문 빌드
Format Analysis Reply로그 분석 보고서, 감지 패턴, RAG 문서를 묶어 세련된 답장용 HTML 메일 본문 빌드
Find Previous Analysis답장 수신 시 제목 캐시 확인 및 하단 인용 메일 역파싱을 통해 이전 분석 상태 스마트 복원
Build Follow-up Agent Request회신 본문 인용구를 제거하고 순수 신규 질문과 이전 분석 보고서를 묶어 AI 에이전트 프롬프트 빌드
Merge Follow-up Agent ReplyAI 에이전트의 Bedrock LLM 최종 답변을 읽고 에러 여부 및 가드레일 필터링 상태 판별
Format Follow-up Reply에이전트가 만든 Markdown 조치 답변을 메일용 간이 HTML 형태로 파싱 변환
Format Empty Content분석할 로그가 누락되었거나 복원에 실패했을 때 안내 메시지 빌드

회신 메일(추가 질문)이 도착하면 이전 분석 이력을 조회하고, RAG 지식 검색 결과를 컨텍스트로 Bedrock LLM이 답변을 생성한다. (RAG는 항상 활성화)

호출 API

API역할
POST /api/v1/log-analysis/tools/invoke로그 타입 판별 + 적절한 분석기 호출
POST /api/v1/rag/build-response-inputRAG 컨텍스트(prompt_input) 생성

요건 및 최소 제한

  • 요건: n8n 구성(방법 자유), chatbot을 통한 로그 분석, 파일 업로드를 통한 로그 분석
  • 최소 제한
    • Bedrock에는 로그 전문을 전달하지 않는다.
    • 로그 내용에 따라 적절한 로그 분석기를 호출하여 분석한다.

검증 결과

n8n Node 집합

image.png

Code 노드별 역할

노드명 (Node Name)핵심 한 줄 역할 요약
Extract Mail Log Content이메일 본문 및 첨부된 로그 파일에서 정제된 텍스트 로그 데이터 추출
Apply Config숨은참조(BCC) 루프 가드 적용 및 스레드 매핑용 메타 설정 설정
Normalize (Bundle) Analysis Result파서 결과에서 심각도 가중치를 추출하고 결과 JSON 구조를 균등 정규화
Format Selection Reply로그 종류를 판별하지 못했을 때 사용자가 분석기를 선택할 수 있도록 안내문 빌드
Format Analysis Reply로그 분석 보고서, 감지 패턴, RAG 문서를 묶어 세련된 답장용 HTML 메일 본문 빌드
Find Previous Analysis답장 수신 시 제목 캐시 확인 및 하단 인용 메일 역파싱을 통해 이전 분석 상태 스마트 복원
Build Follow-up Agent Request회신 본문 인용구를 제거하고 순수 신규 질문과 이전 분석 보고서를 묶어 AI 에이전트 프롬프트 빌드
Merge Follow-up Agent ReplyAI 에이전트의 Bedrock LLM 최종 답변을 읽고 에러 여부 및 가드레일 필터링 상태 판별
Format Follow-up Reply에이전트가 만든 Markdown 조치 답변을 메일용 간이 HTML 형태로 파싱 변환
Format Empty Content분석할 로그가 누락되었거나 복원에 실패했을 때 안내 메시지 빌드

테스트 시나리오

시나리오1: 단일 로그 분석 요청

메일 쓰레드

image-2026-6-10_21-31-53_masked.png

각 메일 간 답변:

  • 첨부파일에 대한 로그 분석 결과로 FE 화면을 그대로 메일로 답변
  • 추가로 로그 분석을 요청 시, agent-engine을 호출하여 LLM이 답변, 특히 해당 답변을 통해 실제 KnowledgeBase에 등록된 문서 기반으로 답변하는 것을 확인할 수 있음.

image-2026-6-10_21-32-43_masked.png image-2026-6-10_21-32-58_masked.png

시나리오2: 다중 로그 분석 요청 (기능 개선 및 기능 개선에 대한 답변)

메일 쓰레드

  • 중간에 김호민으로 보낸 메일은 잘못 전송된 메일. 하지만 계정 확인 노드로 인해 답변이 되지 않은 것을 확인할 수 있음

image-2026-6-10_21-37-41_masked.png

각 메일 간 답변:

  • 로그를 전체적으로 요약하고, 각 로그별로 심각도를 우선 안내
  • 이후, 각 로그별 상세 분석결과를 전달
  • 사내 운영 문서에 따라, 조치가 가장 시급한 로그는 어떤 것인지 물었을 때, LLM이 직접 운영상 가장 심각도가 높은 Danger 수준의 로그 파일을 선정하여 요청자에게 전달

image-2026-6-10_21-39-57_masked.png image-2026-6-10_21-40-30.png image-2026-6-10_21-40-46_masked.png

시나리오3: Tomcat 분석 요청

  • 모든 Log에 대해서 분석이 되어야 하기 때문에 Tomcat 요청 시 정상적으로 수행이 되는지 확인
  • logtype 지정하지 않았을 때

image-2026-6-10_21-44-46_masked.png

  • Logtype 지정 시
    • GC Log 요청처럼, Thread 형식으로 이어져야 하는데, 정상적으로 반영되지 않은 모습

image-2026-6-10_21-45-21_masked.png image-2026-6-10_21-45-37_masked.png

기능 고도화

Step 7 과제에서 보완한 로그 분석기 기능을 아래 3가지로 업데이트했다.

1. Multi Log 분석 기능

여러 로그 파일을 한 번에 분석하고 파일 간 교차 상관(correlation)까지 도출. LLM 쪽에서 분석 결과 3개의 파일까지 확인 가능.

image-2026-6-10_22-25-59.png image-2026-6-10_22-26-19.png image-2026-6-10_22-27-18.png

추가 파일:

routers/bundle_analysis.py         # API
services/bundle_analyzer.py        # 분석 + 교차 상관 + 리포트 생성
models/bundle_schemas.py           # 요청/응답 스키마
frontend/src/features/bundle/      # 번들 분석 UI
tests/test_bundle_analysis_api.py

추가 API:

POST /api/v1/log-analysis/bundle/analyze   # 다중 분석 결과 JSON
POST /api/v1/log-analysis/bundle/report    # Markdown 리포트 파일 다운로드

요청은 최대 10개 파일(BUNDLE_MAX_FILES = 10), 각 파일은 source_name, content, 선택적 log_type.

동작:

  1. 파일마다 detect_log_typetool_router.invoke로 기존 분석기 재사용(GC/Tomcat/Apache/Java/Thread).
  2. 파일별 상태를 ANALYZED / NEEDS_SELECTION(타입 미확정) / ERROR로 분류.
  3. 교차 상관 규칙으로 파일 간 장애 흐름을 추론:
    • GC 압박 + Tomcat 오류 → 같은 장애 흐름 가능성 (HIGH)
    • Apache 5xx/proxy + Tomcat 오류 → 앞단보다 WAS 원인 가능성 (HIGH)
    • Thread dump 병목 + 애플리케이션 오류 → lock contention/DB 대기 (HIGH)
    • 2개 이상 파일에서 HIGH → 서비스 흐름 전반 장애 가능성 (HIGH)
  4. severity 가중치(HIGH 3 / MEDIUM 2 / INFO 1)로 묶음 전체 최대 심각도 산출.
  5. 우선 조치(recommended_actions)를 교차 상관 + 파일별 조치에서 최대 10개로 취합.

원본 로그 전문은 응답/리포트에 포함하지 않음(기존 정책 유지). 리포트 말미에 명시.

2. 분석 Log 다운로드 기능

image-2026-6-10_22-27-39.png

bundle/report가 분석 결과를 Markdown 파일로 반환.

  • build_bundle_report_markdown()이 생성: 파일별 결과 표 → 파일별 상세(신호/패턴/근거/심층분석/조치) → 교차 분석 → 우선 조치 → 감지 패턴 요약.
  • 응답 헤더 Content-Disposition: attachment; filename="{request_id}.md"로 다운로드.

3. Vector DB 사용

Step7의 키워드 RAG에 임베딩 기반 의미 검색을 추가. Step7 품질 비교 문서에서 “이후 VectorDB를 추가하면 키워드 대비 개선을 비교할 수 있다”고 적었던 부분의 실제 구현.

기존, AWS의 OpenSearch와 Bedrock의 Titan Embedding Model까지 직접 이용해서 구현하는 게 목표였지만 시간과 비용 이슈로 간단하게나마 구현.

추가 파일:

services/rag/embedding.py         # 외부 모델 없는 결정적 해싱 임베딩(384차원)
services/rag/chroma_retriever.py  # Chroma 벡터 검색 (HttpClient)
services/rag/chroma_indexer.py    # KB → Chroma 색인 CLI
services/rag/hybrid_retriever.py  # 키워드 + 벡터 하이브리드 병합
tests/rag/test_chroma_components.py

환경 변수:

LOG_ANALYSIS_CHROMA_HOST                  (기본 localhost)
LOG_ANALYSIS_CHROMA_PORT                  (기본 8000)
LOG_ANALYSIS_CHROMA_COLLECTION            (기본 knowledge_chunks)
LOG_ANALYSIS_CHROMA_EMBEDDING_DIMENSIONS  (기본 384)

핵심:

  • HashingEmbedding: SHA-256 토큰 해싱으로 차원에 매핑하는 결정적 임베딩. 외부 임베딩 서비스 없이 재현 가능(실습/오프라인 친화). chunk_embedding_text()로 title·section·docs_id·pattern_id·log_type·keywords·content를 합쳐 임베딩.
  • ChromaRetriever: chromadb.HttpClient로 원격 Chroma 접속(from_env()로 host/port/collection/dim 환경변수 주입). index_chunks/ensure_indexed/count/retrieve 제공. 거리→score 변환은 1/(1+distance). posthog 텔레메트리 비활성.
  • HybridRetriever: 키워드 retriever + 벡터 retriever 결과를 rank 기반 가중 병합. 기본 가중치 keyword 1.0 / vector 1.2. 두 소스 모두에서 잡힌 chunk엔 +1.5 가산(교집합 우대). 후보를 top_k×3까지 모은 뒤 병합·정렬.
  • 기존 Retriever/BaseRetriever 인터페이스를 그대로 구현 → KnowledgeService가 구현체에 의존하지 않는 Step7 설계 덕분에 교체만으로 연결 가능.

키워드 RAG와의 관계:

  • 키워드 RAG(Knowledge Base): 빠르고 디버깅 쉬움, 표현이 다르면 검색 실패.
  • 벡터 RAG(Chroma): 의미 유사도로 표현 차이를 흡수.
  • 하이브리드: 키워드 정확 매칭 + 의미 검색을 동시에. Step7 품질 비교 문서의 “키워드 한계”를 보완하는 방향.

한계 및 개선점

시연 중 동작하지 않은 문제가 있어 원인 파악이 필요하다.

  • 같은 메일 스레드에서 추가 로그 파일을 요청했을 때도 답변이 이어지는지 확인이 필요하다.
  • GC 로그는 정상 응답을 확인했지만, Tomcat과 그 외 로그 유형은 동일한 수준으로 검증하지 못했다.
  • 문서와 메일 결과를 더 전문적으로 보이도록 다듬을 여지가 있다.