앞선 포스팅들을 통해 견고한 백엔드 시스템을 설계하고 예외를 처리하는 방법까지 마스터했습니다. 이제 마지막 퍼즐인 ‘운영(Operation)’ 단계로 넘어갈 차례입니다.
서버는 24시간 돌아가지만, 개발자가 24시간 모니터를 보고 있을 수는 없습니다. 서버가 언제 아팠는지, 어디서 에러가 터졌는지 기록을 남기고(Logging), 심각한 문제가 발생하면 자고 있는 개발자를 깨워야(Alerting) 합니다.
Spring Boot Logback 설정 완벽 가이드: 프로파일별 전략과 Slack 알림 연동
1. 서론
“로그(Log)는 서버의 블랙박스입니다.”
비행기 사고가 나면 가장 먼저 블랙박스를 찾듯, 서버에 장애가 발생했을 때 개발자가 가장 먼저 찾아야 하는 것은 로그 파일입니다. 하지만 아직도 많은 초급 개발자들이 System.out.println()을 사용하여 로그를 찍곤 합니다. 이는 성능을 심각하게 저하시킬 뿐만 아니라, 로그 레벨 관리나 파일 저장이 불가능하여 운영 환경에서는 절대 사용해서는 안 되는 방식입니다.
스프링 부트는 기본적으로 Logback이라는 강력한 로깅 프레임워크를 내장하고 있습니다. 이를 제대로 설정하기만 해도 개발 환경에서는 디버깅을 쉽게 하고, 운영 환경에서는 디스크 용량을 관리하며 중요한 에러를 놓치지 않을 수 있습니다. 더 나아가 슬랙(Slack)과 연동하면 장애 발생 시 즉각적인 알림을 받아 ‘골든 타임’을 지킬 수 있습니다. 오늘은 실무에서 사용하는 환경별(Profile) 로그 전략과 Slack 에러 알림 연동까지, A to Z를 완벽하게 정리해 드리겠습니다.
2. 본론
1: 환경별(Dev vs Prod) 로그 전략 수립
로그 설정의 핵심은 “환경에 따라 다르게 동작해야 한다”는 것입니다. 개발할 때 필요한 정보와 운영할 때 필요한 정보는 다르기 때문입니다.
1. 로컬 및 개발 환경 (Local/Dev)
- 목표: 최대한 상세한 정보 확인 (디버깅 용이성)
- 로그 레벨:
DEBUG또는INFO - 출력 위치: 콘솔 (Console)
- 특징: SQL 쿼리가 어떻게 나가는지, 파라미터 바인딩 값은 무엇인지 눈으로 직접 확인해야 합니다.
2. 운영 환경 (Production)
- 목표: 꼭 필요한 정보만 남기고 스토리지 효율화 (성능 및 안정성)
- 로그 레벨:
INFO(중요 정보) 또는ERROR(장애 상황) - 출력 위치: 파일 (File)
- 특징: 콘솔 출력은 I/O 리소스를 많이 잡아먹으므로 지양하고, 파일로 저장하되 Rolling 정책(날짜별, 용량별 분리)을 적용하여 디스크가 꽉 차는 것을 방지해야 합니다.
2: logback-spring.xml 설정 실전 예제
스프링 부트에서는 src/main/resources 경로에 logback-spring.xml 파일을 생성하면 자동으로 설정을 읽어옵니다. (logback.xml보다 스프링의 기능을 더 활용할 수 있어 권장됩니다.)
아래 코드는 콘솔 출력, 파일 저장, 그리고 환경별 분기 처리를 모두 포함한 모범 설정 예시입니다.
XML
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="./logs"/>
<property name="LOG_FILE_NAME" value="application"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<springProfile name="local,dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILE"/>
</root>
</springProfile>
</configuration>
3: Slack 연동을 통한 실시간 에러 모니터링
서버에 ERROR 로그가 찍혔다는 것은 누군가에게 기능이 동작하지 않았다는 뜻입니다. 이를 매일 아침 로그 파일을 열어서 확인할 수는 없습니다. Slack Webhook을 이용하여 에러 발생 시 즉시 알림을 받도록 설정해 봅시다.
이를 위해 오픈소스 라이브러리(logback-slack-appender)를 활용하는 것이 가장 효율적입니다.
Step 1: 의존성 추가 (build.gradle)
Groovy
implementation 'com.github.maricn:logback-slack-appender:1.6.1'
Step 2: Slack Webhook URL 발급
Slack 워크스페이스 설정에서 ‘Incoming Webhooks’ 앱을 추가하고, 알림을 받을 채널을 선택하여 URL을 복사합니다.
Step 3: logback-spring.xml에 Slack Appender 추가
여기서 중요한 점은 AsyncAppender를 사용하는 것입니다. 슬랙 서버가 느리거나 장애가 났을 때, 우리 서버의 비즈니스 로직까지 멈추는 것(Blocking)을 방지하기 위해 반드시 비동기(Async)로 전송해야 합니다.
XML
<appender name="SLACK" class="com.github.maricn.logback.slack.SlackAppender">
<webhookUri>https://hooks.slack.com/services/YOUR/WEBHOOK/URL</webhookUri>
<channel>#server-error-logs</channel>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</layout>
<username>ErrorBot</username>
<iconEmoji>:rotating_light:</iconEmoji>
<colorCoding>true</colorCoding>
</appender>
<appender name="ASYNC_SLACK" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="SLACK"/>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level> </filter>
</appender>
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="ASYNC_SLACK"/> </root>
</springProfile>
이 설정을 적용하면, 운영 서버에서 log.error("결제 실패...", e);가 호출되는 순간, 지정된 슬랙 채널로 에러 내용이 전송됩니다.
4: 주의사항 및 최적화 팁
- 민감 정보 마스킹: 로그나 슬랙 알림에 사용자의 비밀번호, 주민등록번호, 카드 번호 등 민감한 개인정보(PII)가 포함되어서는 안 됩니다. 로그를 남기기 전에 반드시 마스킹 처리를 해야 합니다.
- 동기화 문제: Slack Appender를
Async없이 사용하면, 슬랙 API 응답이 늦어질 경우 사용자의 요청 처리도 함께 늦어집니다. 반드시AsyncAppender로 감싸서 별도의 스레드에서 전송하도록 설정하세요. - 알림 피로도 관리: 모든
WARN로그까지 알림을 보내면 ‘양치기 소년’이 되어 진짜 중요한 에러를 무시하게 됩니다. 슬랙 알림은 반드시ERROR레벨 이상, 즉 즉각적인 조치가 필요한 건에 대해서만 발송하도록 필터(ThresholdFilter)를 거는 것이 좋습니다.
3. 결론
지금까지 스프링 부트의 Logback 설정을 통해 환경별로 최적화된 로그 전략을 세우고, Slack과 연동하여 실시간 모니터링 체계를 구축하는 방법에 대해 알아보았습니다.
로그는 시스템의 건강 상태를 나타내는 가장 정직한 지표입니다. logback-spring.xml 파일을 한 번 잘 만들어두면, 로컬에서는 편하게 개발하고 운영에서는 안정적으로 시스템을 유지보수할 수 있습니다. 특히 오늘 소개한 Slack 알림 연동은 주니어 개발자에서 시스템 전체를 관망할 줄 아는 시니어 개발자로 성장하는 데 필수적인 스킬입니다.
더 이상 고객의 전화를 받고 장애를 인지하지 마세요. 로그가 여러분에게 먼저 말을 걸도록 시스템을 구축하시기 바랍니다.
이제 서버 한 대의 로그 관리는 마스터하셨습니다. 하지만 서버가 10대, 100대로 늘어나면 로그 파일도 수백 개가 됩니다. 이를 한곳에 모아서 검색하고 시각화 하여 MSA 환경으로 넘어가기가 필요합니다.