CloudWatchLogs를 Lambda에서 자동으로 S3에 업로드하는 하나의 장치

CloudWatch에서 수집한 로그를 방치하지 않았을까요?





데이터는 활용하지 않으면 의미가 없다.

로그는 S3에 집계하자.



그렇게 해야 분석에 활용하거나 운용도 일원화할 수 있고,

무엇보다 주목하고 싶은 것은 보관 요금이다.
보다 저렴한 아카이브 서비스인 Glacier의 보관도 시야에 들어간다.

■ CloudWatch 저장 요금
0.033 USD/GB

■S3의 보관 요금
0.025 USD/GB

■ Glacier 보관 요금
0.005 USD/GB

영리한 당신은 1GB에 대해, 약 3엔의 낭비를 용서할 수 없을 것이다.



【요건】
매일 0시에 Lambda 함수가 시작되고 CloudWatch 로그 그룹 "cloudwatch-logs-messages"
전날 0:00~23:59 로그를 S3 버킷 'mys3bucketname/test_prifix'에 업로드

그럼, 설정해 가자.
(라고 할까 AWS씨, 이제 이런 기능 릴리스 해 주지 않을까-)

S3 설정



대상 S3 버킷에 버킷 정책 부여

다음을 내 환경으로 대체
- 버킷 이름(아래 예제에서는 mys3bucketname으로 표시됨)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "logs.ap-northeast-1.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::mys3bucketname"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "logs.ap-northeast-1.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::mys3bucketname/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    }
  ]
}

Lambda 만들기



파이썬 3.6에서 Lambda 함수를 처음부터 만듭니다.
(롤에는 CloudWatchLogs 권한과 S3 쓰기 권한을 부여하십시오)

예: S3Full 및 CloudwatchLogsFUll 등



Lambda 함수를 만듭니다.

다음을 내 환경으로 대체
  - Lambda 함수 이름
  - 저장처 S3 버킷명
  - 검색할 CloudWatch 로그 그룹 이름
- 저장처 S3 버킷명 아래의 임의의 프리픽스명(임의의 이름이어도 상관없다)

lambda_function.py
import datetime
import time
import boto3

lambda_name = 'PutLogFromCWLtoS3Function'    #Lambda関数名
log_group_name = '/aws/lambda/' + lambda_name
s3_bucket_name = 'mys3bucketname'    #保存先S3バケット名
s3_prefix = lambda_name + '/%s' % (datetime.date.today() - datetime.timedelta(days = 1))

def get_from_timestamp():
    today = datetime.date.today()
    yesterday = datetime.datetime.combine(today - datetime.timedelta(days = 1), datetime.time(0, 0, 0))
    timestamp = time.mktime(yesterday.timetuple())
    return int(timestamp)

def get_to_timestamp(from_ts):
    return from_ts + (60 * 60 * 24) - 1

def lambda_handler(event, context):
    from_ts = get_from_timestamp()
    to_ts = get_to_timestamp(from_ts)
    print('Timestamp: from_ts %s, to_ts %s' % (from_ts, to_ts))

    client = boto3.client('logs')
    response = client.create_export_task(
        logGroupName      = 'cloudwatch-logs-messages',     #取得するCloudWatchロググループ名
        fromTime          = from_ts * 1000,
        to                = to_ts * 1000,
        destination       = 'mys3bucketname',     #保存先S3バケット名
        destinationPrefix = 'test_prifix'    #保存先S3バケット名配下の任意のサブフォルダ名(プリフィックス名)
    )
    return response

Lambda 함수의 테스트는 아래의 형태로 「만들기」를 눌러 OK



이 함수를 CloudWatch 이벤트에 등록하고 매일 0:00에 시작하면 OK
(시각은 UTC 기준이므로 조심한다.)

UTC + 9시간 = JST
0 15 * * ? *

CloudWatch 이벤트의 등록 방법은 아래의 기사를 참조해 주었으면 한다.



아침 7시에 CloudWatch 이벤트에서 Lambda를 통해 Amazon Connect의 호출 스크립트를 발동하고,
가상 그녀 (여성의 기회 음성)에 사전 등록한 스크립트를 읽게 하는 모닝콜을
서버리스로 설계한 것이다.

AWS Virtual 그녀에게 매일 아침 모닝콜에서 일어나는 하나의 아키텍트



결론



버킷명, 프리픽스명을 파라미터로 건네주면 다수의 로그 그룹도 대응 가능하다고 생각된다.
・일차가 아니라, 1주일마다 정리해 업로드도 가능. 시간이 걸릴 것 같을 때는 Lambda의 실행 시간 제약에 주의해 (디폴트 3초가 되어 있으므로, 1분 정도로 연장하는 것)

고마워요.
조금이라도 도움이 되면 「좋아요」를 잘 부탁드립니다.

좋은 웹페이지 즐겨찾기