Exportieren Sie die in CloudWatch-Protokollen gespeicherten Protokolle regelmäßig in S3, das in [AWS] CloudFormation erstellt wurde, um einen S3-Bucket zu erstellen und Lebenszyklusregeln festzulegen. Dies ist die Geschichte der Entwicklung von Lambda in Python.
Ich habe ein GitHub-Repository für einfache Testversionen erstellt-> homoluctus / lambda-cwlogs-s3
--Exportieren Sie das Protokoll des Vortages jeden Tag nach JST 14:00
Es ist unmöglich, den gesamten Code einzugeben, daher wird nur der Hauptcode zur Erklärung angegeben Den vollständigen Quellcode finden Sie unter Repositories.
Aktiviert, um mehrere zu exportierende Protokollgruppen wie TypeScript-Schnittstelle festzulegen. Wenn Sie eine zu exportierende Protokollgruppe hinzufügen möchten, erben Sie einfach die LogGroup-Klasse.
Der zu exportierende S3-Objektschlüssel ist leicht verständlich, in welchem Protokollgruppenprotokoll.
Wie ich in der Dokumentzeichenfolge geschrieben habe, hat es eine hierarchische Struktur wie dest_bucket / dest_obj_first_prefix oder log_group / dest_obj_final_prefix / *
. Wenn dest_obj_first_prefix nicht angegeben ist, wird der Name log_group eingegeben. Nach "*" sieht es aus wie "Task-ID / Protokoll-Stream / Datei exportieren". Dies wird automatisch hinzugefügt und kann nicht gesteuert werden.
class LogGroup(object, metaclass=ABCMeta):
"""Konfigurationsbasisklasse zum Exportieren von CloudWatch-Protokollen nach S3
So fügen Sie eine zu exportierende Protokollgruppe hinzu
class Example(LogGroup):
log_group = 'test'
"""
# log_Gruppe ist erforderlich, sonst optional
log_group: ClassVar[str]
log_stream: ClassVar[str] = ''
start_time: ClassVar[int] = get_specific_time_on_yesterday(
hour=0, minute=0, second=0)
end_time: ClassVar[int] = get_specific_time_on_yesterday(
hour=23, minute=59, second=59)
dest_bucket: ClassVar[str] = 'lambda-cwlogs-s3'
dest_obj_first_prefix: ClassVar[str] = ''
dest_obj_final_prefix: ClassVar[str] = get_yesterday('%Y-%m-%d')
@classmethod
def get_dest_obj_prefix(cls) -> str:
"""Holen Sie sich das vollständige S3-Objektpräfix
Hierarchische Struktur von S3
dest_bucket/dest_obj_first_prefix/dest_obj_final_prefix/*
Returns:
str
"""
first_prefix = cls.dest_obj_first_prefix or cls.log_group
return f'{first_prefix}/{cls.dest_obj_final_prefix}'
@classmethod
def to_args(cls) -> Dict[str, Union[str, int]]:
args: Dict[str, Union[str, int]] = {
'logGroupName': cls.log_group,
'fromTime': cls.start_time,
'to': cls.end_time,
'destination': cls.dest_bucket,
'destinationPrefix': cls.get_dest_obj_prefix()
}
if cls.log_stream:
args['logStreamNamePrefix'] = cls.log_stream
return args
Die folgenden beiden werden in der CloudWatch-Protokoll-API verwendet
COMPLETED
, ist der Export abgeschlossen
--Handle CANCELLED
und FAILED
als Fehler@dataclass
class Exporter:
region: InitVar[str]
client: CloudWatchLogsClient = field(init=False)
def __post_init__(self, region: str):
self.client = boto3.client('logs', region_name=region)
def export(self, target: Type[LogGroup]) -> str:
"""Exportieren Sie eine beliebige CloudWatch-Protokollprotokollgruppe nach S3
Args:
target (Type[LogGroup])
Raises:
ExportToS3Error
Returns:
str:TaskId in Antwort von CloudWatch Logs API enthalten
"""
try:
response = self.client.create_export_task(
**target.to_args()) # type: ignore
return response['taskId']
except Exception as err:
raise ExportToS3Error(err)
def get_export_progress(self, task_id: str) -> str:
try:
response = self.client.describe_export_tasks(taskId=task_id)
status = response['exportTasks'][0]['status']['code']
return status
except Exception as err:
raise GetExportTaskError(err)
@classmethod
def finishes(cls, status_code: str) -> bool:
"""Stellen Sie anhand des Statuscodes fest, ob die Exportaufgabe abgeschlossen wurde
Args:
status_code (str):
describe_export_Statuscode in der Antwort der Aufgabe enthalten
Raises:
ExportToS3Failure:Wenn der Statuscode ABGESAGT oder FEHLGESCHLAGEN ist
Returns:
bool
"""
uppercase_status_code = status_code.upper()
if uppercase_status_code == 'COMPLETED':
return True
elif uppercase_status_code in ['CANCELLED', 'FAILED']:
raise ExportToS3Failure('Exportfehler nach S3')
return False
main
Verwenden Sie LogGroup. \ _ \ _ Subclasses \ _ \ _ (), um die festgelegte untergeordnete Klasse der zu exportierenden Protokollgruppe abzurufen. \ _ \ _ Unterklassen \ _ \ _ () gibt eine Liste zurück, also drehen Sie sie mit einer for-Anweisung. Sie können jeweils nur eine CloudWatch Logs-Exportaufgabe in Ihrem Konto ausführen. Klicken Sie daher auf die API "description_export_tasks", um festzustellen, ob die Aufgabe abgeschlossen ist. Wenn es nicht abgeschlossen ist, werde ich auf 5s warten. Da create_export_task eine asynchrone API ist, haben wir keine andere Wahl, als sie auf diese Weise abzufragen.
def export_to_s3(exporter: Exporter, target: Type[LogGroup]) -> bool:
task_id = exporter.export(target)
logger.info(f'{target.log_group}Wird nach S3 exportiert({task_id=})')
while True:
status = exporter.get_export_progress(task_id)
if exporter.finishes(status):
return True
sleep(5)
def main(event: Any, context: Any) -> bool:
exporter = Exporter(region='ap-northeast-1')
targets = LogGroup.__subclasses__()
logger.info(f'Die zu exportierende Protokollgruppe ist{len(targets)}Stücke')
for target in targets:
try:
export_to_s3(exporter, target)
except GetExportTaskError as err:
logger.warning(err)
logger.warning(f'{target.log_group}Fehler beim Fortschreiten')
except Exception as err:
logger.error(err)
logger.error(f'{target.log_group}Export nach S3 fehlgeschlagen')
else:
logger.info(f'{target.log_group}Export nach S3')
return True
serverless.yml
Das Folgende ist ein Teilauszug.
Stellen Sie die IAM-Rolle so ein, dass Lambda Exportaufgaben erstellen und Aufgabeninformationen abrufen kann.
Dann möchte ich den Export jeden Tag um JST 14:00 ausführen, also geben Sie für Ereignisse cron (0 5 * *? *)
An. CloudWatch-Ereignisse werden unter UTC ausgeführt. Wenn Sie also -9h ausführen, wird es wie erwartet um 14:00 Uhr JST ausgeführt.
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'logs:createExportTask'
- 'logs:DescribeExportTasks'
Resource:
- 'arn:aws:logs:${self:provider.region}:${self:custom.accountId}:log-group:*'
functions:
export:
handler: src/handler.main
memorySize: 512
timeout: 120
events:
- schedule: cron(0 5 * * ? *)
environment:
TZ: Asia/Tokyo
homoluctus / lambda-cwlogs-s3 verfügt auch über eine CloudFormation-Vorlage zum Erstellen von GitHub-Aktionen und Ziel-S3s. Bitte nehmen Sie Bezug darauf.
Reference
Recommended Posts