Application Modernization/Observation

Spring Boot 와 ELK (ElasticSearch, Logstash, Kibana)

Cloud Applicaiton Architect 2022. 1. 6. 23:27
반응형

이미 이 블로그를 통해 나는 Microservice Architecture 기반의 응용 프로그램을 설계 할때 고려해야 하는 6가지 영역(API Gateway, Service Mesh, Container Management, Backing Service, Telemetry, CI/CD)에 대해 언급한 적이 있다. 

 

Microservice Architecture 컴포넌트

Microservice Architecture를 구성하는데 필요한 각각의 필요 요소들에 대해 이를 그룹화 하고 잘 정리한 자료를 찾는 것은 쉽지 않다. 사실 이 분야 전문가는 Gartner라고 생각하고 있고 그 분야의 전문

sharplee7.tistory.com

 

이 6개 영역 중 Telemetry 혹은 Observation 이란 영역은 '로깅(Logging)', '모니터링(Monitoring)', '트레이싱(Tracing)'을 담당 하며 각 기능은 다음과 같다

  • 로깅(Logging) : 여러개로 분리된 서비스에서 생성되는 분산된 로그 파일에 대한 중앙화, 집중화 방안
  • 모니터링(Monitoring) : 다중화된 서비스에 대한 모니터링 방안
  • 트레이싱(Tracing) : 클라이언트의 단일 요청에 대해 마이크로서비스간 다중 호출 관계가 있을때 이에 대한 추적 방안

여번 포스팅에서는 마이크로서비스 아키텍처를 구성할때 가장 많이 사용하는 로깅 방법 중 하나인 ELK(ElasticSearch, Logstash, Kibana)를 이용한 로깅 방식에 대해 알아보도록 한다.

 

ELK를 이용한 로깅 구성

마이크로서비스 아키텍처에서 가장 많이 사용하는 로깅 방식으로는 ELK 와 EFK가 있으며 ELK는 Elasticsearch, Logstash, Kibana로 구성되고 EFK는 Elasticsearch, Fluentd, Kibana로 로깅을 구성한다.

 

ELK의 각 솔루션별 기능을 보면 logstash를 통해 데이터를 집계하고 처리한 다음 elasticsearch를 통해 원하는 데이터 항목을 인덱싱하고 저장하고 kibana를 통해 이렇게 인덱싱된 데이터를 보여주는(Visualization) 구조를 가진다.

아래의 그림을 통해 이해를 조금 쉽게 이해를 해보도록 하자.

위 그림을 보면 ELK이외 beats라는 추가 솔루션이 보인다. beats는 경량의 데이터 수집용 솔루션으로 데이터 수집을 위해 다양한 제품들로 구성되어 있다.

우리는 이번 포스팅에서 spring boot의 access log 파일로부터 데이터를 수집해 이를 kibana를 통해 검색하는 방법을 알아볼 예정이기 때문에 이번 포스팅에서는 filebeat만 다룰 예정이다.

 

Beats + ELK로 구성할 수 있는 다양한 아키텍처

 

예제 시나리오 및 아키텍처 구성

ELK를 테스트하는 시나리오는 /hello/{name}과 /goodbye/{name} 두개의 URI를 가지고 있는 간단한 Spring Boot 어플리케이션이 자동으로 생성하는 access_log 파일에 대해 filebeat가 로그 데이터를 수집해 키바나를 통해 로그 내용을 볼수 있는 간단한 내용이다.

 

 

그 아키텍처는 다음과 같다.

 

  1. 테스트에 사용하는 Spring Boot 앱은 Spring Boot Home 디렉토리 아래 /logs라는 디렉토리가 있으며 이 디렉토리에 access_log 파일이 생성된다.
  2. 설치된 filebeat는 spring boot의 /logs/ 디렉토리 아래 있는 모든 로그파일들을 대상으로 데이터를 수집한다.
  3. filebeat가 수집한 로그데이터의 처리를 위해 logstash로 데이터를 보낸다.
  4. logstash에서 filebeat에서 보내는 데이터를 받을 포트를 지정한다. (3에서 지정한 포트 번호와 동일해야 한다.)
  5. logstash에서 elasticsearch에서 사용할 index 및 기타 필요한 전처리 작업들을 수행한다.
  6. elasticsearch는 logstash에서 보낸 데이터를 인덱싱해 저장한다.
  7. kibana를 통해 elasticsearch에서 보낸 데이터를 검색하거나 시각화 시킨다.
  8. 이 테스트에서 서로 다른 버전의 filebeat, logstash, elasticsearch, kibana를 사용함으로써 발생하는 문제 해결을 위해 docker container를 이용했으며(버전 맞추기가 쉽다) 서로간의 통신 문제를 없애기 위해 동일 네트워크를 사용했다.

 

Spring Boot 응용프로그램 작성

이 테스트에서 사용할 Spring Boot 응용 프로그램의 소스는 다음과 같다.

package com.example.tomcatlog;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class TomcatLogApplication {

   public static void main(String[] args) {
      SpringApplication.run(TomcatLogApplication.class, args);
   }

   @GetMapping("/hello/{name}")
   public String sayHello(@PathVariable String name) {
      return "Hello " + name;
   }

   @GetMapping("/goodbye/{name}")
   public String sayGoodBye(@PathVariable String name) {
      return "Good bye " + name;
   }
}

access_log 파일 생성을 위해 application.properties를 다음과 같이 작성하도록 하자

server.tomcat.accesslog.enabled=true
server.tomcat.basedir=.
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.prefix=access_log
server.tomcat.accesslog.file-date-format=.yyyy-MM-dd
#server.tomcat.accesslog.pattern=common
server.tomcat.accesslog.pattern=%{yyyy-MM-dd HH:mm:ss}t %s %r %{User-Agent}i %{Referer}i %a %b

작성이 귀찮다면 아래의 git 을 clone해 사용하도록 한다.

https://github.com/sharplee7/tomcat-log.git

 

 

Docker를 이용한 filebeat 7.6.2 설치

2021년부터 elasticsearch의 라이선스 정책이 변경되어 7.11 이후 버전은 상용 라이선스를 구입해야 한다.

docker pull docker.elastic.co/beats/filebeat:7.6.2

 

Docker를 이용한 logstash 7.6.2 설치

docker pull docker.elastic.co/logstash/logstash:7.6.2

 

Docker를 이용한 elasticsearch 7.6.2 설치

docker pull docker.elastic.co/elasticsearch/elasticsearch:7.6.2

 

Docker를 이용한 kibana 7.6.2 설치

docker pull docker.elastic.co/kibana/kibana:7.6.2

 

filebeat.yml 파일 작성

filebeat.yml 파일을 docker 외부에 위치시킴으로써 filebeat설정을 용이하게 할수 있다.

이 예에선 $HOME/workspace/telemetry/filebeat라는 디렉토리를 만들고 거기에 filebeat.yml 파일을 만들었다.(각자의 환경에 맞게 작성할 것)

 

filebeat.inputs:
- type: log
  enabled: true
  paths:
  - /logs/*.log

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



logstash.conf 파일 작성

logstash.conf 파일을 docker 외부에 위치시킴으로써 logstash 설정을 용히하게 할 수 있다.

이 예에선 $HOME/workspace/telemetry/logstash 아래에 logstash.conf 파일을 만들도록 한다.

input {
 beats {
  # filebeat 데이터 입력 포트
  port => 5044
 }
}

output {
 elasticsearch {
  hosts => ["elasticsearch:9200"]
  user => elastic #기본 사용자
  password => changeme #기본 사용자 패스워드
  manage_template => false
  index => "access-log" #DB의 데이터베이스 명
  document_type => "log" #DB의 테이블 명
 }
}

 

filebeat, logstash, elasticsearch, kibana 가 서로 식별 될기 위한 docker network 생성

이 테스트에선 elk라는 이름의 docker network를 만들기로 한다.

docker network create elk

다음의 명령어로 생선된 네트워크(elk)를 확인한다.

docker network ls 

 

elk 네트워크에 filebeat 컨테이너 생성 및 실행

다음의 명령어를 실행해 elk네트워크에 filebeat container를 생성하고 실행한다.

 

docker run -d --name filebeat --network elk -v "/Users/euideoklee/workspace/telemetry/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml" -v  "/Users/euideoklee/java-dev/workspace/tomcat-log/logs:/logs" docker.elastic.co/beats/filebeat:7.6.2

 

  • 이때 -v 옵션의 경우 : 를 중심으로 왼쪽은 컨테이너 외부(로컬 서버)의 물리적 디렉토리 위치이고 왼쪽은 컨테이너 내부의 디렉토리 위치이다.

 

elk 네트워크에 logstash 컨테이너 생성 및 실행

다음의 명령어를 실행해 elk네트워크에 logstash container를 생성하고 실행한다.

docker run -d --name logstash --network elk -p 5044:5044 -v "/Users/euideoklee/workspace/telemetry/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf" docker.elastic.co/logstash/logstash:7.6.2

 

elk네트워크에 elastcisearch 컨테이너 생성 및 실행

다음의 명령어를 실행해 elk네트워크에 elasticsearch container를 생성하고 실행한다.

docker run -d --network=elk --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.6.2

 

elk네트워크에 kibana 컨테이너 생성 및 실행

다음의 명령어를 실행해 elk네트워크에 kibana container를 생성하고 실행한다.

docker run -d --network=elk --name kibana -p 5601:5601 docker.elastic.co/kibana/kibana:7.6.2

 

kibana 호출을 통한 로그 수집 데이터 조회

웹브라우저를 통해 localhost:5601을 접속한다.

 

Visualize and Explorer Data 항목 중 Discover를 클릭한다.

Discover는 별다른 조작없이 KQL(Kibana Query Language)를 통해 로그 데이터를 쿼리 할 수 있다.

 

초기 클릭을하면 아직 익덱싱이 완료되지 않아 아무런 데이터도 표시되지 않는다.

 

시간이 조금 흐른 뒤 익덱싱이 완료되면 아래와 같이 우리가 만든 logstash에서 만든 인덱스(access-log)를 볼수 있다.

 

이제 시각화 작업을 해보자

Kibana의 왼쪽 메뉴에서 Visualize를 찾아 선택한다.

Create new visualization 버튼을 클릭한다.

여기서는 Query로 로그를 조회할 예정이기 때문에 Data Table을 선택한다.

 

어떤 인덱스로 Data Table을 만들건지 묻는 질문에 생선된 인덱스인 access-log를 선택한다.

 

Search 란에 *를 입력하고 날짜에는 Today를 찾아 선택한다.(오늘 날짜의 모든 데이터) Reflesh를 클릭해 조회된 데이터가 카운트에 표시되는지 확인한다.

정상적으로 생성되었다면 이제 좌측 메뉴의 Discover를 선택해 실제 데이터를 눈으로 보도록 하자

 

KQL(Kibana Query Language)를 통해 다양한 조건의 데이터만 선별해 조회할 수 있다.

 

이번 포스팅은 여기까지가 끝~

반응형