You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建AWS Lambda监控S3存储桶目录并通知上传后留存超1小时的对象

问题分析与代码修正

我来帮你梳理下当前代码的核心问题,再一步步给出能实现需求的完整方案:

首先,你的原代码存在几个关键错误,导致无法实现“监控S3目录、发送超时对象通知”的目标:

  • obj_age函数实现完全错误:s3.ObjectSummary('last_modified')的用法不符合AWS SDK规范,ObjectSummary需要传入桶名和对象键才能获取元数据,last_modified是对象的属性而非参数。
  • 逻辑判断逻辑混乱:len(obj_age)是试图获取函数对象的长度,这会直接抛出错误;而且时间比较的逻辑颠倒了,应该是当前时间 - 对象最后修改时间 > 1小时才符合“留存超1小时”的条件。
  • 缺少遍历指定目录对象的逻辑:原代码没有批量检查S3目标目录下的所有对象,无法覆盖需求场景。
  • 缺少实际的通知发送逻辑:代码里完全没实现“发送通知”的核心动作(比如通过SNS/SES)。
正确实现方案

要实现这个需求,我们不能只依赖S3事件触发(它只能在对象上传时触发一次,无法后续定时检查时长),而是需要用EventBridge定时触发Lambda,让Lambda定期扫描指定目录,校验对象留存时长并发送通知。

步骤1:配置EventBridge定时触发

创建一个EventBridge规则,设置定时触发频率(比如每15分钟一次,表达式:cron(*/15 * * * ? *)),将目标设置为你的Lambda函数。这样Lambda就能定期执行扫描任务。

步骤2:Lambda代码实现

以下是完整的可运行代码,包含对象遍历、时长校验和SNS通知功能:

import boto3
from datetime import datetime, timedelta, timezone

def lambda_handler(event, context):
    # 初始化AWS客户端
    s3_client = boto3.client('s3')
    sns_client = boto3.client('sns')
    
    # 自定义配置参数
    BUCKET_NAME = 'mybucketname'
    TARGET_PREFIX = 'your-target-directory/'  # 指定监控的目录,注意末尾要加斜杠
    OLDER_THAN_HOURS = 1
    SNS_TOPIC_ARN = 'arn:aws:sns:us-east-1:123456789012:your-sns-topic'  # 替换成你的SNS主题ARN
    
    # 获取当前UTC时间(S3对象的last_modified是UTC时区,避免时区误差)
    now_utc = datetime.now(timezone.utc)
    threshold_time = now_utc - timedelta(hours=OLDER_THAN_HOURS)
    
    # 遍历指定前缀下的所有对象(处理分页,避免对象超过1000个时漏扫)
    paginator = s3_client.get_paginator('list_objects_v2')
    page_iterator = paginator.paginate(Bucket=BUCKET_NAME, Prefix=TARGET_PREFIX)
    
    old_objects = []
    
    for page in page_iterator:
        if 'Contents' not in page:
            continue
        for obj in page['Contents']:
            # 获取对象的最后修改时间(UTC时区)
            last_modified = obj['LastModified']
            # 判断对象是否留存超过指定时长
            if last_modified < threshold_time:
                old_objects.append(f"对象键: {obj['Key']}, 最后修改时间: {last_modified.strftime('%Y-%m-%d %H:%M:%S UTC')}")
    
    # 如果存在超时对象,发送SNS通知
    if old_objects:
        message = f"在S3桶 {BUCKET_NAME} 的目录 {TARGET_PREFIX} 中,发现 {len(old_objects)} 个留存超过 {OLDER_THAN_HOURS} 小时的对象:\n"
        message += "\n".join(old_objects)
        
        # 发送通知到SNS主题
        sns_client.publish(
            TopicArn=SNS_TOPIC_ARN,
            Subject='S3对象留存超时提醒',
            Message=message
        )
        
        return {
            'statusCode': 200,
            'body': f"已发送通知,共发现 {len(old_objects)} 个超时对象"
        }
    else:
        return {
            'statusCode': 200,
            'body': f"未发现留存超过 {OLDER_THAN_HOURS} 小时的对象"
        }

步骤3:配置Lambda IAM权限

确保Lambda的执行角色拥有以下权限:

  • s3:ListBucket:用于遍历S3桶中的对象
  • sns:Publish:用于发送SNS通知

关键细节说明

  • 时区处理:S3对象的LastModified属性是UTC时间,所以我们用datetime.now(timezone.utc)获取当前UTC时间,避免时区差异导致的判断错误。
  • 分页处理:如果目标目录下的对象超过1000个,list_objects_v2会返回分页结果,用分页器paginator可以确保遍历所有对象。
  • 目录匹配:通过Prefix参数指定监控目录时,末尾必须加斜杠(比如data/),否则会匹配所有以data开头的对象(包括data123.txt这类非目录内的对象)。

内容的提问来源于stack exchange,提问作者Aadhinarayanan J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:37:30