CloudWatch ist eine bequeme Möglichkeit, AWS-Systemprotokolle zu erfassen. Bei der Arbeit installiere ich den CloudWatch-Agenten auf meiner EC2-Instanz, um Zugriffsprotokolle und Fehlerprotokolle für verschiedene Anwendungen (Nginx, Tomcat usw.) in CloudWatch-Protokolle zu streamen.
Das Speichern von Protokollen in CloudWatch-Protokollen ist jedoch recht teuer. Daher möchte ich alte Protokolle regelmäßig in S3 verschieben. In diesem Artikel werde ich zusammenfassen, wie CloudWatch-Protokolle mit Lambda regelmäßig in S3 verschoben werden.
Geben Sie dem Lambda zunächst die entsprechenden Berechtigungen zum Bereitstellen des Codes, der die Verschiebung ausführt. Legen Sie die IAM-Rolle mit den folgenden Berechtigungen in Lambda fest.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "cloudwatch:*",
"Resource": "*"
},
{
"Action": [
"s3:Get*",
"s3:Put*",
"s3:List*",
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:CreateExportTask",
"logs:DescribeLogGroups",
"logs:Get*"
],
"Resource": "*"
}
]
}
Erteilen Sie S3 Lese- und Schreibberechtigungen, lesen Sie CloudWatch-Protokolle und erstellen Sie Aufgaben.
Wenn ich den Code in Python schreibe, sieht es so aus: Anders als die Standardbibliothek wird boto3 verwendet. Laden Sie es daher bei der Bereitstellung zusammen mit dem folgenden Code in eine Zip-Datei hoch.
import boto3
import datetime
import time
#Abfrage beim Durchsuchen von Protokollgruppen-
PREFIX = 'test-'
#S3-Bucket zum Speichern von Protokollen
S3_BUCKET = 'test_bucket'
#Verzeichnis von s3 zum Speichern von Protokollen
S3_DIR = 'logs'
def main(event,context):
'''
Funktion in main aufgerufen
'''
#boto3 client
client = boto3.client('logs')
#Holen Sie sich eine Liste der Protokollgruppen
log_groups = get_log_group_list(client)
#Speichern Sie den Protokollinhalt in s3
move_logs(client,log_groups)
def get_log_group_list(client):
'''
Rufen Sie eine Liste mit Protokollgruppeninformationen ab
'''
should_continue = True
next_token = None
log_groups=[]
#Es ist möglicherweise nicht möglich, alle auf einmal zu entfernen. Erwerben Sie sie daher wiederholt.
while should_continue:
if next_token == None:
#Für die erste Anfrage
response = client.describe_log_groups(
logGroupNamePrefix=PREFIX,
limit=50
)
else:
#Für die zweite und nachfolgende Anfrage
response = client.describe_log_groups(
logGroupNamePrefix=PREFIX,
limit=50,
nextToken=next_token
)
#Fügen Sie das erhaltene Ergebnis zur Liste hinzu
for log in response['logGroups']:
log_groups.append(log)
#Bestimmen Sie auch, ob eine Anfrage gestellt werden soll
if 'nextToken' in response.keys():
next_token = response['nextToken']
else:
should_continue = False
return log_groups
def create_export_task(client,log_groups):
'''
Verschieben Sie den Protokollinhalt nach s3
'''
#Aktuelle Zeit abrufen und in UNIX-Zeit konvertieren
time_now = datetime.datetime.now()
unix_time_now = int(time_now.timestamp())
#Wiederholen Sie diesen Vorgang für die Anzahl der Protokollgruppen
for log in log_groups:
for x in range(20):
try:
response = client.create_export_task(
fromTime=0,
to=unix_time_now,
logGroupName=log['logGroupName'],
destination=S3_BUCKET,
destinationPrefix=S3_DIR
)
except:
#Wenn Sie bereits eine Aufgabe haben, warten Sie einen Moment und versuchen Sie es erneut
time.sleep(20)
continue
Geben Sie in der oben definierten Variablen PREFIX die erste Zeichenfolge der Protokollgruppe an, in die Sie die Protokolle migrieren möchten. Hier wird das Protokoll der Protokollgruppe, die mit "test-" beginnt, auf S3 verschoben.
Die Funktion main () wird zur Laufzeit aufgerufen. Diese Funktion ruft die folgenden zwei Funktionen der Reihe nach auf.
Legen Sie abschließend den Bucket von S3 fest, in den Sie das Protokoll exportieren möchten. Legen Sie den folgenden JSON als Richtlinie fest.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "*"
}
]
}
Wenn Sie vergessen, dies anzugeben, wird der Fehler ** ** Beim Aufrufen der Operation CreateExportTask ist ein Fehler aufgetreten (InvalidParameterException): Der Aufruf von GetBucketAcl für den angegebenen Bucket ist fehlgeschlagen. Überprüfen Sie, ob CloudWatch Logs die Berechtigung zum Ausführen dieser Operation erteilt wurde. "** Tritt auf, wenn Lambda-Funktionen ausgeführt werden. Ich war verwirrt, weil die Fehlermeldung irreführend war, als wäre es ein Problem mit den CloudWatch-Protokolleinstellungen.
Wenn Sie CloudWatchs Cron verwenden, um die erstellte Lambda-Funktion so einzustellen, dass sie regelmäßig ausgeführt wird, können Sie beispielsweise CloudWatch-Protokolle jeden Tag nach S3 verschieben.
Es gibt jedoch eine Einschränkung. Die Protokoll-Exportaufgabe ist zeitaufwändig. Wenn Sie also versuchen, 10 oder mehr Protokollgruppen gleichzeitig zu exportieren, dauert dies mehr als 15 Minuten. Dies ist die maximale Ausführungszeit von Lambda. Es ist unpraktisch.
Wenn Sie viele Protokolle gleichzeitig nach s3 verschieben möchten, ist es möglicherweise besser, sie als Cron-Job in EC2 auszuführen, anstatt Lambda zu verwenden.
Recommended Posts