Step 8: n8n 연결, 워크플로 자동화
n8n이란
워크플로우 자동화 플랫폼. 여러 시스템을 연결해 반복 작업을 자동화하며, UI로 워크플로우를 시각적으로 파악할 수 있다.
log-analysis는 로그 텍스트를 분석하는 Python(FastAPI) 서비스- 운영에서는 보통 메일로 로그가 들어오거나 다른 시스템이 자동으로 분석을 요청
- n8n은 “누가, 언제, 어떤 순서로 API를 호출할지”를 코드 없이 연결
- 즉
메일 수신 → 첨부 추출 → 분석 API 호출 → 결과 회신흐름을 JSON 워크플로로 정의 가능
시스템 아키텍처 내 n8n의 역할
기본 호출 경로:
n8n → mail-classifier → log-analysis → ai-agent-engine
시나리오:
- 이메일 등 외부 요청이 수신되면 n8n 워크플로우가 이를 트리거.
- 수신 메일 내용을 메일 분류기(
mail-classifier)에 전달 - 최초에 메일을 수신하였을 때 log-analysis를 이용하여 로그 분석을 수행
- 로그 분석에 대한 추가 분석 요청 시 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-To와References헤더 정보를 명시적으로 추가하여, 회신 메일이 스레드 내에 정상적으로 묶이도록 개선
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/.n8ndocker compose up -d
# http://localhost:5678 접속워크플로우 설계
역할 분담
| 단계 | 내용 |
|---|---|
| 1 | Outlook을 통해 로그 전달 |
| 2 | 로그 내용 추출 (title, content, attachments) |
| 3 | 로그 타입 자동 판별 |
| 4 | 적절한 로그 분석기 호출 |
| 5 | 결과 정규화 |
| 6 | 필요 시 RAG 적용 |
| 7 | Bedrock으로 사용자 친화적 설명 생성 |
| 8 | 메일/웹훅/채팅 형태로 결과 반환 |
처리 흐름
전체 흐름은 최초 로그 분석과 후속 질문(답장) 두 경로로 나뉜다.
최초 분석 플로우 — 이메일 수신 → 기본 로그 분석 → 회신
특히, 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 답변
| 노드명 (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 Reply | AI 에이전트의 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-input | RAG 컨텍스트(prompt_input) 생성 |
요건 및 최소 제한
- 요건: n8n 구성(방법 자유), chatbot을 통한 로그 분석, 파일 업로드를 통한 로그 분석
- 최소 제한
- Bedrock에는 로그 전문을 전달하지 않는다.
- 로그 내용에 따라 적절한 로그 분석기를 호출하여 분석한다.
검증 결과
n8n Node 집합

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 Reply | AI 에이전트의 Bedrock LLM 최종 답변을 읽고 에러 여부 및 가드레일 필터링 상태 판별 |
| Format Follow-up Reply | 에이전트가 만든 Markdown 조치 답변을 메일용 간이 HTML 형태로 파싱 변환 |
| Format Empty Content | 분석할 로그가 누락되었거나 복원에 실패했을 때 안내 메시지 빌드 |
테스트 시나리오
시나리오1: 단일 로그 분석 요청
메일 쓰레드

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

시나리오2: 다중 로그 분석 요청 (기능 개선 및 기능 개선에 대한 답변)
메일 쓰레드
- 중간에 김호민으로 보낸 메일은 잘못 전송된 메일. 하지만 계정 확인 노드로 인해 답변이 되지 않은 것을 확인할 수 있음

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

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

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

기능 고도화
Step 7 과제에서 보완한 로그 분석기 기능을 아래 3가지로 업데이트했다.
1. Multi Log 분석 기능
여러 로그 파일을 한 번에 분석하고 파일 간 교차 상관(correlation)까지 도출. LLM 쪽에서 분석 결과 3개의 파일까지 확인 가능.

추가 파일:
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.
동작:
- 파일마다
detect_log_type→tool_router.invoke로 기존 분석기 재사용(GC/Tomcat/Apache/Java/Thread). - 파일별 상태를
ANALYZED/NEEDS_SELECTION(타입 미확정) /ERROR로 분류. - 교차 상관 규칙으로 파일 간 장애 흐름을 추론:
- GC 압박 + Tomcat 오류 → 같은 장애 흐름 가능성 (HIGH)
- Apache 5xx/proxy + Tomcat 오류 → 앞단보다 WAS 원인 가능성 (HIGH)
- Thread dump 병목 + 애플리케이션 오류 → lock contention/DB 대기 (HIGH)
- 2개 이상 파일에서 HIGH → 서비스 흐름 전반 장애 가능성 (HIGH)
- severity 가중치(HIGH 3 / MEDIUM 2 / INFO 1)로 묶음 전체 최대 심각도 산출.
- 우선 조치(
recommended_actions)를 교차 상관 + 파일별 조치에서 최대 10개로 취합.
원본 로그 전문은 응답/리포트에 포함하지 않음(기존 정책 유지). 리포트 말미에 명시.
2. 분석 Log 다운로드 기능

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과 그 외 로그 유형은 동일한 수준으로 검증하지 못했다.
- 문서와 메일 결과를 더 전문적으로 보이도록 다듬을 여지가 있다.

