[데브노트] 웹 프로젝트 (devnote.kr)

ELK 스택으로 MSA 로그 한곳에 모으기

남건욱 2025. 9. 16. 21:34

목차

    반응형

    1. 왜 중앙화된 로그 시스템이 필요할까?

    마이크로서비스 환경에서 장애가 발생하면 곤란한 상황에 빠질 수 있다. 현재 나의 devnote를 예로 들면 요청 하나를 추적하기 위해  6개의 서비스 컨테이너에 각각 접속해 로그 파일을 뒤지는 것은 상당히 비효율적일것이다. 이 문제를 해결하기 위해 모든 서비스의 로그를 한곳으로 모아 검색하고 분석할 수 있는 중앙화된 로그 시스템으로 ELK 스택을 구축했다.

     

    2. Devnote 프로젝트의 로그 아키텍처

    로그는 Filebeat → Logstash → Elasticsearch → Kibana 순서로 흐르도록 구성했다. 각 컴포넌트는 아래처럼 명확한 역할을 수행한다.

     

    MSA 서비스 → 호스트의 로그 파일 → Filebeat (수집) → Logstash (가공) → Elasticsearch (저장/색인) → Kibana (시각화/검색)

     

    3. 1단계: 로그 포맷 통일하기

    먼저 6개 서비스가 모두 동일한 형식으로 로그를 남기도록 application.yml의 로깅 패턴을 통일했다.

    특히 [${spring.application.name}] 부분을 추가하여 로그 한 줄만 봐도 어떤 서비스에서 발생했는지 명확히 알 수 있도록 했다.

    logging:
      pattern:
        file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [${spring.application.name}] %msg%n"

     

    4. 2단계: Filebeat로 로그 수집하기

    Filebeat는 각 서버에 설치되어 로그 파일의 변경을 감지하고 수집하는 경량 에이전트다. docker-compose.yml의 volumes 설정을 통해 서버의 로그 디렉터리(/home/gunwook/app/devnote/logs)를 Filebeat 컨테이너의 /var/log/msa로 연결했다. filebeat.yml에는 이 경로의 모든 *.log 파일을 감시하도록 설정하여 모든 서비스의 로그를 수집했다.

     

    5. 3단계: Logstash로 로그 파싱 및 정제하기

    Filebeat가 보낸 텍스트 로그는 그 자체로 분석하기는 어렵다. Logstash는 이 비정형 데이터를 구조화된 JSON 데이터로 가공하는 역할을 한다. logstash.conf의 filter 플러그인에 grok 패턴을 사용하여, 1단계에서 정의한 로그 포맷에 맞춰 로그를 파싱했다. 이것을 통해서 service_name, log_level 등 의미 있는 필드를 추출하여 Elasticsearch에 저장할 수 있었다.

    # logstash.conf
    filter {
      grok {
        match => { "message" => "%{...} - \[%{DATA:service_name}\] %{GREEDYDATA:log_message}" }
      }
    }

     

     

    6. 4단계: Kibana에서 로그 검색 및 시각화하기

    이제 Kibana 대시보드에 접속하여 msa-logs-* 인덱스 패턴을 생성했다. 이제 단일 검색창에서 service_name: "user-service" AND log_level: "ERROR" 와 같은 KQL 쿼리를 통해 수많은 로그 중에서 원하는 내용을 곧바로 찾아낼 수 있게 되었다.

     

    7. 느낀점

    ELK 스택을 구축하기 전에는 장애 추적이 쉽지 않은 작업이었지만 이제는 오히려 간단한 작업이 되었다. 중앙화된 로그 시스템은 단순히 편리함을 넘어서 MSA의 안정성과 운영 효율성을 향상시켜주는 필수적인 기술이라고 느껴졌다.

    반응형
    프로필사진

    남건욱's 공부기록