스프링부트/ELK

[ELK] 로그스태시 도커로 다운 받기(+설정 및 연결)

삼록이 2025. 9. 24. 21:38

https://gotopm.tistory.com/115

 

엘라스틱 서치, 키바나 도커로 다운로드

엘라스틱 서치란?하나의 데이터베이스다. 다만, 단순한 데이터베이스라기보다는 빠른 검색을 위해 특화된 엔진이자 데이터베이스라고 보면 된다.엘라스틱 서치는 JSON문서 단위로 데이터를 저

gotopm.tistory.com

https://gotopm.tistory.com/117

 

[Spring] 스프링과 엘라스틱 서치 연결(+키바나로 확인까지)

이전 게시물을 통해 엘라스틱 서치와 키바나를 다운받았다.엘라스틱 서치를 통해 검색기능을 구현하기 위해, 이제 스프링과 엘라스틱 서치를 연결시켜보려한다.먼저 검색로직은 아래와 같다.

gotopm.tistory.com

 

위 첫번 째 게시물을 순서대로 따라가다 보면 엘라스틱 서치, 키바나를 도커로 다운 받을 수 있다.

그리고 두번째 게시물까지 따라가면 스프링과 엘라스틱 서치를 연결까지도 가능하니 

위의 게시물을 따라 엘라스틱서치, 키바나를 연동할 수 있다.

본 게시물에서는 로그스태시를 설치하고 설정, 연결하는 것 까지 해보려 한다.


 

첫번째 게시물에 있던 도커파일에 logstash 부분을 추가했다.

엘라스틱 서치와, 키바나가 설치되고 연결이 되었다면, 이제는

docker compose up logstash 명령어로 로그스태시를 설치하기 전에,,,!!!

앞서 설정해주어야 할 것이 있다!!

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=true
      - ELASTIC_PASSWORD=changeme123
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ports:
      - "9200:9200"
    volumes:
      - es_data:/usr/share/elasticsearch/data

  kibana:
    image: docker.elastic.co/kibana/kibana:8.15.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_SERVICEACCOUNTTOKEN=AAEAAWVsYXN0aWMva2liYW5hL2tpYmFuYS1zZXJ2aWNlOllWYkxLeVRpVFJDM0wwMi1Nc3hST3c
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

  logstash:
    image: docker.elastic.co/logstash/logstash:8.15.0
    container_name: logstash
    volumes:
      # logstash.conf를 현재 디렉토리에 두고 마운트
      - ./pipeline/:/usr/share/logstash/pipeline/
      # 애플리케이션 로그 디렉토리 마운트
      - ./logs:/usr/share/logstash/logs
    environment:
      - xpack.monitoring.enabled=false
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=changeme123
    depends_on:
      - elasticsearch
    ports:
      - "5044:5044"   # Beats input용 (추후 Filebeat 연동할 때 필요)

volumes:
  es_data:
    driver: local

 

 


 

자. 아래 logstash 부분을 보면 volumes 설정이 있다.

*참고로 xpack.monitoring.enabled = false 는 xpack(ELK의 스택에 붙는 부가기능) 중 모니터링 설정을 끄는 것이다.

  logstash:
    image: docker.elastic.co/logstash/logstash:8.15.0 <--사용할 컨테이너 이미지 지정
    container_name: logstash <--컨테이너 이름 지정
    volumes: <--host(내 PC)와 컨테이너 안 경로를 연결(마운트)
      # logstash.conf를 현재 디렉토리에 두고 마운트
      - ./pipeline/:/usr/share/logstash/pipeline/
      # 애플리케이션 로그 디렉토리 마운트
      - ./logs:/usr/share/logstash/logs
    environment:
      - xpack.monitoring.enabled=false
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=changeme123
    depends_on:
      - elasticsearch
    ports:
      - "5044:5044"   # Beats input용 (추후 Filebeat 연동할 때 필요)

 

도커로 실행할 logstash 컨테이너 내부의 어떤 폴더와 호스트 PC(내 컴퓨터)의 어떤 폴더 사이에 연결설정이 있다.

그래서 내 컴퓨터에도 그 폴더를 먼저 만들어 놓아야한다.

먼저 이유를 더 상세히 설명하기 위해 volumes 부분을 다시 살펴보자.

  volumes:
      - ./pipeline/:/usr/share/logstash/pipeline/   --1번
      - ./logs:/usr/share/logstash/logs   --2번

1번 설명.

호스트의 pipeline폴더와 컨테이너의 /usr/share/logstash/pipeline/ 폴더를 연결하는 설정이다.

(사실상 공유된다고 보면 된다)

로그스태시는 /usr/share/logstash/pipeline/ 안의 모든 .conf파일(설정파일)을 자동 실행하는데 

그 설정파일을 우리 컴퓨터(호스트PC)에서 설정하고 관리할 수 있게 /usr/share/logstash/pipeline/ 이 폴더와 내 컴퓨터에 pipeline이라는 폴더를 연결 시키는 것이다.

(그러면 로그 스태시 이미지를 매번 docker로 다시 설치하 않아도 되니까.)

그러므로 이 도커파일로 logstash가 설치되기 이전에 pipeline폴더가 생성되어있어야한다.

pipeline폴더의 위치는 docker-compose파일과 동일선상에 위치하면 된다.(아래 사진 참고)

 

 

2번 설명.

로그스태시는 로그파일을 읽어와 엘라스틱서치로 보내는 역할을 한다.

호스트의 logs 폴더와 컨테이너 /usr/share/logstash/logs 폴더를 연결하는 것이다.

스프링이 JSON로그를 logs/app.log로 자동 생성시키면, 로그스태시가 그 파일을 읽게 하기 위해서 컨테이너 안에
/usr/share/logstash/logs  경로에서 app.log를 읽는다.

즉, 스프링 로그 파일을 로그스태시가 가져올 수 있도록 연결하는 것이다.

따라서 마찬가지로 docker-compose파일과 동일선상에 logs폴더가 있어야한다.

 


앞서 로그스태시는 /usr/share/logstash/pipeline 폴더안의 모든 .conf파일(설정파일)을 자동 실행한다고 말했다.

그리고 그 폴더는 내 컴퓨터의 pipeline폴더와 연결되어있어 pipeline폴더도 만들어 놓았다.

그러면 그 안의 설정파일도 작성해서 넣어야한다.

logstash.conf라는 이름으로 파일을 만들고 아래 내용을 복붙한다.

input {
  file {
    # 컨테이너 내부에서 바라보는 로그 파일 경로
    path => "/usr/share/logstash/logs/app.log"
    # 컨테이너 실행 후 파일 처음부터 읽을지 여부
    start_position => "beginning"
    # JSON 포맷 로그를 그대로 읽어들이도록 설정
    codec => "json"
    # 파일이 새로 생겨도 계속 추적하도록
    sincedb_path => "/dev/null"
  }
}

filter {
  # 원하는 경우 로그에 추가 필드 삽입 가능 (선택)
  mutate {
    add_field => { "log_source" => "spring-app" }
  }
}

output {
  # Elasticsearch로 전송
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    user  => "elastic"
    password => "fZYZO-xLXq8dHwBDInBY"
    index => "user-actions-%{+YYYY.MM.dd}"   # 날짜별 인덱스 생성
  }

  # 디버깅 용도: Logstash stdout에도 출력
  stdout { codec => rubydebug }
}

 

로그스태시는 ELK에서 데이터 파이프라인을 맡으면서도, 기본적으로는 ETL 데이터 파이프라인 도구다.

*데이터 파이프라인이란

데이터를 한 곳에서 다른 곳으로 옮기면서 필요한 가동을 하는 과정. 단순히 옮기기만 하는 게 아니라, 중간에 필요한 형태로 바꾸는 작업도 포함됨.

(여기서는 스프링에서 엘라스틱서치로 데이터를 옮기는 파이프라인이다) 

 

* ETL이란? 

ETL은 데이터 파이프라인의 고전적인 3단계를 뜻한다.

Extract(추출) - Transform(변환) - Load(적재)

데이터를 스프링에서 extract해서 원하는 형태로 transform하고 엘라스틱서치에 load한다.

 

그래서 위 설정파일을 보면 전형적인 ETL구조가 드러나있다.

input부분은 app.log파일에서 로그를 extract. 즉 읽어올 수 있도록 설정하는 부분이고,

 

filter부분은 Transform. 데이터를 가공시키도록 설정하는 부분이다.

위 파일에서는 mutate{}를 통해 각 로그마다 "log_source" : "spring-app" 이라는 필드를 추가해서 가공시키는 것이다.

키바나에서 보았을 때 이 로그가 스프링에서 온 앱인것을 알 수 있도록 말이다.

grok {} → 정규식으로 로그 파싱 (ex. Apache/Nginx 로그)

json {} → JSON 문자열 파싱해서 필드 분리

mutate {} → 필드 이름 바꾸기, 값 추가하기

date {} → 문자열을 날짜로 변환

 

output 부분은 Load. 데이터를 최종 목적지로 보내 적재하는 설정이다.

 

elasticsearch {} → Elasticsearch로 전송

file {} → 파일로 저장

stdout {} → 콘솔에 출력

kafka {} → Kafka 토픽으로 전송

 


그러면 설정도 구성했다.

마지막으로 테스트를 위해 logs폴더 아래에 app.log파일을 만들어 아래내용을 복붙한다.

{"timeMillis":1737660000000,"thread":"http-nio-8080-exec-3","level":"INFO","loggerName":"com.sceneconnect.SearchController","message":"{\"userId\":\"user123\",\"action\":\"SEARCH\",\"target\":\"엘라스틱서치\",\"timestamp\":\"2025-09-23T10:00:00\"}"}
{"timeMillis":1737660060000,"thread":"http-nio-8080-exec-5","level":"INFO","loggerName":"com.sceneconnect.JobController","message":"{\"userId\":\"user456\",\"action\":\"CREATE_JOB\",\"target\":\"id:9876\",\"timestamp\":\"2025-09-23T10:01:00\"}"}
{"timeMillis":1737660120000,"thread":"http-nio-8080-exec-7","level":"INFO","loggerName":"com.sceneconnect.LoginController","message":"{\"userId\":\"user789\",\"action\":\"LOGIN\",\"target\":\"/login\",\"timestamp\":\"2025-09-23T10:02:00\"}"}

 

그런다음 이제야 docker-compose logstash로 로그스태시를 설치한다음 바로 실행이 되면 이 로그들이 자동으로 엘라스틱 서치에 적재된다.

그러면 localhost:5601로 들어가 키바나로 확인해보면 

아래처럼 로그데이터가 잘 적재된 것을 확인할 수 있다.

자세히 보면 "log_source" : "spring-app" 까지도 추가된 것도 확인할 수 있다.