Ich habe AWS Lambda (Laufzeit ist Python) verwendet, um den Quellcode für die Ausgabe von CloudWatch-Protokollen an S3 zu schreiben. Übrigens können Sie Lambda manuell oder regelmäßig mit CloudWatch Event ausführen.
Für boto3
logs = boto3.client("logs") response = logs.create_export_task(**kwargs)
Die Protokollausgabe funktioniert mit, aber create_export_task wird asynchron ausgeführt. Wenn Sie also die nächste Protokollausgabe ausführen, ohne das Ende der Verarbeitung zu bestätigen, kann ein Fehler auftreten. Wenn Sie also mehrere Protokolle ausgeben, müssen Sie überprüfen, ob die Protokollausgabe abgeschlossen ist.
logs.describe_export_tasks(taskId = response["taskId"])
Fügen wir die Verarbeitung von ein.
Die Werte der Umgebungsvariablen sind wie folgt.
Variable | Wert |
---|---|
BUCKET_NAME | Name des S3-Buckets des Protokollausgabeziels |
WAITING_TIME | 10 |
LOG_GROUPS | CloudWatchLogGroup,Verbinde dich mit einer Pause |
# -*- coding: utf-8 -*-
from datetime import datetime,timezone,timedelta
import os
import boto3
import time
import logging
import traceback
#Protokolleinstellungen
logger = logging.getLogger()
logger.setLevel(os.getenv('LOG_LEVEL', logging.DEBUG))
logs = boto3.client("logs")
BUCKET_NAME = os.environ["BUCKET_NAME"]
WAITING_TIME = int(os.environ["WAITING_TIME"])
#Stellen Sie die Zeitzone auf Japanische Zeit (JST) ein.
JST = timezone(timedelta(hours=9),"JST")
#Datumstyp bei der Ausgabe von Protokollen an S3
DATE_FORMAT = "%Y-%m-%d"
def lambda_handler(event, context):
"""
Ausgabe von CloudWatch-Protokollen im Wert von einem Tag an S3.
Die Zielzeit ist wie folgt.
AM 00:00:00.000000 ~ PM 23:59:59.999999
"""
try:
#Gestern PM23:59:59.999999
tmp_today = datetime.now(JST).replace(hour=0,minute=0,second=0,microsecond=0) - timedelta(microseconds=1)
#Gestern AM00:00:00.000000
tmp_yesterday = (tmp_today - timedelta(days=1)) + timedelta(microseconds=1)
#Wird als Präfix bei der Ausgabe von S3-Protokollen verwendet
target_date = tmp_yesterday.strftime(DATE_FORMAT)
#Für die Protokollausgabe in Zeitstempeltyp konvertieren (bis zu Mikrosekunden dauern)
today = int(tmp_today.timestamp() * 1000)
yesterday = int(tmp_yesterday.timestamp() * 1000)
#Holen Sie sich CloudWatchLogGroup von der Umgebungsvariablen
logGroups = os.environ["LOG_GROUPS"].split(",")
for logGroupName in logGroups:
try:
keys = ["logGroupName","yesterday","today","target_date"]
values = [logGroupName,yesterday,today,target_date]
payload = dict(zip(keys,values))
#Protokollausgabe ausführen
response = logs.create_export_task(
logGroupName = payload["logGroupName"],
fromTime = payload["yesterday"],
to = payload["today"],
destination = BUCKET_NAME,
destinationPrefix = "Logs" + payload["logGroupName"] + "/" + payload["target_date"]
)
#Warten Sie, bis die Protokollausgabe abgeschlossen ist.
taskId = response["taskId"]
while True:
response = logs.describe_export_tasks(
taskId = taskId
)
status = response["exportTasks"][0]["status"]["code"]
#Unterbrechen Sie die Ausführung der Aufgabe
if status != "PENDING" and status != "PENDING_CANCEL" and status != "RUNNING":
logger.info(f"taskId {taskId} has finished exporting")
break
else:
logger.info(f"taskId {taskId} is now exporting")
time.sleep(WAITING_TIME)
continue
except Exception as e:
traceback.print_exc()
logger.warning(f"type = {type(e)} , message = {e}",exc_info=True)
except Exception as e:
traceback.print_exc()
logger.error(f"type = {type(e)} , message = {e}",exc_info=True)
raise