-
[AWS] Spring Logback으로 CloudWatch에 로그 보내는 법Cloud/AWS 2021. 5. 13. 11:40728x90반응형
Spring Error log CloudWatch로 전송하는 법
서버를 관리하게 되면 가장 많이 하는 일 중 하나가
로그
를 읽는 작업이라고도 할 수 있습니다. 로그는 그 당시 어떤 일이 일어났는지 확인할 수 있게 해주는 중요한 단서이기 때문에 문제가 생겼을 때 해결하는데 많은 도움이 됩니다. 그렇기 때문에 이런 로그들은 반드시 기록하고 있어야 하며 일정 기간 동안 유실되지 않도록 잘 관리해야 합니다.또한 모든 로그를 다 기록할 순 없기 때문에 필요한 로그들만 잘 기록해야 하고, 많은 로그들 중에서 손쉽게 필요한 로그들만 찾을 수 있도록 관리할 방법들도 필요한데요. AWS에서는 이러한 기능들을 편리하게 사용할 수 있도록
CloudWatch
라는 서비스를 제공해주고 있습니다.CloudWatch Agent
가 로그도 모니터링해서CloudWatch logs
로 전송하는 역할도 하고 있습니다.그래서 이번 글에서는
CloudWatch
와Spring Logback
을 사용해서Spring Error log
를 CloudWatch Log Group 으로 전송하는 법에 대해서 정리 해보겠습니다.Spring 설정하기
Spring에서
CloudWatch
로 Error log를 전송할 수 있도록 정말 편리하게 제공해주는 라이브러리 가 있습니다. 해당 라이브러리를 사용하려면 아래의 의존성을 추가해주어야 합니다.gradle
implementation "ca.pjer:logback-awslogs-appender:1.6.0"
maven
<dependency> <groupId>ca.pjer</groupId> <artifactId>logback-awslogs-appender</artifactId> <version>1.6.0</version> </dependency>
위의 의존성을 추가하고 프로젝트 세팅을 해보겠습니다. (버전은 시기에 따라 달라질 수 있습니다.)
저의 프로젝트 구조는 위와 같습니다. 가장 중요한 파일은
logback.xml
파일 인데요.resources
폴더 아래에logback.xml
파일을 만드시면 됩니다.AWS IAM CloudWatch 권한 추가하기
CloudWatchFullAccess
권한을 추가하겠습니다.logback.xml
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> <property name="LOG_PATTERN" value="${LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){blue} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <springProperty name="AWS_ACCESS_KEY" source="cloud.aws.credentials.accessKey"/> <springProperty name="AWS_SECRET_KEY" source="cloud.aws.credentials.secretKey"/> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>${LOG_PATTERN}</Pattern> </layout> </appender> <appender name="aws_cloud_watch_log" class="ca.pjer.logback.AwsLogsAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <layout> <pattern>[%thread] [%date] [%level] [%file:%line] - %msg%n</pattern> </layout> <logGroupName>Marryting-log</logGroupName> <logStreamUuidPrefix>Marryting-log-</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> </appender> <springProfile name="local,dev"> <root level="info"> <appender-ref ref="CONSOLE"/> </root> <logger name="com.amazonaws.util.EC2MetadataUtils" level="error" additivity="false"> </logger> <logger name="mashup.spring.jsmr" level="debug" additivity="false"> <appender-ref ref="CONSOLE"/> </logger> <logger name="mashup.spring.jsmr" level="error" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="aws_cloud_watch_log"/> </logger> </springProfile> <springProfile name="prod"> <root level="info"> <appender-ref ref="CONSOLE"/> </root> <logger name="com.amazonaws.util.EC2MetadataUtils" level="error" additivity="false"> </logger> <logger name="mashup.spring.jsmr" level="debug" additivity="false"> <appender-ref ref="CONSOLE"/> </logger> </springProfile> </configuration>
전체 Logback 코드는 위와 같은데요. 코드에 대해서 일부분 정리해보겠습니다.
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <property name="LOG_PATTERN" value="${LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){blue} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> </configuration>
위처럼
property
라는 속성을 통해서 로그의 패턴을 어떻게 출력할 것인지 정의할 수 있습니다.<?xml version="1.0" encoding="UTF-8" ?> <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>${LOG_PATTERN}</Pattern> </layout> </appender> </configuration>
그리고 위에서 정의한 로그 패턴을 출력할
appender
를 하나 정의합니다.<?xml version="1.0" encoding="UTF-8" ?> <configuration> <springProperty name="AWS_ACCESS_KEY" source="cloud.aws.credentials.accessKey"/> <springProperty name="AWS_SECRET_KEY" source="cloud.aws.credentials.secretKey"/> </configuration>
springProperty
속성을 사용하면logback.xml
파일에서application.yml
에 있는AWS IAM AccessKey, SecretKey
값을 읽어와서 사용할 수 있습니다.이제 CloudWatch로 Spring Log를 전송하는
ca.pjer:logback-awslogs-appender
라이브러리를 활용하는 appender 부분을 알아보겠습니다.- logGroupName: CloudWatch log Group Name
- logStreamUuidPrefix: Marryting-Api-log-d880c850-c43c-4313-b0f6-8d32139470b 와 같은 로그 스트림의 UUID가 생깁니다.
- logRegion: CloudWatch AWS Region
- maxBatchLogEvents: 배치의 최대 이벤트 갯수를 설정하는 것이며 1 ~ 10000사이 값만 설정이 가능하다. 이벤트 대기열에 갯수가 50개가 되면 AWS Cloud Watch로 로그가 전송됩니다.
- maxFlushTimeMillis: 마지막 플러시가 발생된 이후 지정된 시간이 지나면 AWS Cloud Watch로 로그가 전송된다. 0일 경우 로그를 동기로 전송하고 0보다 큰값일 경우 비동기로 로그가 전송됩니다.
- maxBlockTimeMillis: 로그가 전송되는 동안 코드가 계속 실행되는 것을 차단하고 값을 0으로 세팅하면 전송중에 발생되는 모든 로그를 버립니다.
- retentionTimeDays: 로그그룹의 보존기간을 얘기합니다. 0으로 세팅하면 보존기간은 무기한으로 보존됩니다.
- accessKeyId: AWS IAM Access Key (위에서 SpringProperty로 yml에서 읽어온 것 사용하기)
- secretAccessKey: AWS IAM Secret Key (위에서 SpringProperty로 yml에서 읽어온 것 사용하기)
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <springProfile name="local,dev"> <root level="info"> <appender-ref ref="CONSOLE"/> </root> <logger name="com.amazonaws.util.EC2MetadataUtils" level="error" additivity="false"> </logger> <logger name="mashup.spring.jsmr" level="debug" additivity="false"> <appender-ref ref="CONSOLE"/> </logger> <logger name="mashup.spring.jsmr" level="error" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="aws_cloud_watch_log"/> </logger> </springProfile> </configuration>
마지막으로
springProfile
을 사용하면active profile
값에 따라 logback 설정을 커스텀할 수 있습니다.<logger name="mashup.spring.jsmr" level="error" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="aws_cloud_watch_log"/> </logger>
예를들어, 위처럼 로그 레벨 error에 해당할 때 위에서 정의한 appender 2개를 추가해서 정의할 수 있는 형식입니다.
Error 발생시키기
위처럼 logback을 작성하면
log.error()
로 출력되는 에러들을CloudWatch
로 전송하게 되는데요.log.error()
가 출력되는 어떤 것들을 실행시켜보겠습니다.(저는 현재 진행하고 있는 프로젝트를 실행시켰습니다.)그러면 위처럼 CloudWatch에 로그가 잘 쌓이는 것을 확인할 수 있습니다.
Reference
반응형'Cloud > AWS' 카테고리의 다른 글
[AWS] API Gateway, Lambda로 S3 파일 업로드 API 만들기 (2) 2021.05.14 [AWS] NodeJS로 만든 Lambda 함수로 이미지 사이즈 줄이는 법 (0) 2021.05.13 [AWS] API Gateway로 Lambda 함수 호출하는 간단한 실습해보기 (0) 2021.05.13 [AWS] EC2 Nginx Access log를 CloudWatch로 전송하는 법 (1) 2021.05.12 [AWS] Lambda로 Thumbnail 이미지 자동 생성하기 (11) 2021.05.11