티스토리 뷰

이번글에서는 Spring 애플리케이션에서 발생된 로그를 AWS Cloud Watch로 전송하는 방법에 대해 알아보자.

 

그전에 Spring 애플리케이션에서 AWS Cloud Watch로 로그를 전송하려면 CloudWatchLogsFullAccess 라는 Role을 가진 IAM 사용자의 액세스 키, 시크릿 키가 존재해야 한다. IAM 사용자를 추가하고 Role을 부여하는 방법은 여기를 참고하자.

프로젝트 환경

  • JAVA 11
  • Spring Boot 2.6.2
  • Maven

AWS Log Appender 라이브러리 추가

Maven
<dependency>
    <groupId>ca.pjer</groupId>
    <artifactId>logback-awslogs-appender</artifactId>
    <version>1.6.0</version>
</dependency>

Gradle
implementation group: 'ca.pjer', name: 'logback-awslogs-appender', version: '1.6.0'

application.yml 세팅

logging:
  config: classpath:logback-spring.xml
server:
  port: 8080
---

spring:
  config:
    activate:
      on-profile: local
---

spring:
  config:
    activate:
      on-profile: stage

stage일때 Cloud Watch로 로그를 전송하도록 구성한다.

logback-spring.xml 파일추가

<configuration packagingData="true">
    <timestamp key="timestamp" datePattern="yyyy-MM-dd-HH-mm-ssSSS"/>

    <appender name="aws_cloud_watch_log" class="ca.pjer.logback.AwsLogsAppender">
        <layout>
            <pattern>[%thread] [%date] [%level] [%file:%line] - %msg%n</pattern>
        </layout>
        <logGroupName>kimjonghyun-</logGroupName>
        <logStreamUuidPrefix>kimjonghyun-</logStreamUuidPrefix>
        <logRegion>us-east-2</logRegion>
        <maxBatchLogEvents>50</maxBatchLogEvents>
        <maxFlushTimeMillis>30000</maxFlushTimeMillis>
        <maxBlockTimeMillis>5000</maxBlockTimeMillis>
        <retentionTimeDays>0</retentionTimeDays>
        <accessKeyId>액세스키값</accessKeyId>
        <secretAccessKey>시크릿키값</secretAccessKey>
    </appender>
    <appender name="application_log" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%thread] [%date] [%level] [%file:%line] - %msg%n</pattern>
        </encoder>
    </appender>

    <springProfile name="(local | development)">
        <root level="INFO">
            <appender-ref ref="application_log"/>
        </root>
    </springProfile>
    <springProfile name="(stage | production)">
        <root level="INFO">
            <appender-ref ref="application_log"/>
        </root>
        <logger name="com.example" level="DEBUG">
            <appender-ref ref="aws_cloud_watch_log"/>
        </logger>
    </springProfile>
</configuration>

logGroupName

  • 로그그룹의 이름이다. 로그스트림을 그룹화 할 수 있게끔 구성되있다

 

logStreamUuidPrefix

  • 로그스트림은 난수로 생성이 되는데 그 난수앞에 prefix값을 지정해줄 수 있다.

 

logRegion

  • IAM 사용자의 region 값을 적어준다.

 

maxBatchLogEvents

  • 배치의 최대 이벤트 갯수를 설정하는 것이며 1 ~ 10000사이 값만 설정이 가능하다. 이벤트 대기열에 갯수가 50개가 되면 AWS Cloud Watch로 로그가 전송된다.
  • 기본값 : 50

 

maxFlushTimeMillis

  • 마지막 플러시가 발생된 이후 지정된 시간이 지나면 AWS Cloud Watch로 로그가 전송된다. 0일 경우 로그를 동기로 전송하고 0보다 큰값일 경우 비동기로 로그가 전송된다.
  • 기본값 : 0

 

maxBlockTimeMillis

  • 로그가 전송되는 동안 코드가 계속 실행되는 것을 차단하고 값을 0으로 세팅하면 전송중에 발생되는 모든 로그를 버립니다. 그래서 기본값으로 세팅하였다.
  • 기본값 : 5000

 

retentionTimeDays

  • 로그그룹의 보존기간을 얘기합니다. 0으로 세팅하면 보존기간은 무기한으로 보존됩니다. 이 필드에 대한 자세한 내용은 여기에서 참고하자.
  • 기본값 : 0

 

accessKeyId, secretAccessKey

  • CloudWatchLogsFullAccess Role을 소유한 IAM 사용자의 액세스키, 시크릿키 입니다. 이 값을 logback-spring.xml 파일에 정의하지 않고 외부에서 관리를 하는방법이 있는데 여기에서 확인할 수 있다.

JAVA 코드작성

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;

@Slf4j
@RestController
public class CloudWatchController {
    @GetMapping("/hello")
    public void hello() {
        log.info("current time : {}", LocalDateTime.now());
        throw new RuntimeException("cloud-watch !");
    }
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Slf4j
@ControllerAdvice
public class CloudWatchControllerAdvice {
    @ExceptionHandler(RuntimeException.class)
    public void exceptionHandler(RuntimeException e) {
        log.error(e.getMessage(), e);
    }
}

현재날짜를 출력하는 로그와 예외에 대한 로그를 Cloud Watch로 전송할 수 있도록 구성하였다.

Cloud Watch로 로그전송

Spring 애플리케이션을 구동시킨 후 로그를 출력해보았다. 이제 Cloud Watch Management Console에 가보자.



logback-spring.xml에 지정한 로그그룹과 로그스트림이 생성된 걸 확인할 수 있다.



정상적으로 로그가 전송된 걸 확인할 수 있다.



로그메세지 검색, 로그생성시간 검색기능들도 제공해준다.



Pause을 클릭하면 Resume으로 바뀌고 애플리케이션에서 로그가 전송되어도 Cloud Watch 목록엔 나오지 않는다.

 

Resume을 클릭하면 Pause상태 이후 전송된 로그들을 확인할 수 있다.

 

참고 

위 예제에서 사용된 aws log dependency 버전이 1.6.0인데 1.5.0으로 낮춰주면 accessKey, secretAccessKey를 logback-spring.xml에 추가하지 않아도 된다.

 

버전 1.5.0은 aws cloudwatch log credentials 인증을 DefaultAWSCredentialsProviderChain 클래스가 처리하는데 이 클래스는 accessKey, secretAccessKey를 Java System 속성 또는 OS 환경변수에 정의된 값을 참조해서 credentials 인증을 처리한다.

 

EC2 같은 경우에는 인스턴스 프로파일에 CloudWatchLogsFullAccess 역할을 부여하면 IMDS를 통해 credentials 인증을 처리한다.

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함