ELK에 대해 간단하게 설명드리고 springboot와 elk stack을 연동해서 springboot 애플리케이션의 log를 수집하고, 검색 및 시각화하는 과정에 대해서 보여드리겠습니다.
ELK Stack
- Logstash
- 다양한 소스(DB)의 로그 또는 트랜잭션 데이터를 수집, 집계, 파싱하여 ES에게 전달
- ElasticSearch
- Logstash로부터 받은 데이터를 검색 및 집계하여 필요한 관심 있는 정보 획득
- Kibana
- Elasticsearch의 빠른 검색을 통해 데이터를 시각화 및 모니터링
우선 elk stack을 연동하기 위해 elk 관련 image를 다운로드 받아야 합니다. (호환성을 위해 elk 버전 일치 시켰습니다)
docker pull elasticsearch:8.3.3
docker pull kibana:8.3.3
docker pull logstash:8.3.3
docker-compose.yml
version: "3"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.3.3
container_name: elastic_springboot
environment:
- bootstrap.memory_lock=true // 하드디스크의 일정 부분을 가져다쓰는 swap 메모리 사용 X
- "ES_JAVA_OPS=-Xms512m -Xmx512m" // JVM heap 메모리 설정
- "discovery.type=single-node" // 단일 노드로 구성
- xpack.security.enabled=false // x-pack 보안 비활성화
ports:
- "9200:9200"
volumes:
- elastic_data:/usr/share/elasticsearch/data // es의 데이터를 저장하기 위한 volume 설정
networks:
- elastic // 하나의 네트워크에서 여러 컨테이너가 실행되도록 networks 지정
kibana:
image: docker.elastic.co/kibana/kibana:8.3.3
container_name: kibana_springboot
ports:
- "5601:5601"
environment:
ELASTICSEARCH_URL: http://elasticsearch:9200 // es와 연결하기 위한 url
ELASTICSEARCH_HOST: '["http://elasticsearch:9200"]' // host 설정
depends_on:
- elasticsearch // es가 실행중일 때만 kibana가 실행되도록 설정
networks:
- elastic // 하나의 네트워크에서 여러 컨테이너가 실행되도록 networks 지정
logstash:
image: docker.elastic.co/logstash/logstash:8.3.3
container_name: logstash_springboot
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports:
- "5000:5000"
environment:
LS_JAVA_OPTS: "-Xmx1024m -Xms1024m"
networks:
- elastic // 하나의 네트워크에서 여러 컨테이너가 실행되도록 networks 지정
depends_on:
- elasticsearch // es가 실행중일 때만 logstash가 실행되도록 설정
networks:
elastic:
driver: bridge // network: bridge(기본 값) 지정, 명시적으로 보이기 위해 작성
volumes:
elastic_data:
driver: local
log를 ES의 기본 데이터 형식인 Json으로 변경하고, elasticsearch에 전송하기 위해 의존성 추가
pom.xml
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.2</version>
</dependency>
logstash-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>localhost:5000</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<mdc />
<context />
<logLevel />
<loggerName />
<pattern>
<pattern>
{
"app": "test-log"
}
</pattern>
</pattern>
<threadName />
<message />
<logstashMarkers />
<stackTrace />
</providers>
</encoder>
</appender>
<root level="info">
<appender-ref ref="logstash" />
</root>
</configuration>
logstash.conf (logstash의 입출력(수, 송신) 지정)
input {
tcp {
port => 5000
codec => json
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
index => "springboot-%{app}"
}
}
Controller.java (Client의 요청시, 간단하게 로그를 출력해 주는 API)
@RestController
@Slf4j
public class Controller {
@GetMapping("/")
public String HomePage() {
LocalDateTime localDateTime = LocalDateTime.now();
log.info("Welcome home Page " + localDateTime);
return "Welcome SpringBoot";
}
@GetMapping("/logs")
public String LogsPage() {
LocalDateTime localDateTime = LocalDateTime.now();
log.info("This Logs page " + localDateTime);
return "Welcome SpringBoot";
}
@GetMapping("/warn")
public String WarnPage() {
LocalDateTime localDateTime = LocalDateTime.now();
log.warn("This warn page " + localDateTime);
return "Welcome to warn page";
}
@GetMapping("/er")
public String ErrorPage() {
LocalDateTime localDateTime = LocalDateTime.now();
log.error("This error page " + localDateTime);
return "Welcome to error page";
}
}
docker-compose up (elk 컨테이너 생성 및 실행)
spring application (build & execute)
프로젝트 build 후, target 폴더 내의 jar 파일 실행
elasticsearch ,kibana 연동 확인(localhost:9200, localhost:5601)
이제 localhost:8080/logs, /warn, /er로 요청을 보내보고, kibana로 요청에 대한 로그를 확인해 보겠습니다.
다음과 같이 logLevel과 Controller에서 작성한 log message를 확인할 수 있게 되었습니다.
'DevOps > Docker' 카테고리의 다른 글
[Docker] Dockerfile을 이용해 SpringApplication 빌드 및 실행 (0) | 2023.09.14 |
---|---|
[Docker] Docker-Compose를 사용하여 Springboot, Mysql 연동 (0) | 2023.08.31 |
[Docker] Docker, Docker-Compose, Dockerfile (0) | 2023.08.31 |
[Docker] Container vs VM (0) | 2023.08.31 |
Docker (0) | 2022.10.04 |