AWS CloudWatch Log 남기기

짱구석·2022년 1월 4일
1

python flask aws cloudwatch에 로그를 남기는 방법에 대해서 알아보겠습니다.

TL;DR

  • log를 킹갓 AWS에 맡겨볼겁니다.
  • watchtower를 사용할 겁니다.
  • flask에 적용할겁니다.(다른 framework면 미리 죄송합니다.)

들어가며

회사에서는 로그를 특정 파일에 남긴 뒤 해당 파일을 s3의 올리는 방식을 사용하고 있습니다.
원하는 로그를 검색도 하기도 어렵고 가독성도 매우 떨어져서 "이게 맞나..." 싶었습니다.
또 로그를 확인하기 위해서 s3에서 파일을 다운받고 에디터로 열고 검색하고 하는 과정이 심히 불편쓰..
그러다보니 로그가 있어도 잘 이용을 하지 않는 느낌을 많이 받아서 고민하던 중
간단하게 적용할 수 있는 라이브러리가 있어서 회사 적용해보았더니 기존에 비해 편리하다는 느낌을 많이 받아서 정리 겸 공유 해보려고 합니다.

IAM 사용자 생성

사용자 생성

'AWS Console - IAM - 사용자'에서 '사용자 추가'를 해주세요.

*'AWS 액세스 유형 선택'에서 '엑세스 키-프로그래밍 방식 액세스' 선택 해주세요.

권한 부여

watchtower에서 다음과 같이 적절한 권한을 추가하도록 권장하고 있습니다.

we recommend that you use the arn:aws:iam::aws:policy/AWSOpsWorksCloudWatchLogs managed policy, which has just the right permissions without being overly broad.
-> 지나치게 광범위하지 않으면서 적절한 "AWSOpsWorksCloudWatchLogs" 정책을 사용하는 것을 추천합니다.

IAM 생성완료

IAM 생성이 완료된 모습입니다. 액세스 키와 비밀 액세스 키를 잘 가지고 있어 주세요.

watchtower 추가

pip install --upgrade pip
pip install watchtower

끝입니다.

handler 적용

# app.py
import logging

from flask import Flask, current_app
import watchtower

app = Flask(__name__)

handler = watchtower.CloudWatchLogHandler(
        log_group_name="my-service",
        log_stream_name="dev", 
)

formatter = logging.Formatter("[%(levelname)s] %(message)s")
handler.setFormatter(formatter)
handler.setLevel(logging.INFO)

app.logger.addHandler(handler)

@app.route("/")
def hello_world():
    current_app.logger.info("It`s working!!")
    return "<p>Hello, World!</p>"

적용을 위한 간단한 flask app을 만들어보았습니다.

그럼 테스트를 한번 해볼까요?

export FLASK_APP=app.py
flask run

이런... 에러가 나오네요.

botocore.exceptions.NoRegionError: You must specify a region.

이때! 1번에서 생성한 IAM 액세스 키를 추가해주어야합니다.

export AWS_DEFAULT_REGION=default_region
export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key

AWS_DEFAULT_REGION = default region을 설정해주어야합니다. 서울은 'ap-northeast-2'입니다.
AWS_ACCESS_KEY_ID = IAM 생성 시 받은 액세스 키를 넣어줍니다.
AWS_SECRET_ACCESS_KEY = IAM 생성 시 받은 비밀 액세스 키를 넣어줍니다.

적용 후 다시 flask run 하면 이번에는 정상동작하는 것을 볼 수 있습니다.

확인하기

API를 호출 해볼까요?
http://localhost:5000/

호출 후 AWS Console로 가보면 다음과 같이 코드에 설정한 로그 그룹과 로그 스트림 정보가 나타나게됩니다.

로그 전송 시간이 있어서 1분정도 딜레이가 있을 수 있습니다.
물론 해당 시간은 로그핸들러 생성시 조정할 수 있는 인자가 있습니다.


짠! log가 정상적으로 들어왔네요~ 이제 cloudwatch에서 서비스의 로그를 확인할 수 있습니다.

실제 운영 시 고려한 점

  • 로그스트림에는 개발환경(dev, staging, prod)를 넣어서 구분했다.
  • 실제로는 환경변수가 아닌 aws credential을 사용했다.(보안)
  • 기존에 boto3를 사용하고 있었으면 boto3.client("logs")로 credential을 부여할 수 있는 인자기 있다.(라이브러리가 boto3 기반)
  • 핸들러 생성시 aws credential이 적절하지 않으면 서버가 구동이 안되기 때문에 적용하지 않도록 에러 처리를 했다. (예: CI 테스트 서버)

마치며

서비스를 운영하면서 당장의 대응만 생각하다보면 로그 구축은 생각보다 우선순위에서 멀어지게 되는거 같습니다.
때문에 미래를 대비하기 위해서 읽기 쉽고, 사용하기 쉬운 로깅에 대해서 고민이 필요할 것 같습니다.

Reference

watchtower github

0개의 댓글