Anzeigen von CloudWatch-Protokollen für Lambda-Funktionen - AWS Lambda

Anzeigen von CloudWatch-Protokollen für Lambda-Funktionen

Sie können die Amazon CloudWatch Logs für Ihre Lambda-Funktion über die Lambda-Konsole, die CloudWatch-Konsole oder das AWS Command Line Interface (AWS CLI) anzeigen. Folgen Sie den Anweisungen in den folgenden Abschnitten, um auf die Protokolle Ihrer Funktion zuzugreifen.

Streamen Sie Funktionsprotokolle mit CloudWatch Logs Live Tail

Amazon CloudWatch Logs Live Tail hilft Ihnen bei der schnellen Behebung von Problemen, indem eine Streamingliste neuer Protokollereignisse direkt in der Lambda-Konsole angezeigt wird. Sie können die von Ihren Lambda-Funktionen aufgenommenen Protokolle in Echtzeit anzeigen und filtern, sodass Sie Probleme schnell erkennen und beheben können.

Anmerkung

Bei Live Tail-Sitzungen fallen Kosten pro Minute an. Weitere Informationen zu Preisen finden Sie unter Amazon CloudWatch – Preise.

Vergleich von Live Tail und --log-type Tail

Es gibt mehrere Unterschiede zwischen CloudWatch Logs Live Tail und der Option LogType: Tail in der Lambda-API (--log-type Tail in der AWS CLI):

  • --log-type Tail gibt nur die ersten 4 KB der Aufruf-Logs zurück. Live Tail hat dieses Limit nicht gemeinsam und kann bis zu 500 Protokollereignisse pro Sekunde empfangen.

  • --log-type Tail erfasst und sendet die Protokolle zusammen mit der Antwort, was sich auf die Antwortlatenz der Funktion auswirken kann. Live Tail hat keinen Einfluss auf die Reaktionslatenz der Funktionen.

  • --log-type Tail unterstützt nur synchrone Aufrufe. Live Tail funktioniert sowohl für synchrone als auch für asynchrone Aufrufe.

Berechtigungen

Die folgenden Berechtigungen sind erforderlich, um CloudWatch Logs Live Tail-Sitzungen zu starten und zu beenden:

  • logs:DescribeLogGroups

  • logs:StartLiveTail

  • logs:StopLiveTail

Starten einer Live-Tail-Sitzung in der Lambda-Konsole

  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Wählen Sie den Namen einer Funktion aus.

  3. Wählen Sie die Registerkarte Test.

  4. Wählen Sie im Bereich Testereignis die Option CloudWatch Logs Live Tail aus.

  5. Für Protokollgruppen auswählen ist standardmäßig die Protokollgruppe der Funktion ausgewählt. Sie können bis zu fünf Protokollgruppen gleichzeitig auswählen.

  6. (Optional) Um nur Protokollereignisse anzuzeigen, die bestimmte Wörter oder andere Zeichenfolgen enthalten, geben Sie das Wort oder die Zeichenfolge in das Feld Filtermuster hinzufügen ein. Im Feld „Filter“ wird zwischen Groß- und Kleinschreibung unterschieden. Sie können mehrere Begriffe und Musteroperatoren in dieses Feld eingeben, einschließlich regulärer Ausdrücke (regex). Weitere Informationen zur Mustersyntax finden Sie unter Filtermustersyntax im Benutzerhandbuch zu Amazon CloudWatch Logs.

  7. Wählen Sie Starten. Im Fenster werden nun übereinstimmende Protokollereignisse angezeigt.

  8. Zum Beenden der Live-Tail-Sitzung wählen Sie Stoppen.

    Anmerkung

    Die Live-Tail-Sitzung wird automatisch nach 15 Minuten Inaktivität oder nach Ablauf der Zeit für die Lambda-Konsolensitzung beendet.

Zugriff auf Funktionsprotokolle über die Konsole

  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Wählen Sie eine Funktion aus.

  3. Wählen Sie den Tab Überwachung.

  4. Wählen Sie CloudWatch-Protokolle anzeigen, um die CloudWatch-Konsole zu öffnen.

  5. Scrollen Sie nach unten und wählen Sie den Protokollstream für die Funktionsaufrufen aus, die Sie sich ansehen möchten.

    Liste der Protokollstreams für eine Lambda-Funktion.

Jede Instance einer Lambda-Funktion hat einen eigenen Protokollstream. Wenn eine Funktion skaliert wird, hat jede gleichzeitige Instance ihren eigenen Protokollstream. Jedes Mal, wenn als Reaktion auf einen Aufruf eine neue Ausführungsumgebung erstellt wird, wird ein neuer Protokollstream generiert. Die Benennungskonvention für Protokollstreams lautet:

YYYY/MM/DD[Function version][Execution environment GUID]

Eine einzelne Ausführungsumgebung schreibt während ihrer Lebensdauer in denselben Protokollstream. Der Protokollstream enthält Nachrichten aus dieser Ausführungsumgebung sowie alle Ausgaben aus dem Code Ihrer Lambda-Funktion. Jede Nachricht wird mit einem Zeitstempel versehen, auch Ihre benutzerdefinierten Protokolle. Selbst wenn Ihre Funktion keine Ausgabe Ihres Codes protokolliert, werden pro Aufruf mindestens drei Protokollanweisungen generiert (START, END und REPORT):

Überwachung der Beobachtbarkeit Abbildung 3

Aus diesen Protokollen geht Folgendes hervor:

  • RequestId: Dies ist eine eindeutige ID, die pro Anfrage generiert wird. Wenn die Lambda-Funktion eine Anfrage erneut versucht, ändert sich diese ID nicht und erscheint in den Protokollen für jeden weiteren Versuch.

  • Start/Ende: Diese setzen ein Lesezeichen für einen einzelnen Aufruf, sodass jede Protokollzeile zwischen diesen Aufrufen zu demselben Aufruf gehört.

  • Dauer: Die gesamte Aufrufzeit für die Handler-Funktion, ohne INIT-Code.

  • Dauer der Abrechnung: Wendet die Rundungslogik für Abrechnungszwecke an.

  • Speichergröße: Die der Funktion zugewiesene Speichermenge.

  • Maximal genutzter Speicher: Der maximale während des Aufrufs genutzte Speicher.

  • Initialisierungsdauer: Die Zeit, die benötigt wurde, um den INIT-Codeabschnitt außerhalb des Haupthandlers auszuführen.

Zugriff auf Protokolle mit der AWS CLI

Die AWS CLI ist ein Open-Source-Tool, mit dem Sie über Befehle in Ihrer Befehlszeilen-Shell mit den AWS-Services interagieren können. Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie AWS CLI Version 2.

Sie können die AWS CLI verwenden, um Protokolle für einen Aufruf mit der --log-type-Befehlsoption abzurufen. Die Antwort enthält das Feld LogResult, das bis zu 4 KB base64-verschlüsselte Protokolle aus dem Aufruf enthält.

Beispiel eine Log-ID abrufen

Das folgende Beispiel zeigt, wie eine Protokoll-ID aus dem LogResult-Feld für eine Funktion namens my-function abgerufen wird.

aws lambda invoke --function-name my-function out --log-type Tail

Die Ausgabe sollte folgendermaßen aussehen:

{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
Beispiel entschlüsseln der Protokolle

Verwenden Sie in derselben Eingabeaufforderung das base64-Dienstprogramm, um die Protokolle zu entschlüsseln. Das folgende Beispiel zeigt, wie Base64-codierte Logs für abgerufen werde my-function.

aws lambda invoke --function-name my-function out --log-type Tail \ --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode

Die cli-binary-format-Option ist erforderlich, wenn Sie AWS CLI Version 2 verwenden. Um dies zur Standardeinstellung zu machen, führen Sie aws configure set cli-binary-format raw-in-base64-out aus. Weitere Informationen finden Sie unter Von AWS CLI unterstützte globale Befehlszeilenoptionen im AWS Command Line Interface-Benutzerhandbuch für Version 2.

Die Ausgabe sollte folgendermaßen aussehen:

START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB

Das base64-Dienstprogramm ist unter Linux, macOS und Ubuntu auf Windowsverfügbar. macOS-Benutzer müssen möglicherweise base64 -D verwenden.

Beispiel get-logs.sh-Skript

Verwenden Sie in derselben Eingabeaufforderung das folgende Skript, um die letzten fünf Protokollereignisse herunterzuladen. Das Skript verwendet sed zum Entfernen von Anführungszeichen aus der Ausgabedatei und wechselt 15 Sekunden lang in den Ruhezustand, um Zeit einzuräumen, damit Protokolle verfügbar werden können. Die Ausgabe enthält die Antwort von Lambda und die get-log-eventsAusgabe des Befehls.

Kopieren Sie den Inhalt des folgenden Codebeispiels und speichern Sie es in Ihrem Lambda-Projektverzeichnis unter get-logs.sh.

Die cli-binary-format-Option ist erforderlich, wenn Sie AWS CLI Version 2 verwenden. Um dies zur Standardeinstellung zu machen, führen Sie aws configure set cli-binary-format raw-in-base64-out aus. Weitere Informationen finden Sie unter Von AWS CLI unterstützte globale Befehlszeilenoptionen im AWS Command Line Interface-Benutzerhandbuch für Version 2.

#!/bin/bash aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out sed -i'' -e 's/"//g' out sleep 15 aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
Beispiel macOS und Linux (nur diese Systeme)

In derselben Eingabeaufforderung müssen macOS- und Linux-Benutzer möglicherweise den folgenden Befehl ausführen, um sicherzustellen, dass das Skript ausführbar ist.

chmod -R 755 get-logs.sh
Beispiel die letzten fünf Protokollereignisse abrufen

Führen Sie an derselben Eingabeaufforderung das folgende Skript aus, um die letzten fünf Protokollereignisse abzurufen.

./get-logs.sh

Die Ausgabe sollte folgendermaßen aussehen:

{ "StatusCode": 200, "ExecutedVersion": "$LATEST" } { "events": [ { "timestamp": 1559763003171, "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n", "ingestionTime": 1559763003309 }, { "timestamp": 1559763003173, "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003173, "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r \"key\": \"value\"\r}\n", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003218, "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n", "ingestionTime": 1559763018353 }, { "timestamp": 1559763003218, "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n", "ingestionTime": 1559763018353 } ], "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795", "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080" }

Parsing von Protokollen und strukturierte Protokollierung

Mit CloudWatch Logs Insights können Sie Protokolldaten mithilfe einer speziellen Abfragesyntax suchen und analysieren. Es führt Abfragen über mehrere Protokollgruppen durch und bietet eine leistungsstarke Filterung mithilfe von Mustervergleichen mit Glob- und regulären Ausdrücken.

Sie können diese Funktionen nutzen, indem Sie strukturierte Protokollierung in Ihren Lambda-Funktionen implementieren. Strukturierte Protokollierung organisiert Ihre Protokolle in einem vordefinierten Format, wodurch die Abfrage vereinfacht wird. Die Verwendung von Protokollebenen ist ein wichtiger erster Schritt zur Erstellung filterfreundlicher Protokolle, die Informationsmeldungen von Warnungen oder Fehlern trennen. Betrachten Sie beispielsweise den folgenden Node.js-Code:

exports.handler = async (event) => { console.log("console.log - Application is fine") console.info("console.info - This is the same as console.log") console.warn("console.warn - Application provides a warning") console.error("console.error - An error occurred") }

Die resultierende CloudWatch-Protokolldatei enthält ein separates Feld, das die Protokollebene angibt:

Überwachung der Beobachtbarkeit Abbildung 10

Eine Abfrage von CloudWatch Logs Insights kann dann nach Protokollebene filtern. Um beispielsweise nur nach Fehlern zu suchen, können Sie die folgende Abfrage verwenden:

fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc

JSON-strukturierte Protokollierung

JSON wird häufig verwendet, um Anwendungsprotokolle zu strukturieren. Im folgenden Beispiel wurden die Protokolle in JSON konvertiert, um drei unterschiedliche Werte auszugeben:

Überwachung der Beobachtbarkeit Abbildung 11

Das Feature CloudWatch Logs Insights erkennt automatisch Werte in der JSON-Ausgabe und parst die Nachrichten als Felder, ohne dass ein benutzerdefinierter glob oder regulärer Ausdruck erforderlich ist. Unter Verwendung der JSON-strukturierten Protokolle findet die folgende Abfrage Aufrufe, bei denen die hochgeladene Datei größer als 1 MB war, die Upload-Zeit mehr als 1 Sekunde betrug und der Aufruf kein Kaltstart war:

fields @message | filter @message like /INFO/ | filter uploadedBytes > 1000000 | filter uploadTimeMS > 1000 | filter invocation != 1

Diese Abfrage könnte folgendes Ergebnis liefern:

Überwachung der Beobachtbarkeit Abbildung 12

Die in JSON erkannten Felder werden automatisch im Menü Erkannte Felder auf der rechten Seite ausgefüllt. Den vom Lambda-Dienst ausgegebenen Standardfeldern ist ein „@“ vorangestellt und Sie können diese Felder auf die gleiche Weise abfragen. Lambda-Protokolle enthalten immer die Felder @timestamp, @logStream, @message, @requestId, @duration, @billedDuration, @type, @maxMemoryUsed, @memorySize. Wenn X-Ray für eine Funktion aktiviert ist, enthalten die Protokolle auch @xrayTraceId und @xraySegmentId.

Wenn eine AWS-Ereignisquelle wie Amazon S3, Amazon SQS oder Amazon EventBridge Ihre Funktion aufruft, wird das gesamte Ereignis der Funktion als JSON-Objekt-Eingabe bereitgestellt. Indem Sie dieses Ereignis in der ersten Zeile der Funktion protokollieren, können Sie dann mit CloudWatch Logs Insights jedes der verschachtelten Felder abfragen.

Nützliche Insights-Abfragen

Die folgende Tabelle zeigt Beispiele für Insights-Abfragen, die für die Überwachung von Lambda-Funktionen nützlich sein können.

Beschreibung Beispiel für Abfragesyntax

Die letzten 100 Fehler

 fields Timestamp, LogLevel, Message
 | filter LogLevel == "ERR"
 | sort @timestamp desc
 | limit 100

Die 100 Aufrufe mit den höchsten Abrechnungen

filter @type = "REPORT"
| fields @requestId, @billedDuration
| sort by @billedDuration desc
| limit 100

Prozentualer Anteil der Kaltstarts an der Gesamtzahl der Aufrufe

filter @type = "REPORT"
| stats sum(strcontains(@message, "Init Duration"))/count(*) * 100 as
  coldStartPct, avg(@duration)
  by bin(5m)

Perzentilbericht zur Lambda-Dauer

filter @type = "REPORT"
| stats
    avg(@billedDuration) as Average,
    percentile(@billedDuration, 99) as NinetyNinth,
    percentile(@billedDuration, 95) as NinetyFifth,
    percentile(@billedDuration, 90) as Ninetieth
    by bin(30m)

Perzentilbericht zur Lambda-Speichernutzung

filter @type="REPORT"
| stats avg(@maxMemoryUsed/1024/1024) as mean_MemoryUsed,
    min(@maxMemoryUsed/1024/1024) as min_MemoryUsed,
    max(@maxMemoryUsed/1024/1024) as max_MemoryUsed,
    percentile(@maxMemoryUsed/1024/1024, 95) as Percentile95

Aufrufe, die 100 % des zugewiesenen Speichers beanspruchen

filter @type = "REPORT" and @maxMemoryUsed=@memorySize
| stats
    count_distinct(@requestId)
    by bin(30m)

Durchschnittlicher Speicherverbrauch bei Aufrufen

avgMemoryUsedPERC,
    avg(@billedDuration) as avgDurationMS
    by bin(5m)

Visualisierung von Speicherstatistiken

filter @type = "REPORT"
| stats
    max(@maxMemoryUsed / 1024 / 1024) as maxMemMB,
    avg(@maxMemoryUsed / 1024 / 1024) as avgMemMB,
    min(@maxMemoryUsed / 1024 / 1024) as minMemMB,
    (avg(@maxMemoryUsed / 1024 / 1024) / max(@memorySize / 1024 / 1024)) * 100 as avgMemUsedPct,
    avg(@billedDuration) as avgDurationMS
    by bin(30m)

Aufrufe, bei denen Lambda beendet wurde

filter @message like /Process exited/
| stats count() by bin(30m)

Aufrufe mit Zeitüberschreitung

filter @message like /Task timed out/
| stats count() by bin(30m)

Latenzbericht

filter @type = "REPORT"
| stats avg(@duration), max(@duration), min(@duration)
  by bin(5m)

Übermäßig bereitgestellter Arbeitsspeicher

filter @type = "REPORT"
| stats max(@memorySize / 1024 / 1024) as provisonedMemMB,
        min(@maxMemoryUsed / 1024 / 1024) as smallestMemReqMB,
        avg(@maxMemoryUsed / 1024 / 1024) as avgMemUsedMB,
        max(@maxMemoryUsed / 1024 / 1024) as maxMemUsedMB,
        provisonedMemMB - maxMemUsedMB as overProvisionedMB

Protokollvisualisierung und Dashboards

Für jede Abfrage mit CloudWatch Logs Insights können Sie die Ergebnisse im Markdown- oder CSV-Format exportieren. In einigen Fällen kann es sinnvoller sein, Visualisierungen aus Abfragen zu erstellen, sofern mindestens eine Aggregationsfunktion vorhanden ist. Mit der stats-Funktion können Sie Aggregationen und Gruppierungen definieren.

Das vorherige logInsightsJSON-Beispiel hat nach Upload-Größe und Upload-Zeit gefiltert und erste Aufrufe ausgeschlossen. Dies führte zu einer Datentabelle. Für die Überwachung eines Produktionssystems kann es sinnvoller sein, die minimalen, maximalen und durchschnittlichen Dateigrößen zu visualisieren, um Ausreißer zu erkennen. Wenden Sie dazu die Statistikfunktion mit den erforderlichen Aggregaten an und gruppieren Sie nach einem Zeitwert, z. B. jede Minute:

Nehmen Sie beispielsweise die folgende Abfrage. Dies ist dieselbe Beispielabfrage wie im Abschnitt JSON-strukturierte Protokollierung, jedoch mit zusätzlichen Aggregationsfunktionen:

fields @message | filter @message like /INFO/ | filter uploadedBytes > 1000000 | filter uploadTimeMS > 1000 | filter invocation != 1 | stats min(uploadedBytes), avg(uploadedBytes), max(uploadedBytes) by bin (1m)

Wir haben diese Aggregate aufgenommen, da es möglicherweise hilfreicher ist, die minimalen, maximalen und durchschnittlichen Dateigrößen zu visualisieren, um Ausreißer zu finden. Sie können die Ergebnisse auf der Registerkarte Visualisierung einsehen:

Überwachung der Beobachtbarkeit Abbildung 14

Nachdem Sie die Visualisierung erstellt haben, können Sie das Diagramm optional zu einem CloudWatch-Dashboard hinzufügen. Wählen Sie dazu oberhalb der Visualisierung die Option Zum Dashboard hinzufügen aus. Dadurch wird die Abfrage als Widget hinzugefügt und Sie können automatische Aktualisierungsintervalle auswählen, was die kontinuierliche Überwachung der Ergebnisse erleichtert:

Überwachung der Beobachtbarkeit Abbildung 15