우아한테크코스/레벨4, 레벨5
[팀 프로젝트] GM 로그 관리를 위한 ELK Stack 설정 방법 문서화
nauni
2021. 9. 27. 23:05
Elastic Stack
- ELK: Elasticsearch, Logstash, Kibana
- Elasticsearch: 검색 및 분석엔진
- Logstash: 서버 사이드 데이터 처리 파이프라인, 여러 소스의 데이터를 수집하여 변환한 뒤 elasticsearch 에 전송
- Kibana: Elasticsearch 의 내용을 차트와 그래프를 이용해 데이터를 시각화
- Beats: 경량의 단일 목적 데이터 수집기 제품군
- Elastic Stack: EKL + Beat
우리 서비스 ELK Stack 구성
- ElasticSeach, Logstash, Kibana는 docker-elk 레포지토리를 참고하여 설정
- 각각의 GM 서버에는 로그 정보를 Logstash에 전달하는 filebeat를 설치
FileBeat
- 로그가 있는 서버에 설치
- Beats 의 제품군에는 여러가지가 존재하는데 그 중 로그파일 전용이 Filebeat
filebeat.inputs:
- type: log
# 도커 컨터이너로부터 쌓이는 로그의 경로 설정
paths:
- '/var/lib/docker/containers/*/*.log'
# docker 의 로그는 json 형태로 쌓이는데 json.message_key 는 해당 key 에 해당하는 정보를 위로 올려준다.
json.keys_under_root: true
json.overwrite_keys: true
json.add_error_key: true
json.expand_keys: true
json.message_key: log
# 로그를 한줄한줄이 아닌 원하는 패턴의 단위로 묶어서 보내줄 수 있다.
multiline.type: pattern
multiline.pattern: '^Epoch'
multiline.negate: true
multiline.match: after
# default 는 5초로 셋팅되어 있다. 묶어주는 로그 단위가 크면 중간에 의도한대로 나오지 않고 짤렸기 때문에 늘려주었다.
multiline.timeout: 30
output.logstash:
hosts: [${로그스태시의 호스트 IP:PORT}]
Logstash 설정
- filebeat 에서 로그를 받아 filter 로 분석하기
input {
beats {
port => Logstash에서 열어준 포트번호(default:5044)
}
}
filter {
# backspace 제거: 정형화된 로그가 아니다 보니 \b 부분이 문제가 되었는데 없애줌
mutate {
gsub => ["log","[\b]", ""]
}
# grok 을 사용하여 원하는 방식대로 로그를 filter
# grok 문법을 사용하며, log 필드에 들어온 값을 정규표현식과 비슷하게 파싱하여 json 형태로 보내준다.
# %{해당패턴:필드로_묶을_이름:자료형} -> 필드로 묶을 이름을 지정하지 않으면 해당패턴 명으로 묶인다.
grok {
match => {"log" => ["Epoch %{NUMBER:currentEpoch:int}\/%{NUMBER:totalEpoch:int}
%{GREEDYDATA}- loss: %{NUMBER:loss:float} - accuracy: %{NUMBER:accuracy:float}"] }
}
# jobId를 태그로 관리: [] 방식으로 json 경로의 key 접근가능
mutate {
rename => {"[attrs][tag]" => "jobId"}
}
}
output {
elasticsearch {
hosts => 엘라스틱 포트
# .. 각종 설정정보 넣어줌 ..
# index 는 job 으로 클러스터링
index => "job"
}
}
Kibana
- kibana 는 elastic 에서 API 를 통해 봐야하는 로그정보들을 쉽게 시각화 해줌 (개발하며 로그 시각화 및 모니터링이 가능)
- 우리 서비스에서 kibana 를 사용하여 로그를 시각화 하지는 않았고, 프론트엔드 팀원들이 시각화를 진행
ElasticSearch
- SpringBoot 를 사용한다면 의존성 추가로 쉽게 적용이 가능하다.
- gradle 설정에서
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
를 추가 - Java 에서 Repository 처럼 쉽게 사용이 가능하다.
- Config 설정을 해준다.
@Configuration
public class ElasticClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(host)
.withBasicAuth(userName, password)
.build();
return RestClients.create(clientConfiguration).rest();
}
}
- ElasticsearchRepository 를 상속받아 Repository 처럼 사용가능하다.
public interface LogRepository extends ElasticsearchRepository<Log, String> {
List<Log> findByJobIdOrderByTime(Long jobId);
}
docker-compose.yml 설정
elk docker 설치 참고 레포짓토리의 설정 파일을 우리 환경에 맞게 수정을 진행했다.
version: '3.2'
services:
elasticsearch:
build:
context: elasticsearch/
args:
ELK_VERSION: $ELK_VERSION
volumes:
- type: bind
source: ./elasticsearch/config/elasticsearch.yml
target: /usr/share/elasticsearch/config/elasticsearch.yml
read_only: true
- type: volume
source: elasticsearch
target: /usr/share/elasticsearch/data
ports:
# EC2 인바운드 규칙으로 9000번 포트로 수정
- "9000:9200"
- "9300:9300"
environment:
# OOM 에러를 해결하기 위해 메모리 크기 수정
ES_JAVA_OPTS: "-Xmx1g -Xms1g"
ELASTIC_PASSWORD: password
discovery.type: single-node
networks:
- elk
logstash:
build:
context: logstash/
args:
ELK_VERSION: $ELK_VERSION
volumes:
- type: bind
source: ./logstash/config/logstash.yml
target: /usr/share/logstash/config/logstash.yml
read_only: true
- type: bind
source: ./logstash/pipeline
target: /usr/share/logstash/pipeline
read_only: true
ports:
# EC2 인바운드 규칙으로 8000번 포트로 수정
- "8000:5044"
- "5000:5000/tcp"
- "5000:5000/udp"
- "9600:9600"
environment:
# OOM 에러를 해결하기 위해 메모리 크기 수정
LS_JAVA_OPTS: "-Xmx1g -Xms1g"
networks:
- elk
depends_on:
- elasticsearch
kibana:
build:
context: kibana/
args:
ELK_VERSION: $ELK_VERSION
volumes:
- type: bind
source: ./kibana/config/kibana.yml
target: /usr/share/kibana/config/kibana.yml
read_only: true
ports:
# EC2 인바운드 규칙으로 8080번 포트로 수정
- "8080:5601"
networks:
- elk
depends_on:
- elasticsearch
networks:
elk:
driver: bridge
volumes:
elasticsearch:
참고
- 완태와 공동작성된 글입니다.
- what is elk
- elk docker 설치
- filebeat multiline
- spring-data docs elasticsearch