연차 신청, 관리 시스템 만들기 #13 logback.xml 설정, 로그 cloudwatch로 전달, 디스코드로 알람 설정
로컬 pc에선 에러가 나면 그냥 내가 그대로 고치면 된다.
하지만 ec2에 배포한 상황에서 로그 기록을 보려면
iterm 켜서 ec2에 ssh 접속 하고 docker logs [컨테이너이름] 하고
계속 이러다보니 현타가 와버렸다. 그리고 쓸데없는 INFO 레벨 로그도 내 귀찮음에 한 몫 했다.
그래서 서버에선 에러 로그만 출력되고 에러가 뜨면 CloudWatch에 저장되게 하고, 디스코드로 웹 훅을 걸어두기로 했따.
이전 회사에서도 이게 귀찮아서 slack에 알람 해뒀었는데 지금은 슬랙을 안쓰니.. 디스코드로 해보기로 했다.
그래들
// logback,cloudwatch
implementation 'ca.pjer:logback-awslogs-appender:1.6.0'
logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 공통 설정 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %clr(%5level) %cyan(%logger) - %msg%n" />
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger - %msg%n" />
<!-- 콘솔 출력 설정 (모든 프로파일에서 사용) -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- prod 프로파일일 때만 적용 -->
<springProfile name="prod">
<!-- 디스코드 웹훅 설정 -->
<springProperty name="DISCORD_WEBHOOK_URL" source="logging.discord.webhook-url"/>
<appender name="DISCORD" class="com.github.napstr.logback.DiscordAppender">
<webhookUri>${DISCORD_WEBHOOK_URL}</webhookUri>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{HH:mm:ss} [%thread] [%-5level] %logger{36} - %msg%n```%ex{full}```</pattern>
</layout>
<username>ALERT</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>
<!-- AWS CloudWatch 로그 설정 (prod) -->
<springProperty name="AWS_ACCESS_KEY" source="cloud.aws.credentials.access-key"/>
<springProperty name="AWS_SECRET_KEY" source="cloud.aws.credentials.secret-key"/>
<appender name="aws_cloud_watch_log" class="ca.pjer.logback.AwsLogsAppender">
<!-- ERROR 이상의 로그만 전송 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<layout>
<pattern>[%thread] [%date] [%level] [%file:%line] - %msg%n</pattern>
</layout>
<logGroupName>aws-error-log-prod/error-log</logGroupName>
<logStreamUuidPrefix>error-log-prod-</logStreamUuidPrefix>
<logRegion>ap-northeast-2</logRegion>
<maxBatchLogEvents>50</maxBatchLogEvents>
<maxFlushTimeMillis>30000</maxFlushTimeMillis>
<maxBlockTimeMillis>5000</maxBlockTimeMillis>
<retentionTimeDays>0</retentionTimeDays>
<accessKeyId>${AWS_ACCESS_KEY}</accessKeyId>
<secretAccessKey>${AWS_SECRET_KEY}</secretAccessKey>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%thread] [%5level] %logger{35}[%method:%line] %m%n</pattern>
</encoder>
</appender>
<!-- 에러 로거 (prod에서만 CloudWatch로 전송) -->
<logger name="errorLogger" level="error" additivity="false">
<appender-ref ref="aws_cloud_watch_log" />
</logger>
<!-- prod 환경에서만 DISCORD와 AWS CloudWatch 로그 전송 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_DISCORD" />
<appender-ref ref="aws_cloud_watch_log" />
</root>
</springProfile>
<!-- 다른 프로파일에 대한 루트 로거 (예: local, dev) -->
<springProfile name="!prod">
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
</configuration>
에러 발생 시 디스코드로 알람이 잘 왔다.
보아하니 Github Actions에 이사간 RDS 주소 최신화를 안해서 디비 연결이 안되서 저러는 것 같다.
클라우드와치에서도 로그가 잘 출력 된다.
역시 사람은 귀찮음에서 영감을 얻는 것 같다..
cloudwatch 참고: https://devlog-wjdrbs96.tistory.com/329
PS.
xml 중간에 aws 계정 액세스키, 비밀키 설정을 yml에서 불러온다.
저렇게 설정 해두고 분명 내가 application-local.yml 을 .gitignore에 설정 해두었는데
깃허브에 application-local.yml이 업로드 되버렸다; 지우다가 깃이 꼬여서 뭔 삽질을 했는지 참..
이미 한번 깃에 올라간 것은 .gittgnore에 설정해도 의미가 없다는 것을 알았다. 그래서 application-local.yml 깃 내에 캐시를 지우는 법을 알아냈다.
git rm --cached application-local.yml
지우고 새로 유저 발급을 했다.
aws 관련 키를 푸시해두고 크게 인생 경험 당한 썰들이 참 많으니 조심 해야한다..