통합 로그 시스템



About Project
Objective
AhnLab EPP / EDR / MDS 보안 로그를 공통 스키마로 정규화하고, Loki·Grafana 대시보드, Teams 실시간 알림, MCP 기반 자연어 조회까지 연결해 로그 분석과 대응 속도를 높인 통합 로그 시스템.
Tools & Technologies
Node.js, TypeScript, NestJS, syslog-ng, Vector, Loki, Grafana, Docker Compose, Teams Webhook, MCP, JSON-RPC
Challenge
기존에는 보안 로그를 확인하려면 각 솔루션 사이트에 접속해 로그인하고, 조회 조건을 직접 입력한 뒤 결과를 하나씩 해석해야 했습니다. 특히 EPP / EDR / MDS는 로그 형식과 필드 구성이 서로 달라, 서비스 간 비교나 공통 조건 기반 탐색이 어려웠습니다.
이 프로젝트는 단순히 로그를 저장하는 데서 끝나지 않고, 운영자가 로그를 더 빠르게 찾고, 더 쉽게 해석하고, 바로 대응할 수 있는 흐름을 만드는 것을 목표로 했습니다. 이를 위해 서로 다른 보안 로그를 하나의 기준으로 정규화하고, 대시보드·실시간 알림·자연어 조회까지 연결하는 통합 로그 시스템을 구축했습니다.
로그 입력 경로
알림 흐름
자연어 조회 흐름
배포 방식
장비별 로그를 실제로 분석한 뒤, 서비스 간 공통으로 활용할 수 있는 기준 필드를 추출해 아래 스키마로 정규화했습니다.
service: 로그가 어느 보안 솔루션(EPP / EDR / MDS)에서 왔는지 식별risk: 보안 솔루션이 탐지한 위협 수준syslog_type: 장비별 이벤트 유형을 식별하기 위해 파싱 단계에서 추가한 필드parse_status: 지정한 서비스 포맷이 아닌 다른 syslog가 들어오거나 부분 파싱에 실패한 경우를 식별하기 위한 상태 필드이 공통 스키마를 통해 서로 다른 장비 로그라도 동일한 기준으로 필터링·집계·탐색할 수 있도록 구성했습니다.
이 프로젝트에서 가장 중요하게 가져간 설계 판단 중 하나는 수집 책임과 파싱 책임을 분리하는 것이었습니다.
이렇게 분리한 이유는 다음과 같습니다.
결과적으로 수집 계층은 안정적으로 유지하면서도, 파싱/정규화 로직은 빠르게 수정·확장할 수 있는 구조를 만들 수 있었습니다.
이 프로젝트의 두 번째 핵심 판단은, 로그 파이프라인을 단순 대시보드 조회 도구가 아니라 운영 자동화 인터페이스로 확장하는 것이었습니다.
이를 위해 NestJS 기반 MCP 서버를 별도 애플리케이션으로 구현했고, 헥사고날 아키텍처를 적용해 어댑터 레이어에서 JSON-RPC over HTTP / stdio를 모두 지원하도록 설계했습니다. MCP 서버는 Loki 질의용 도구를 제공하고, 자연어 요청을 기반으로 필요한 로그 조회 흐름을 빠르게 실행할 수 있도록 구성했습니다.
이를 통해 운영자는 반복적인 조회 조건 입력 과정을 줄이고, 예를 들어 특정 IP 대역, 특정 위험도, 특정 시각 주변 로그를 빠르게 조회·요약하는 흐름으로 접근할 수 있게 되었습니다.
가장 어려웠던 점은 EPP / EDR / MDS가 모두 syslog로 들어오더라도, 실제 메시지 형식은 완전히 다르다는 점이었습니다.
뿐만 아니라 같은 장비 안에서도 필드 구성이 일정하지 않거나, timestamp 형식과 메시지 구조가 다를 수 있어 하나의 파서로 처리하기 어려웠습니다.
이를 해결하기 위해 Vector에서:
parse_status=partial/invalid로 상태 보존을 적용했습니다.
이 구조를 통해 파싱 실패 로그까지 완전히 버리지 않고, 운영자가 품질 상태를 함께 확인할 수 있는 형태로 정리할 수 있었습니다.
로그를 Loki에 적재하는 것만으로는 운영 효율이 크게 좋아지지 않았습니다. 운영자 관점에서는 "무슨 일이 일어났는지 바로 알 수 있는 정보"가 필요했습니다.
이를 위해:
하도록 구성했습니다.
알림 메시지에는 사용자 이름, IP 주소, 악성 파일명 등 어떤 호스트에 어떤 문제가 발생했는지 직관적으로 파악할 수 있는 정보를 포함시켜, 운영자가 대시보드에 들어가기 전에도 상황을 빠르게 인지할 수 있도록 만들었습니다.
기존 방식은 솔루션 접속 → 로그인 → 조건 지정 → 조회 → 결과 해석처럼 여러 단계를 거쳐야 했고, 동일한 유형의 로그 확인에도 반복 작업이 많았습니다.
이를 해결하기 위해 MCP 기반 조회 도구를 붙여 자연어 기반 조회 흐름으로 확장했습니다. 이 구조는 특정 서비스의 위험 로그 목록 조회, 위험 상세 로그 조회, 시간 범위 기반 조회 등으로 나누어 구현했고, Loki를 직접 질의해 결과를 반환하도록 구성했습니다.
시나리오 테스트와 특정 예시 질의 기준으로 보면, 기존 10~15분 걸리던 로그 확인 과정을 1~2분 수준으로 줄일 수 있었습니다.
이 프로젝트의 Teams 알림은 Grafana가 직접 보내는 방식이 아니라, NestJS API가 직접 Webhook을 전송하는 구조로 구성했습니다.
실제로 Teams로 전달한 이벤트는 다음과 같은 즉시 대응 대상이었습니다.
메시지에는 운영자가 바로 상황을 파악할 수 있도록 다음 정보를 포함했습니다.
/rpc와 stdio transport 모두 지원이 프로젝트를 통해 단순 로그 수집을 넘어, 수집 안정성, 파싱 정규화, 대시보드, 실시간 알림, 자연어 조회까지 연결하는 운영 자동화형 로그 시스템을 설계하고 실제 환경에 적용해본 경험을 쌓을 수 있었습니다.