ELK Stack을 이용하여 로그 모니터링 하기

2025. 5. 28. 16:32·Infra

이전 글에서 Prometheus + Grafana를 이용하여 시스템 모니터링을 구성했었다.

이번 글에선 Filebeat + Elastic Search + Log Stash + Kibana 를 이용하여 로그 모니터링을 구성한 과정을 작성한다.

 

ELK Stack을 쓰는 이유는 ?

로그 수집 / 분석

  • 문제가 생긴 원인을 파악하거나 사용자 행위 분석 등 텍스트 기반 검색이 필요할 때
  • "왜" 죽었는지 알 수 있다.
구성 요소 역할
Filebeat 로그 파일을 읽어 Logstash로 전달
Log Stash 로그 수집 및 파싱 (필요 시 변환)
Elastic Search 로그 저장 및 검색
Kibana 로그 시각화 및 대시보드

 

현재 디렉터리 구조는 아래와 같다.

msa-deploy/
├── docker-compose.yml
├── .env 파일들
├── prometheus.yml
└── elk/
    ├── logstash.conf          # Logstash 입력 → 출력 규칙
    ├── filebeat.yml           # Filebeat가 로그를 어디서 → 어디로 보낼지
    └── data/                  # (Elasticsearch 저장용, volume 연결)
  • docker-compose.yml, logstash.conf, filebeat.yml을 작성해야한다.

docker-compose.yml

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - ./elk/data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    restart: unless-stopped

  kibana:
    image: docker.elastic.co/kibana/kibana:8.12.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    restart: unless-stopped

  logstash:
    image: docker.elastic.co/logstash/logstash:8.12.0
    container_name: logstash
    ports:
      - "5044:5044"   # Filebeat input
    volumes:
      - ./elk/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    depends_on:
      - elasticsearch
    restart: unless-stopped

  filebeat:
    image: docker.elastic.co/beats/filebeat:8.12.0
    container_name: filebeat
    user: root
    depends_on:
      - logstash
    volumes:
      - ./elk/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

 

Filebeat

 

elk/filebeat.yml

filebeat.inputs:
  - type: container
    paths:
      - /var/lib/docker/containers/*/*.log
    processors:
      - add_docker_metadata: ~

output.logstash:
  hosts: ["logstash:5044"]
  • filebeat.inputs : Docker 컨테이너 로그 파일 자동 수집
  • add_docker_metadata : 컨테이너 이름, 이미지 이름 등 메타데이터 자동 추가
  • output.logstash : 로그를 Logstash에 전달한다. (5044 포트)

설정을 마쳤으면 docker-compose를 재시작한다.

 

혹시 filebeat에서 아래와 같은 오류가 발생하면 권한을 바꿔줘야한다.

ubuntu@ip-@@@@:~/msa-deploy$ docker logs filebeat
Exiting: error loading config file: config file ("filebeat.yml") must be owned 
by the user identifier (uid=0) or root

 

아래 명령어로 파일의 소유자를 root로 바꿔준다.

sudo chown root:root ./elk/filebeat.yml
sudo chmod 600 ./elk/filebeat.yml

 

아래 명령어로 Elastic Search가 정상적으로 응답하고 있는지 확인한다.

curl http://localhost:9200

 

다음과 같이 출력되면 정상 동작중인 것이다.

{
  "name" : "6624bd4560b2",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "dFhT841PRu6k5uFggLcNCw",
  "version" : {
    "number" : "8.12.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "1665f706fd9354802c02146c1e6b5c0fbcddfbc9",
    "build_date" : "2024-01-11T10:05:27.953830042Z",
    "build_snapshot" : false,
    "lucene_version" : "9.9.1",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

 

또 아래 명령어를 이용해 로그가 정상 수집되고 있는지 확인한다.

curl http://localhost:9200/_cat/indices?v

 

컨테이너별로 태그를 지정하여 로그를 관리하고 싶은 경우

filebeat.yml의 processors: 부분에 match_source: true를 넣어준다.

filebeat.inputs:
  - type: container
    paths:
      - /var/lib/docker/containers/*/*.log
    processors:
      - add_docker_metadata:
        match_source: true 

output.logstash:
  hosts: ["logstash:5044"]

 

docker-compose.yml의 로그를 관리하고 싶은 컨테이너에 아래와 같이 label을 추가한다.

user-service:
    image: @@@/user-service:latest
    container_name: user-service
    labels:
      service: user-service

 

백, 프론트 컨테이너만 붙여줘도 된다.

DB, Redis 같은 외부 패키지 / 미들웨어 서비스에 레이블을 붙여도 되지만, 보통 애플리케이션 로그보단 시스템 로그 중심이기 때문에 Kibana에서 추적할 일이 드물기 때문이다.

하지만 백, 프론트 컨테이너는 서비스 별로 로그를 관리를 해야하기 때문에 꼭 붙여주자.

 

설정을 마치면 Filebeat에서 자동으로 태그별로 수집해준다.

 

Logstash

 

elk/logstash.conf

input {
  beats {
    port => 5044
  }
}

filter {
  json {
    source => "message"
    skip_on_invalid_json => true
  }

  if [container][labels][service] {
    mutate {
      add_field => { "service_name" => "%{[container][labels][service]}" }
    }
  }
}

output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "docker-logs-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}
  • input : Filebeat가 보내는 로그를 5044 포트에서 받음
  • filter : JSON 파싱 + 레이블에서 service_name 필드 추가
  • output : Elastic Search에 docker-logs-YYYY.MM.dd 인덱스로 저장 + 콘솔 출력

Kibana

http://<서버 IP>:5601 로 이동하여 Kibana에 접속하자.

  • 보안 설정은 나중에 할 수 있으므로 일단 Dismiss를 선택하자.
  • Integrations는 이미 Filebeat로 로그를 전송 중이므로 Explore on my own을 선택하자.

Index 패턴 만들기

1. 왼쪽 햄버거 메뉴나, 검색창에 Stack Management를 검색하여 클릭한다.

 

2. 메뉴 중 Kibana - Data Views를 클릭한다.

 

3. Create data view 클릭 후 Name, Index pattern을 입력 해 준다.

  • Timestamp는 자동 감지 된다. 없다면 다른 값들이 후보로 나올 수 있다.

인덱스를 모르는 경우는 아까 엘라스틱 서치 동작 테스트 중 사용한 명령어를 다시 한 번 사용하자.

curl http://localhost:9200/_cat/indices?v
health status index                  uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
yellow open   docker-logs-2025.05.19 W4UkbhiVQuKaZUJDO1csrg   1   1    1717750            0    427.8mb        427.8mb      427.8mb

현재 나는 이런 응답이 오는데 여기서 index인 docker-logs-* 만 입력해주면 된다.

 

4. Kibana - Discover로 이동하여 로그가 잘 수집되고 있는지 확인

 

현재 ELK 스택 구성은 완료되었지만 전체 컨테이너의 로그를 수집하는 상황이 발생했다.

전에 label을 붙인 컨테이너 이외에는 로그를 수집 할 필요가 없기 때문에 이미 들어온 로그들은 삭제하고 label이 붙은 컨테이너만 로그를 수집하도록 변경할 것이다.

 

.elk/filebeat.yml

filebeat.inputs: []

filebeat.autodiscover:
  providers:
    - type: docker
      templates:
        - condition:
            contains:
              docker.container.labels.service: ""
          config:
            - type: container
              paths:
                - /var/lib/docker/containers/${data.docker.container.id}/*.log
              processors:
                - add_docker_metadata:
                    match_source: true

 

새로 변경된 autodiscover 방식은 기존의 inputs 방식과 아래와 같은 차이가 있다.

설정이 좀 더 복잡해도 유연하게 로그를 처리하고, 더 빠른 수집이 가능하기 때문에 변경했다.

항목 filbeat.inputs 방식 filebeat.autodiscover 방식
로그 경로 수집 방식 고정된 경로
(/var/lib/docker/container/*/*.log)
컨테이너가 시작될 때 동적으로 경로 생성
라벨 필터링 drop_evenet 등의 프로세서로 필터링 condition.contains로 라벨 조건 직접 지정 가능
유연성 낮음 - 모든 컨테이너 대상 높음 - 조건 만족 컨테이너 대상
리소스 효율성 더 많은 로그 읽고 나서 필터 처음부터 조건 맞는 컨테이너만 수집
설정 난이도 간단 상대적으로 복잡하지만 정밀 제어 가능
실시간 반응성 느림 (파일 변경 감지 기반) 빠름 (컨테이너 이벤트 기반)

 

기존 로그 삭제

Stack Management - Index management 에 접속한다.

삭제할 로그를 선택하고 Manage Index에서 Delete index를 클릭하여 삭제한다.

 

filebeat의 로그 초기화 하는 법

# Filebeat 수집 상태 초기화
docker-compose down filebeat
sudo rm -rf /var/lib/filebeat/registry

# 기존 로그 파일 삭제 (주의: 이건 실제 로그 삭제임)
sudo rm -rf /var/lib/docker/containers/*/*-json.log

# 다시 시작
docker-compose up -d filebeat

 

 

Spring Boot에서 Log 형식 Json으로 바꾸는 법

기존 로그 형식은 Json 형식이 아니다. Kibana에서 로그 분석, 수집을 더욱 잘 할 수 있게 하려면 Json으로 로그를 바꿔야한다.

 

build.gradle에 아래 의존성 추가

implementation 'net.logstash.logback:logstash-logback-encoder:7.4'

 

main/resources에 아래 파일을 추가한다.

 

logback-spring.xml

<configuration>

    <appender name="JSON_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <root level="INFO">
        <appender-ref ref="JSON_CONSOLE" />
    </root>

</configuration>

 

이제 Spring Boot에서 로그를 JSON 형식으로 출력하게 된다.

'Infra' 카테고리의 다른 글

Prometheus + Grafana로 시스템 상태 모니터링 하기  (0) 2025.05.28
Netlify에 프론트 서버 띄우기  (0) 2025.04.17
CI/CD (GitHub Actions, Jenkins)  (0) 2025.03.25
'Infra' 카테고리의 다른 글
  • Prometheus + Grafana로 시스템 상태 모니터링 하기
  • Netlify에 프론트 서버 띄우기
  • CI/CD (GitHub Actions, Jenkins)
juuuuuuun
juuuuuuun
  • juuuuuuun
    namae
    juuuuuuun
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • java (2)
      • Infra (4)
      • server (2)
      • algorithm (52)
      • HTTP (8)
      • android (1)
      • baekjoon (16)
      • 소프트웨어공학 (6)
      • 기타 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
juuuuuuun
ELK Stack을 이용하여 로그 모니터링 하기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.