CloudWatch日志迁移到S3过程中权限检查成功

问题描述 投票:0回答:0

如何将 CloudWatch 的日志保存为 S3?

这是 S3 存储桶策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-2.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::s3-bucket-logs"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-2.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::s3-bucket-logs/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

Cron 事件由 EventBridge 生成。

只是我得到

Permission Check Successful
.

这是代码并且已经设置了环境变量。

import boto3
import os
import datetime
import time

DESTINATION_BUCKET = os.environ['DESTINATION_BUCKET']
GROUP_NAME = os.environ['GROUP_NAME']
PREFIX = os.environ['PREFIX']
BATCH_SIZE = int(os.environ['BATCH_SIZE'])
DAYS = int(os.environ['DAYS'])
EXPORT_CHECK_CYCLE_TIME = int(os.environ['EXPORT_CHECK_CYCLE_TIME'])

currentTime = datetime.datetime.now()
start_date = currentTime - datetime.timedelta(days=(DAYS * 2))
end_date = currentTime - datetime.timedelta(days=DAYS)

FROM_DATE = int(start_date.timestamp() * 1000)
TO_DATE = int(end_date.timestamp() * 1000)

#S3 Log Bucket Directory
BUCKET_PREFIX = os.path.join(PREFIX, end_date.strftime('%Y{0}%m{0}%d').format(os.path.sep))

#1. Export CloudWatch logs in logGroup within a specified time range to S3
#2. Wait for the export operation to finish(because create_export_task is an asynchronous call)
#3. Check CloudWatch LogStream whether log events that need to be preserved exists or not
#4. If there are logs to be preserved, store logs in variables
#5. delete & remake LogStream with the same name as previously used and put the archived logs in LogStream

def lambda_handler(event, context):
    client = boto3.client('logs')
    #Export CloudWatch Log To S3
    response = client.create_export_task(
         logGroupName=GROUP_NAME,
         fromTime=FROM_DATE,
         to=TO_DATE,
         destination=DESTINATION_BUCKET,
         destinationPrefix=BUCKET_PREFIX
        )
    #Check create_export_task is finished
    taskId = response['taskId']
    status = 'RUNNING'
    while status in ['RUNNING','PENDING']:
        time.sleep(EXPORT_CHECK_CYCLE_TIME)
        response_desc = client.describe_export_tasks(
            taskId=taskId
        )
        status = response_desc['exportTasks'][0]['status']['code']
    #If create_export_task is finished 
    if status == 'COMPLETED':
        #Get all LogStreams in LogGroup
        log_streams = client.describe_log_streams(logGroupName=GROUP_NAME)['logStreams']
        for stream in log_streams:
            stream_name = stream['logStreamName']
            #If you have reached the end of the stream, it returns the same token you passed in
            prev_token = 'prev_token'
            next_token = None
            kwargs = dict(
                    logGroupName=GROUP_NAME,
                    logStreamName=stream_name,
                    startTime=TO_DATE,
                    limit=BATCH_SIZE,
                    startFromHead=False
                )
            retention_events = []
            while next_token != prev_token:
                #Get batch size LogEvents in LogStream at a time, in order of latest
                if next_token is not None:
                    kwargs['nextToken'] = next_token
                log_event_info = client.get_log_events(**kwargs)
                events = log_event_info['events']
                prev_token = next_token
                next_token = log_event_info['nextForwardToken']
                for event in events:
                    if event['timestamp'] <= TO_DATE:
                        break
                    #Remove keys not needed in put_log_events function
                    del event['ingestionTime']
                    retention_events.append(event)
            #Delete & remake LogStream
            client.delete_log_stream(logGroupName=GROUP_NAME, logStreamName=stream_name)
            client.create_log_stream(logGroupName=GROUP_NAME, logStreamName=stream_name)
            #If there are log events that need to be preserved in LogStream, Put batch size LogEvents in LogStream at a time
            retention_events_size = len(retention_events)
            for i in range(0, retention_events_size, BATCH_SIZE):
                client.put_log_events(
                    logGroupName=GROUP_NAME,
                    logStreamName=stream_name,
                    logEvents=retention_events[i : (i + BATCH_SIZE)]
                )
                time.sleep(0.2)


这就是环境

  • BATCH_SIZE = 32
  • 天 = 1
  • DESTINATION_BUCKET = s3-bucket-logs
  • EXPORT_CHECK_CYCLE_TIME = 3
  • GROUP_NAME = 日志
  • 前缀 = 保存

lambda 测试误差 [错误] InvalidParameterException:调用 CreateExportTask 操作时发生错误 (InvalidParameterException):对给定存储桶的 PutObject 调用失败。请检查 CloudWatch Logs 是否已被授予执行此操作的权限。这可能是 KMS 密钥或存储桶加密配置错误的结果。

名为“aws-log-write-test”的文件在存储桶内的 S3 上创建,但存储桶中没有其他数据或文件。 我该如何解决?

amazon-web-services amazon-s3 aws-lambda amazon-cloudwatch
© www.soinside.com 2019 - 2024. All rights reserved.