본문 바로가기

AWS

AWS Elastic Beanstalk에서 로깅하고 AWS ElasticSearch Service + Kibana로 로그 시각화하기

🔐 들어가며

안녕하세요! 이번 포스팅에서는 AWS의 Elastic Beanstalk에서 로깅을 어떻게 할 수 있는지 알아보고, 추가적으로 Elastic Search와 Kibana로 로그를 모니터링하는 방법에 대해 소개해드리겠습니다!

공식 문서를 보고 따라한 방법이 아닌 많은 시행착오와 삽질과 멘토님의 도움으로 완성한 방법입니다. 따라서 이 방법이 정답은 아니라는 것을 알려드리고 시작하려고 합니다.

로그 모니터링 구조

저는 위 사진과 같은 구조로 구현을 할 예정입니다!

서울리전을 기준으로 링크를 걸어두었으니, 다른 리전이신 분들은 하이퍼링크 걸린 링크에 들어간 후에 리전을 바꿔주세요! 🙏


🔌 로그 포맷 JSON으로 변경하기

가장 먼저 로그 포맷은 JSON으로 관리하는게 가장 편하고 트래킹하기도 편했기 때문에 로그 포맷을 JSON으로 바꾸고 시작하도록 하겠습니다. 저는 Spring Boot를 사용하기 때문에 Spring Boot 기준으로 설명하도록 하겠습니다.

build.gradle

dependencies {
  ...
  compile 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
  compile 'ch.qos.logback.contrib:logback-jackson:0.1.5'
}

 

의존성을 추가하고, logback의 설정을 변경해줍니다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
      <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
        <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
        <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
        <appendLineSeparator>true</appendLineSeparator>
        <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
        </jsonFormatter>
      </layout>
    </encoder>
  </appender>

  <root level="INFO">
    <appender-ref ref="Console"/>
  </root>
</configuration>

이렇게 하면, 로그가 아래와 같은 방식으로 찍히는 것을 확인할 수 있습니다.


⭐️ Elastic Search 만들기

1. Elastic Beanstalk 로그 스트리밍하기

구성 - 소프트웨어에 들어가서 편집을 눌러줍니다.

 

그 이후에 로그 스트리밍을 활성화해줍니다. 설정을 저장해준뒤에 CloudWatch - 로그 그룹에 가서 확인을 하면

 

로그 그룹이 아래와 같이 생기는 것을 확인할 수 있습니다. 로그 그룹은 플랫폼에 따라 조금씩 다를 수 있습니다. 저는 Corretto 플랫폼을 사용하기 때문에 아래와 같이 5개의 로그 그룹이 생성되었습니다.

Cloud Watch로 로그 확인은 충분히 가능하지만, 검색에 시간이 너무 오래 걸리고 시각화가 안된다는 단점이 있기 때문에 ElasticSearch + Kibana를 붙여보겠습니다.

 

2. ElasticSearch 도메인 생성

이제 로그가 생성된 것을 확인했으니, ElasticSearch Service에 접속해보겠습니다.

그 이후에 새 도메인 생성을 눌러 도메인을 생성해줍니다.

 

세분화된 액세스 제어를 활성해주어야합니다. 이 때 사용자 이름과 암호는 Kibana에 접속할 때 사용됩니다.

이렇게 다 만들고나면,

 

성공적으로 생성했다는 알람이 뜨게 됩니다. 현재 상태는 '로드 중'이지만, 10분정도 기다린 다음에 다시 새로고침을 하게 되면,


👀 Kibana 접근 권한 설정하기

1. Kibana 접속하기

 

활성화 상태로 바뀌게 됩니다. 키바나 링크가 추가적으로 제공되는데, 이 링크를 클릭해서 접속해보도록 하겠습니다.

 

아까 입력했던 사용자 이름과 비밀번호를 입력해줍니다.

 

접속에 성공하면 키바나 홈이 뜨게 됩니다. 하지만 키바나에 접근할 수 있는건 최초 사용자밖에 없기 때문에, 접근할 수 있는 역할을 만들어보겠습니다.

 

2. IAM 역할 만들기

Identity and Access Management(IAM) 서비스에 접속한 뒤에, 역할을 클릭해줍니다.

 

사용 사례는 Lambda를 클릭해주고, 다음으로 넘어가줍니다.

 

권한 정책을 연결해야하는데, Beanstalk → Cloudwatch로 넘어오는 로그를 Elasticsearch Service로 넘기기 위해 필요한 람다 관련 정책인 AWSLambdaBasicExecutionRole를 선택해줍니다.

 

그 뒤에 역할 이름을 지어줍니다. 이 때, 역할 이름은 최대한 짧게 짓는게 좋습니다. 그 이유는

 

여기에 설정되는 역할 ARN이 Kibana의 유저 이름이 되는데, 유저 이름은 총 50자를 넘길 수 없기 때문입니다. 그렇기 때문에 ARN의 글자수를 확인해보고 50자 이내로 지어주어야합니다. 이 ARN은 계속 사용할 값이기 때문에 복사해둡니다.

 

3. Kibana internal user 추가

다시 키바나로 돌아와서, Security - Internal users를 선택합니다.

그 이후에 Create Internal user를 클릭합니다.

 

Username과 Backend roles에 아까 복사했던 IAM Role의 ARN을 입력해줍니다.

 

생성이 된 것을 확인할 수 있습니다.

 

4. Kibana 역할 매핑하기

이제 유저를 만들었으니, 유저를 권한에 매핑해보겠습니다. Security - Roles를 클릭해서 들어가줍니다.


all_access를 찾아 들어가줍니다.

 

방금 만든 유저를 매핑해준 후에 저장해줍니다.


🌷 구독 필터 생성하기

1. CloudWatch에서 구독 필터 생성

다시 CloudWatch의 로그 그룹으로 돌아와서, web.stdout.log를 클릭하고 Elasticsearch 구독 필터를 생성해줍니다.

 

클러스터는 아까 만든 ElasticSearch를, IAM Role은 아까 만든 IAM Role을 선택해줍니다.

 

로그 형식은 JSON을 선택하고 필터 추가를 해줍니다.

 

제대로 생성이 된 것을 확인할 수 있습니다.

 

2. Kibana 인덱스 생성

이제 문제가 없다면! 로그가 생성될 때 마다 Elastic Beanstalk → Cloud Watch → Lambda → ElasticSearch → Kibana를 통해 로그를 확인할 수 있습니다.

인덱스 패턴을 만들어주겠습니다.

 

인덱스를 생성해준 준 뒤에, Discover를 클릭하면

 

 

드디어!! 로그 시각화를 할 수 있게 되었습니다… 😭

 

검색도 가능한 것을 확인할 수 있습니다.

저는 여기에 람다를 추가적으로 커스터마이징해서 필드를 몇 개 제거해놨는데, 람다 코드는 자유롭게 수정할 수 있으니 원하는대로 커스터마이징하면 될 것 같습니다!


✨ 정리

정리를 하고 나니 정말 … 길고 긴 장정이였습니다… 😅 며칠 내내 삽질도 해보고, 시행착오도 겪었는데 다 된 결과물을 보니 너무 뿌듯한 것 같습니다!

아직 ElasticSearch의 사용법도 잘 모르고, 어떻게 하면 효율적으로 사용하는지도 잘 모르기 때문에 천천히 공부하면서 익혀보려고 합니다.

혹시 글을 읽으면서 잘못된 내용이 있으면 댓글로 알려주시면 감사하겠습니다! 읽어주셔서 감사합니다! 😊


👏 참고