여러분이 성공적인 서비스를 만들어 서버가 50대로 늘어났습니다. 어느 날 밤, 고객센터에서 "결제가 자꾸 실패한다고 고객 클레임이 들어옵니다!"라는 다급한 연락이 옵니다. 초보 개발자는 리눅스(Linux) 터미널을 열고 1번 서버에 접속해 tail -f /var/log/spring.log를 치고 한참 찾다가 없으면 2번 서버에 들어가서 또 찾습니다. 50대의 서버를 일일이 돌아다니며 에러 로그를 찾는 사이에 고객은 다 떠나고 회사는 망할 것입니다. 수십 대의 서버에서 각자 뿜어내는 수 기가바이트(GB)의 텍스트 로그 파일들을 한 곳으로 빨아들여서, "결제 에러"라는 키워드 하나만 치면 구글처럼 0.1초 만에 50대 서버 전체의 에러 로그를 찾아주고 삐까뻔쩍한 대시보드로 시각화해 주는 인프라는 없을까요? 있습니다. 바로 전 세계 IT 기업의 99%가 사용하는 표준 로깅 파이프라인, ELK(Elasticsearch, Logstash, Kibana) 스택입니다.
이번 [Spring Boot 실무 완벽 가이드] 시리즈에서는 "로깅 노가다의 종식!" Spring Boot와 ELK 스택 연동 아키텍처에 대하여 다뤄보겠습니다.

🧩 1. ELK 스택의 3형제 역할 분담
ELK는 세 가지 오픈소스 소프트웨어의 앞 글자를 딴 것입니다. 데이터(로그)가 흘러가는 순서대로 역할을 이해해 봅시다.

- L (Logstash): 수집 및 정제 담당입니다. 각 서버에 심어진 에이전트(Filebeat 등)가 스프링 부트의
.log파일을 읽어서 Logstash로 쏘면, Logstash는 "음, 이건 INFO 로그고 이건 ERROR 로그네. 날짜는 이거고..."라며 지저분한 문자열을 깔끔한 JSON 형태로 정제(Parsing)합니다. - E (Elasticsearch): 저장 및 검색 담당입니다. 이전 35단계에서 배웠던 바로 그 초고속 검색 엔진입니다. Logstash가 예쁘게 정제해서 넘겨준 로그 JSON 덩어리들을 역인덱스(Inverted Index)로 저장합니다.
- K (Kibana): 시각화 화면(UI) 담당입니다. 개발자가 브라우저로 Kibana에 접속해 "error"라고 검색하면, 내부적으로 Elasticsearch에 쿼리를 날려 결과를 가져오고 이를 예쁜 그래프나 표로 그려줍니다.
⚙️ 2. Spring Boot Logback을 ELK에 직결하기
파일(Filebeat)로 로그를 남긴 다음 긁어가는 것이 정석이지만, 작은 프로젝트에서는 스프링 부트의 logback-spring.xml 설정만으로 로그를 Logstash 서버로 직접(TCP/UDP) 쏴버릴 수도 있습니다. logstash-logback-encoder 라이브러리를 사용합니다.
<!-- logback-spring.xml: 콘솔이나 파일 대신 Logstash 서버로 쏘는 어펜더(Appender) -->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!-- Logstash 서버의 IP와 포트 (보통 5000번) -->
<destination>192.168.1.100:5000</destination>
<!-- 로그를 JSON 형태로 예쁘게 바꿔서 날려줍니다! -->
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"app_name":"my-shopping-mall"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="LOGSTASH" />
</root>
🚨 3. 실무 아키텍처: Logstash가 죽으면 로그가 다 날아간다?
위 방식은 아주 편하지만 치명적인 단점이 있습니다. 스프링 부트가 Logstash로 로그를 쏘고 있는데, Logstash 서버가 잠시 다운되거나 네트워크가 끊기면 어떻게 될까요? 그 시간 동안 발생한 중요한 에러 로그는 영영 증발해 버립니다!
그래서 대규모 실무(네이버, 카카오 등) 환경에서는 Spring Boot와 Logstash 사이에 '버퍼(Buffer)' 역할을 하는 Apache Kafka(카프카)나 Redis를 반드시 중간에 끼워 넣습니다. 스프링 부트는 무조건 Kafka에 로그를 던지고 끝냅니다(Kafka는 절대 죽지 않는 분산 큐입니다). 그러면 Logstash는 Kafka에 쌓여있는 로그를 자기 페이스(속도)에 맞게 천천히 가져가서 Elasticsearch에 넣습니다. 이렇게 구성해야 트래픽이 폭주해도 로그 유실(Loss)률 0%를 달성할 수 있습니다.
🎯 4. 마무리 및 다음 단계
지금까지 수십 대의 서버를 돌며 에러를 찾던 끔찍한 삽질을 끝내고, 모든 서버의 로그를 단일 검색창(Kibana)에서 초고속으로 조회하게 해주는 현대 인프라의 마법, ELK 스택 파이프라인의 원리와 실무 아키텍처(Kafka 버퍼링)에 대해 상세히 다루어 보았습니다. 이제 모니터링 모니터 하나를 통째로 Kibana 대시보드로 띄워두는 '진짜 백엔드 팀'이 되셨습니다.
우리의 서비스가 거대해지면서, 회원(Auth), 상품(Product), 주문(Order), 배송(Delivery) 기능이 4개의 각각 다른 서버(스프링 부트 앱 4개)로 쪼개졌습니다. 이것이 바로 마이크로서비스 아키텍처(MSA)입니다. 그런데 프론트엔드(React, iOS) 개발자가 화를 냅니다. "API 주소가 4개나 돼서 호출하기 너무 힘들어! 도메인(URL) 하나로 통일해 주고, 네가 알아서 서버 4개로 찢어 보내주면 안 돼?" 이어지는 37단계 포스팅에서는 "수많은 마이크로서비스 앞을 막아선 거대한 단일 진입점(문지기)!" MSA 아키텍처의 필수 관문, Spring Cloud Gateway의 라우팅과 글로벌 필터링(JWT 인증) 비법에 대해 아주 뼈 때리게 파헤쳐 보겠습니다!
'Framework > Spring Boot' 카테고리의 다른 글
| [Spring Boot] Eureka 서비스 디스커버리 (0) | 2026.08.05 |
|---|---|
| [Spring Boot] Spring Cloud Gateway (0) | 2026.08.05 |
| [Spring Boot] Elasticsearch 연동: RDB의 LIKE 검색 한계를 부수다 (0) | 2026.08.05 |
| [Spring Boot] Spring Batch Chunk 지향 처리: 1,000만 건 메모리 최적화의 꽃 (0) | 2026.08.05 |
| [Spring Boot] Spring Batch 입문: 1,000만 건의 데이터를 씹어 삼키다 (0) | 2026.08.05 |