-
[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를 전송할 수 있도록 정말 편리하게 제공해주는 라이브러리 가 있습니다. 해당 라이브러리를 사용하려면 아래의 의존성을 추가해주어야 합니다.gradleimplementation "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