作者:SRE運維博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/230410659053/
相關話題:https://www.cnsre.cn/tags/lambda/
Lambda函數檢查S3文件夾是否存在
作為 AWS 中最常用的對象存儲服務,S3 可以用於存儲各種類型的文件,包括網站文件、媒體文件、備份文件等等。在 S3 中存儲的文件可以通過不同的方式訪問,例如在 Web 應用程序中、通過移動應用程序或直接使用 AWS SDK 訪問等。
在進行 S3 存儲時,如果我們需要將存儲的日誌同步到另一個桶或區域中,則可以使用 AWS 的 S3 日誌同步任務功能。通過將日誌同步到其他存儲桶或區域中,我們可以更方便地對日誌進行分析、監控和管理。
但是,如果 S3 日誌同步任務出現故障,我們可能無法及時獲取相關的日誌信息。因此,為了確保日誌同步任務的正常運行,我們需要對任務進行監控。在本文中,我們將介紹如何使用 AWS Lambda 監控 S3 日誌同步任務。
介紹
AWS Lambda 是一種無服務器計算服務,可使您在雲中運行代碼,而無需自己管理服務器。通過使用 Lambda,您可以將代碼上傳到雲中,然後 Lambda 會根據需要自動擴展和縮減計算資源,以滿足您的應用程序的請求。Lambda 還支持許多編程語言和庫,使您能夠編寫功能強大的應用程序和服務。
在本文中,我們將使用 Lambda 編寫一個函數,該函數將定期檢查 S3 存儲桶中的文件夾是否存在。如果不存在任何文件夾,則 Lambda 將向指定的 SNS 主題發送一條消息,以便管理員可以及時採取措施。通過使用 Lambda 監控 S3 存儲桶中的文件夾,我們可以確保日誌同步任務的正常運行。
1. 準備工作
在開始之前,我們需要先準備好以下工作:
- 一個S3桶,用於存儲我們要檢查的文件夾。
- 一個SNS主題,用於發送消息提醒。
2. 創建Lambda函數
在AWS控制枱上創建一個Python Lambda函數,名稱為s3-folder-exist-checker,並使用以下代碼:
import boto3
from datetime import datetime, timedelta
from dateutil import tz
def lambda_handler(event, context):
print('Lambda 函數已啓動.')
s3 = boto3.resource('s3')
bucket_name = 'my_s3_bucket_name'
local_tz = tz.gettz('Asia/Shanghai')
now = datetime.now()
date_prefix = now.strftime('%Y/%m/%d/')
folder_prefixes = ['my_prefixes/' + date_prefix, 'my_prefixes/' + date_prefix, 'RGC-Prod-3in1oven/' + date_prefix]
folder_prefixes = [prefix + '/' if not prefix.endswith('/') else prefix for prefix in folder_prefixes] # 確保每個前綴以斜槓結尾
print('正在檢查以下 S3 文件夾:', folder_prefixes)
sns = boto3.client('sns')
topic_arn = 'arn:aws-cn:sns:cn-north-1:1234567890:s3-logs-monitoring'
for prefix in folder_prefixes:
resp = s3.meta.client.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter='/')
subfolders = [p['Prefix'] for p in resp.get('CommonPrefixes', [])]
if len(subfolders) > 0:
print(f"子文件夾 '{prefix}' 存在:")
for folder in subfolders:
print(f"發現子文件夾: {folder}")
else:
message = f"S3桶'{bucket_name}中'{prefix}'下不存在新增文件夾,即日誌同步S3桶任務失敗.請檢查.'"
sns.publish(TopicArn=topic_arn, Message=message)
print(f"已發送 SNS 消息: {message}")
print('Lambda 函數已完成.')
return {
'statusCode': 200,
'body': 'S3 文件夾存在性檢查已完成.'
}
接下來是對 Lambda 函數中的一些細節進行講解。首先,我們定義了 S3 的資源,並且指定了 S3 桶的名稱:
s3 = boto3.resource('s3')
bucket_name = 'my_bucket_name'
接着,我們獲取當前的時間,並且根據當前時間生成一個目錄前綴。我們使用 dateutil 模塊中的 tz.gettz 函數來獲取一個本地的時區信息。為了確保時區的準確性,我們建議在使用 Lambda 函數時,顯式地設置時區信息:
local_tz = tz.gettz('Asia/Shanghai')
now = datetime.now(local_tz)
date_prefix = now.strftime('%Y/%m/%d/')
在 Lambda 函數中,我們使用了 list_objects_v2 方法來列舉指定的文件夾。具體來説,我們使用了 CommonPrefixes 參數,該參數可以返回指定前綴下的子文件夾列表。如果返回的子文件夾列表為空,則説明指定的文件夾不存在。如果子文件夾列表不為空,則説明文件夾存在,並且我們可以將每個子文件夾的路徑打印出來:
resp = s3.meta.client.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter='/')
subfolders = [p['Prefix'] for p in resp.get('CommonPrefixes', [])]
if len(subfolders) > 0:
print(f"子文件夾 '{prefix}' 存在:")
for folder in subfolders:
print(f"發現子文件夾: {folder}")
如果子文件夾列表為空,則説明文件夾不存在。在這種情況下,我們可以使用 SNS 服務發送一條消息來通知管理員:
if len(subfolders) == 0:
message = f"S3桶'{bucket_name}中'{prefix}'下不存在新增文件夾,即日誌同步S3桶任務失敗.請檢查.'"
sns.publish(TopicArn=topic_arn, Message=message)
print(f"已發送 SNS 消息: {message}")
最後,我們返回了一個包含狀態碼和消息的字典,以便可以在 Lambda 函數執行過程中監控執行狀態:
return {
'statusCode': 200,
'body': 'S3 文件夾存在性檢查已完成.'
}
- 確保您的 Lambda 函數有權限訪問 S3 和 SNS
-
在 AWS Lambda 控制枱中,創建一個新的 Lambda 函數。在函數代碼中將 Python 代碼粘貼到代碼編輯器中。請確保您選擇了正確的運行時環境,並設置以下環境變量:
BUCKET_NAME:您的 S3 桶名稱SNS_TOPIC_ARN:SNS 主題的 ARN
- 配置 Lambda 函數的基本設置和高級設置,包括內存和超時。
- 在 Lambda 控制枱中,測試 Lambda 函數,以確保 Lambda 函數能夠訪問 S3 桶和 SNS 主題。為了測試該函數,您可以創建一個測試事件,該事件需要一個空的 JSON 對象,例如:
- 最後,您需要在 Amazon CloudWatch 中設置 CloudWatch Events 規則以定期觸發 Lambda 函數。這樣您的 Lambda 函數就能在您預定的時間檢查 S3 文件夾是否存在併發送通知。
總結
在這篇文章中,我們介紹了一個使用 AWS Lambda、S3 和 SNS 的自動化任務,該任務定期檢查 S3 文件夾是否存在併發送通知。我們解釋瞭如何編寫 Python 代碼來實現此任務,並提供了一個詳細的代碼示例。我們還介紹瞭如何在 AWS Lambda 和 Amazon SNS 控制枱上配置 Lambda 函數和 SNS 主題,並在 Amazon CloudWatch 中創建定期觸發器來觸發 Lambda 函數。最後,我們提供了一些最佳實踐和注意事項,以確保您的 Lambda 函數和 SNS 主題能夠正常工作。
希望這篇文章對您有所幫助!如果您有任何疑問或建議,請在下面的評論區留言。
參考文獻
- AWS Lambda 文檔
- AWS S3 文檔
- AWS SNS 文檔
作者:SRE運維博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/230410659053/
相關話題:https://www.cnsre.cn/tags/lambda/