카카오테크 부트캠프/프로젝트

백엔드 서버에 오류가 떴을 때 디스코드로 알람 연동 자동화 기능 연결

bubhyun 2025. 5. 15. 17:48
728x90

1. 디스코드 채팅 채널 웹후크 생성

웹후크 URL 복사 해서 application.yml 파일에 추가

 

🗂️ 디렉토리 구조

수정해야 하는 파일 / 생성해야 하는 파일

koco/
├── .gradle/
├── build/
├── gradle/
├── src/
│   ├── main/
│   │   ├── java/
│   │   └── resources/
│   │       ├── application.yml
│   │       ├── console-appender.xml
│   │       ├── discord-error-appender.xml
│   │       └── logback-spring.xml
│   └── test/
├── .gitattributes
├── .gitignore
├── build.gradle
├── gradlew
├── gradlew.bat
└── settings.gradle

🌱 스프링부트 코드 수정 (기존 파일에 아래 내용 추가)

build.gradle

...
repositories {
	...
    maven { url '<https://jitpack.io>' }
    ...
}

dependencies {
	...
    implementation 'com.github.napstr:logback-discord-appender:1.0.0'
	...
}

application.yml

...
logging:
  discord:
    webhook-url: {디스코드에서 복사해 온 웹훅 url(중괄호없이)}
    config: classpath:logback-spring.xml

🌱 스프링부트 파일 추가

logback-spring.xml

스프링부트 로그 형식을 설정하는 파일

<configuration>
    <include resource="console-appender.xml"/>
    <include resource="discord-error-appender.xml"/>
    <appender-ref ref="ASYNC_DISCORD" />

    <timestamp key="BY_DATE" datePattern="yyyy-MM-dd"/>
    <!-- 로깅 테마 -->
    <property name="LOG_PATTERN"
              value="[%d{yyyy-MM-dd HH:mm:ss}:%-4relative] %green([%thread]) %highlight(%-5level) %boldWhite([%C.%M:%yellow(%L)]) - %msg%n"/>

    <springProperty name="DISCORD_ERROR_WEBHOOK_URL" source="logging.discord.webhook-url"/>

    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="ASYNC_DISCORD" />
    </root>

</configuration>

console-appender.xml

콘솔로 출력하는 형식 지정

<included>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>
</included>

discord-error-appender.xml

디스코드로 출력하는 형식 지정

<included>
    <appender name="DISCORD" class="com.github.napstr.logback.DiscordAppender">
        <webhookUri>${DISCORD_ERROR_WEBHOOK_URL}</webhookUri>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>

                \\n [ERROR LOG] ============================================================================
                \\n %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{2}.%M:%L] - %msg%n  
    %ex{full}%n
            </pattern>
        </layout>
        <username>백엔드에러봇🚨</username>
        <tts>false</tts>
    </appender>

    <appender name="ASYNC_DISCORD" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="DISCORD" />
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>
</included>

🧪 테스트 코드

src
└── main
    └── java
        └── koco
            └── util
                └── **DiscordTestController.java** << 파일 생성
package koco.util;  // ← 프로젝트에 맞게 변경

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DiscordTestController {
    private static final Logger log = LoggerFactory.getLogger(DiscordTestController.class);

    @GetMapping("/test-discord")
    public ResponseEntity<String> testDiscordWebhook() {
        log.error(">> TEST: Discord webhook 연동 확인용 에러 메시지");
        return ResponseEntity.ok("Discord webhook test triggered");
    }
}

 

 

로컬 실행 스크립트

./gradlew clean build

# 포트번호는 비어있는 포트 사용
java -jar build/libs/{jar파일이름}.jar --server.port=8080

curl -v <http://localhost:8080/test-discord>

 

하지만 이런 경우 로컬에서 작업할 때의 오류도 디스코드에 전부 올라가게 된다.

따라서 계정을 구분해 로컬 작업 시엔 알람이 가지 않게 구분한다.

 

먼저 application.yml 에 로컬인지 아닌지를 구분한다.

spring:
  profiles:
    active: local  # or prod (배포 시)

# 공통 설정 (application.yml)

logging:
  level:
    root: INFO

 

 

application-local.yml

# 로컬 전용 설정 (application-local.yml)

logging:
  discord:
    enabled: false  # 알림 비활성화

 

apllication-prod.yml

logging:
  discord:
    enabled: true
    webhook-url: https://discord.com/api/webhooks/
    config: classpath:logback-spring.xml

 

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <timestamp key="BY_DATE" datePattern="yyyy-MM-dd"/>

    <!-- 로깅 테마 -->
    <property name="LOG_PATTERN"
              value="[%d{yyyy-MM-dd HH:mm:ss}:%-4relative] %green([%thread]) %highlight(%-5level) %boldWhite([%C.%M:%yellow(%L)]) - %msg%n"/>

    <!-- Spring 환경 변수 -->
    <springProperty name="DISCORD_ENABLED" source="logging.discord.enabled" defaultValue="false"/>
    <springProperty name="DISCORD_ERROR_WEBHOOK_URL" source="logging.discord.webhook-url" defaultValue=""/>

    <!-- 콘솔 로그 설정 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- 루트 로거 설정 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

 

이후 각 파일들을 수정해주면 로컬에서 작업할 때 알람이 가지 않게 된다!

 

운영 서버에서 실행할 땐 계정을 prod로 변경해주면 된다!

java -jar app.jar --spring.profiles.active=prod

 

오류가 잘 뜨는 모습

728x90