스타트업 ELK 스택 적용기

ELK 스택 으로 Spring boot & nginx 서버 로그를 모니터링 해보자

Omnipede
CPLABS-TECH
10 min readJan 27, 2021

--

이 글을 쓰게 된 계기

필자는 현재 코인플러그 서버 개발팀에서 개발 업무를 맡고 있다. 우리 팀은 평소 서버 로그를 확인할 때 ssh 터미널로 서버에 접속하여 로그를 확인했다. 검정 바탕에 흰 글씨가 가득한 터미널 뷰는 가독성이 좋지 않았다. 만약 로그를 검색 하려고 하면 다음과 같이

$ cat LOGFILE.log | grep ERROR

명령어를 일일이 입력해서 원하는 내용을 찾아야 했고 로그 파일을 확인하는 개발자 및 운영자를 불편하게 했다.

터미널로 확인한 로그 예시

로그 파일을 확인하는 것이 불편하다 보니 중요한 로그를 놓치거나 간혹 로그를 잘못 해석하는 경우가 종종 발생했다.

이런 상황을 막기 위해서는 로그 모니터링 시스템이 필요해 보였다.

주변에 알아보니 스타트업 에서는 주로 ELK 스택을 사용하여 로그를 모니터링 한다고 했다. 이번 기회에 우리 팀도 로그 모니터링 시스템을 적용해 보는 게 좋을 것 같아 PoC 느낌으로 ELK 스택을 적용해 보고, 적용 과정을 정리하기 위해 이 글을 작성하게 되었다.

ELK 스택이란

ELK 스택이란 Elasticsearch, Logstash, kibana 세 가지를 일컫는 기술 스택이다.

  • Elasticsearch (E): 검색 및 분석 엔진.
  • Logstash (L): 여러 로그 파일을 수집하여 변환한 후 Elasticsearch 로 전송하는 파이프라인.
  • Kibana (K): elastic search 에 저장된 데이터를 시각화 시켜주는 툴.
ELK 스택 구조도

간단히 정리하면 서버가 발생시킨 로그를 Logstash 가 모아서 Elasticsearch 로 보내고 Elasticsearch 가 로그를 검색하기 쉽게 잘 정리해서 Kibana 에게 보내면 Kibana 가 정리된 로그를 GUI 로 시각화하여 사용자에게 보여 준다고 할 수 있다.

ELK 스택 설치 방법

Docker-compose

설치 과정을 단순화 하기 위해 Elasticsearch, Logstash, Kibana 를 docker-compose 를 사용해서 한번에 설치하자. 필요한 docker-compose 파일은 아래와 같다.

docker-compose.yaml

그리고 설정 파일 두 가지가 필요하다.

kibana.yml

kibana.yml 은 Elasticsearch 와 Kibana 를 연결할 때 필요한 설정파일이다. 이 파일에는 접속할 Elasticsearch 의 주소와 Elasticsearch 에 접속할 때 필요한 ID, PW 가 적혀있다.

Kibana와 Elasticsearch 를 연결할 때 필요한 kibana.yml 파일

logstash.conf

logstash.conf 는 Logstash 의 입력과 출력을 정의한 설정파일이다.

Logstash 는 다양한 종류 소스로부터 입력을 받을 수 있다. 파일을 받을 수도 있고 일반 키보드 입력 (stdin) 을 받을 수도 있다. 여기서는 단순하게 tcp 입력을 받는다고 가정하고 input 영역에 tcp 포트와 JSON 코덱을 정의했다.

Logstash 는 로그를 받아서 Elasticsearch 에게 전달해야 하므로 output 에 Elasticsearch 주소와 접속정보, 그리고 로그가 저장될 Elasticsearch index 이름을 넣었다.

Logstash 입출력을 정의한 logstash.conf 파일

설정이 완료되었다면 docker-compose.yaml, kibana.yml, logstash.conf 파일을 다음과 같이 배치하자.

|_ docker-compose.yaml
|_ kibana
|_ config
|_ kibana.yml
|_ logstash
|_ pipeline
|_ logstash.conf

이후 다음 명령어를 입력하여 ELK 스택을 설치하고 실행해주자.

$ docker-compose up

그리고 http://localhost:5601 로 접속하고 Elasticsearch 아이디와 비밀번호 를 입력후 이런 화면이 보이면 성공이다.

Kibana 메인 페이지

모니터링 예시

ELK 스택 설치가 끝났으니 이제 실제로 서버 로그를 발생시키고, 해당 로그를 ELK 스택으로 전달하여 모니터링을 해보자.

우리 팀은 리버스 프록시 서버로 nginx 를 사용하고, WAS 서버로 주로 스프링 부트 를 사용하기 때문에 스프링 부트 서버와 nginx 서버를 모니터링 해보겠다.

스프링 부트 서버 로그 모니터링 예시

우선, 로그를 발생시킬 샘플 서버가 필요하기 때문에 다음과 같이 간단한 서버를 만들었다.

간단한 샘플 서버 코드

위 서버는 GET /api/v1/hello/{value} 요청이 들어오면 “Hello world ” 와value 를 연결한 문자열을 반환하는 간단한 http 서버다. 중간 중간 로그를 남기고, 의도적으로 에러 로그를 남기기 위해 들어오는 value 값이 100 보다 크면 RuntimeException 을 발생시키고 있다.

요청이 들어오면 로그는 이렇게 남을 것이다.

로그 샘플

로그가 발생했으니 발생한 로그를 ELK 스택으로 보내보자. Logback 을 이용하면 간단하게 스프링 부트 로그를 Logstash 로 보낼 수 있다. 먼저 Logstash logback encoder 를 추가해야 한다.

빌드 도구로 maven 을 사용하면 이렇게 추가하고

<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.11</version>
</dependency>

gradle 을 사용하면 이렇게 추가하자.

compile group: ‘net.logstash.logback’, name: ‘logstash-logback-encoder’, version: ‘4.11’

그리고 다음 logback-spring.xml 파일을 src.main.resources 에 추가해주자.

Logstash loback encoder 를 적용한 Logback 설정 파일

스프링 부트 서버를 재 시동 후 로그를 발생시키고 Kibana 의 Discover 페이지에 들어가면 로그를 모니터링 할 수 있다.

왼쪽의 Available fields 에서 모니터링 할 필드를 선택 할 수도 있다. 로그 레벨과 로그 메시지, logger name 정도만 남겨보자.

보고 싶은 필드만 모니터링 할 수 있다.

또한 위쪽의 Search 입력란에 검색 조건을 입력해서 로그를 검색할 수도 있다. 에러 로그만 검색해보자.

level:ERROR 로 검색하고 stack trace 를 추가로 선택한 결과

스프링 부트 서버 로그 모니터링 예시: 커스텀 필드 모니터링

앞선 예시에서는 log level, logger name , log message 등 Logstash logback encoder 가 사전에 정의한 필드만 모니터링 할 수 있었다. 반면 사용자가 지정한 값을 모니터링 하려면 어떻게 해야 될까? 예를 들어서 스프링 부트 샘플 서버에게 HTTP 요청으로 들어오는 value 변화 추이를 지켜 보려고 한다면?

Logstash Logback encoder 가 제공하는 커스텀 필드 기능을 사용하면 사용자가 직접 모니터링 할 값을 지정해줄 수 있다.

샘플 서버에게 요청으로 들어오는 value 를 모니터링 하고 싶다면 다음과 같이 한 줄만 추가하면 된다.

Value 를 로깅 하는 구문이 추가된 샘플 서버 코드

“HERE!” 라고 표시한 곳 밑의 코드가 커스텀 필드를 로깅 하는 코드다. 위 코드 상에서는 정수 값만 로깅 하고 있지만 정수 뿐 아니라 Map, String, Object 등 로깅 할 수 있는 타입은 다양하다.

커스텀 필드를 로깅 하는 다양한 방법은 링크 를 참조해보면 좋을 것 같다.

이제 샘플 서버를 재 시작 하고 HTTP 요청을 몇 개 날려서 로그를 발생 시켜 보자. Kibana 의 discover 페이지의 왼편 Available fieldsvalue 필드 가 생길 것이고 value 를 선택하면 value 를 중점적으로 모니터링 할 수 있다.

요청으로 들어온 value 값을 모니터링 하는 모습

이렇게 value 필드를 모니터링 했을 때 좋은 점은 검색이 용이하다는 점이다. value>50 로 조건을 걸고 검색하면 조건에 부합하는 로그를 찾을 수 있다.

value 가 50 보다 큰 로그를 검색 한 결과

nginx 서버 로그 모니터링 예시

Nginx 서버 로그를 ELK 스택으로 보내는 방법은

Kibana Home 화면 > Add data > Logs > Nginx logs 에 자세히 나와있다. (Kibana 버전에 따라 위치는 조금씩 다를 수 있다. 이 글에서는 7.10.1 사용)

nginx 로그 모니터링 가이드 위치
Kibana 에서 확인할 수 있는 nginx log 모니터링 가이드

기본적으로 Kibana 가 제공하는 가이드를 쭉 따르면 된다. 이 과정에서 filebeat.yml 은 이렇게 작성 하고

output.elasticsearch: 
hosts: [“localhost:9200”]
username: “elastic”
password: “MyPw123”
setup.kibana:
host: “http://localhost:5601”

modules.d/nginx.yml 은 이렇게 작성 하면 된다.

단, access.var.paths 에는 실제 nginx access log 경로를 넣고 error.var.paths 에는 실제 nginx error log 경로를 넣어야 하는 점에 주의.

Kibana discover 페이지에서 왼쪽 상단의 index pattern 을 filebeat* 로 맞추면 이제 nginx 로그를 모니터링 할 수 있다.

nginx access log monitoring

마치며

지금까지 로그 모니터링 기능을 간략하게 적용해보았습니다.

이번에는 Elasticsearch 노드를 하나만 사용했는데, 만약 모니터링 해야 할 로그의 양이 많아지면 여러 개의 Elaisticsearch 노드를 clustering 하여 부하를 분산할 필요가 있을 것 같습니다.

글 읽어주셔서 감사합니다. 관련하여 의견이 있거나, 이슈가 발생했다면 아래 연락처로 공유 부탁드립니다.

  • 이메일 : contact@coinplug.com

참고 자료

--

--