Spring 공부하면서 터미널에서 보고 싶지 않아도 항상 보여주고 있다. 에러 공부하면서 로그의 중요성을 크게 느끼지 못하였는데 컨테이너 서비스를 하면서 오토 스케일링 할때 내부 시스템을 문제가 생겼는데 어느 지점에서 문제가 생겼는지 확인할 수 있는 방법이 없었다. 그때 AWS Cloud Watch를 통해 어느 시점에 오류가 생겼는지 로그를 보면서 처리를 할 수 있었고 덕분에 해결할 수 있었다. 이 계기를 통해 로그의 중요성을 알게 되었고 로그 처리 및 데이터 수집의 필요성을 느끼게 되었다. 특히 향후 검색과 관련된 로직을 처리할일이 있기에 ELK 스택을 사용하여 로깅과 검색을 위한 공부를 위해 써본다.
먼저 로깅을 써야하는 이유는 알것같다.
- 로그는 시스템이나 애플리케이션이 예상치 못한 동작을 할 때 그 원인을 추적하는 데 중요한 역할
- 자원 사용 패턴을 파악하여 효율적인 자원 관리
- 로그를 통해 사용자 행동 패턴을 분석하고, 사용자 경험을 개선
- 트렌드 분석, 사용 패턴 분석 등을 통해 데이터 기반의 의사 결정
# docker-compose.yml
version: "3"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
container_name: elasticsearch
environment:
- discovery.type=single-node
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
networks:
- elastic
kibana:
image: docker.elastic.co/kibana/kibana:7.12.1
container_name: kibana
ports:
- "5601:5601"
environment:
ELASTICSEARCH_URL: http://elasticsearch:9200
ELASTICSEARCH_HOSTS: '["http://elasticsearch:9200"]'
depends_on:
- elasticsearch
networks:
- elastic
logstash:
image: docker.elastic.co/logstash/logstash:7.12.1
container_name: logstash
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports:
- "5044:5044"
- "5000:5000/tcp"
- "5000:5000/udp"
- "9600:9600"
networks:
- elastic
depends_on:
- elasticsearch
networks:
elastic:
driver: bridge
volumes:
elasticsearch_data:
driver: local
# logstash/config/logstash.yml
http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline
xpack.monitoring.elasticsearch.hosts: [ "localhost:9200" ]
# logstash/pipline/logstash.conf
input {
tcp{
port => 5000
codec => json
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
index => "springboot-%{app}"
}
}
이후 다음과 같이 elk container가 실행이 된다.
# resources/logback-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>
적용후 스프링 실행시 Logback이 클래스를 인스턴스화하는 데 실패로 다음과 같은 오류 발생
해당 라이브러리 추가
implementation 'net.logstash.logback:logstash-logback-encoder:7.2'
@RestController
@Slf4j
public class HomeController {
@GetMapping("/")
public String HomePage(){
LocalDateTime localDateTime = LocalDateTime.now();
log.info("Welcome home Page " + localDateTime);
return "Welcome to Home page";
}
@GetMapping("/logs")
public String LogsPage(){
LocalDateTime localDateTime = LocalDateTime.now();
log.info("This Logs page " + localDateTime);
return "Welcome to logs page";
}
@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";
}
}