[PYTHON] Eine Geschichte, die ich behoben habe, als ich das Lambda-Protokoll von Cloudwatch Logs erhalten habe

Es ist der 21. Tag von cloudpack Ara Convenient Calendar 2017!


Ich habe Python verwendet, um Lambda-Protokolle aus Cloudwatch-Protokollen abzurufen. Als ich kürzlich versuchte, es zu bekommen, bekam ich einen Fehler, also versuchte ich, es ein wenig zu beheben.


Geschichte vor etwa einem halben Jahr

Zuvor dachte ich daran, Lambda-Protokolle in Cloudwatch-Protokollen für geschäftliche Zwecke auf einen Server (EC2) zu übertragen und verschiedene Dinge zu untersuchen. Protokolle aus CloudWatch-Protokollen abrufen (ich habe versucht, den Zeitraum anzugeben) Ich habe es in Bezug auf das in der Entwicklung befindliche System erstellt und es verwendet, um es zu untersuchen. Das war sehr hilfreich. Vielen Dank! Wir möchten diese Gelegenheit nutzen, um Ihnen zu danken.

Das Problem tritt auf, nachdem es nach langer Zeit verwendet wurde

Ich habe es eine Weile nicht benutzt

Vom Benutzer

Holen Sie sich für einen Moment ein Protokoll dieser Tageszeit

Das heißt, es ist mühsam, alles auf einmal von der Konsole zu nehmen. Verwenden Sie die, die Sie zuvor gemacht haben? Ich habe es nach langer Zeit versucht. .. .. Es hört nie auf. Selbst wenn Sie 1 Minute angeben, endet es nicht. Warum nicht? !! Ich habe versucht, das Protokoll einzufügen und nachzuschlagen. .. ..

** Versuch, aus einem Vollzeit-Stream zu entnehmen. .. .. ** ** **

Es ist ungefähr 3 Monate her, seit es in Betrieb genommen wurde, und mit einigen Protokollen. Es ist ein überstrichenes Protokoll der gesamten Periode, das Zeit braucht. Es war in einem solchen Zustand.

Renovierung

Ich konnte es nicht so bekommen, wie es ist ... Also beschloss ich, es zu reparieren, recherchierte verschiedene Dinge und sah mir schließlich das SDK-Dokument an. Von der Methode zum Abrufen des Protokolldatenstroms describe_log_streams Als Argument von Ich habe festgestellt, dass ich den Protokoll-Stream-Namen als Präfix angeben kann. Boto 3 Documentation - describe_log_streams Bei Lambda-Protokollen können Sie das Datum hier eingrenzen! Fügen Sie dem Laufzeitargument also ein Datum hinzu (Fokus auf Entwicklungsgeschwindigkeit). Es wurde eine Änderung implementiert, die dem Argument von description_log_streams hinzugefügt werden soll Lauf! ... Es endete in einem Augenblick (wenn auch nicht so schnell).

Quelle nach der Sanierung

getCwLogs.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import sys
import codecs
import boto3
import time
from datetime import datetime
from datetime import timedelta

sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
log_group = sys.argv[1]
date = datetime.now().strftime("%Y%m%d-%H%M%S")
#Ausgabe Verzeichnis
log_directory_base ='./cwlogs'
slice = log_group[0:1]
if (slice == '/'):
    log_directory = log_directory_base + "%s/%s" % (log_group, date)
else:
    log_directory = log_directory_base + "/%s/%s" % (log_group, date)

def validate():
    if(len(sys.argv) != 5):
        print '[ ERROR ] Few arguments.'
        print 'Please specify the argument.'
        print 'First: LogGroupName, Second: StartTime, Third: EndTime, Fourth: profileName., Fifth: logPrefixName'
        sys.exit()
    try:
        epoc = datetime(1970, 1, 1)
        global starttime
        starttime  = int((datetime.strptime(sys.argv[2], '%Y-%m-%dT%H:%M:%S') - epoc).total_seconds()) * 1000
        global endtime
        endtime  = int((datetime.strptime(sys.argv[3], '%Y-%m-%dT%H:%M:%S') - epoc).total_seconds()) * 1000
        durationtime = int(endtime - starttime)
        print 'durationtime "%s"' % durationtime
        if 86400000 < durationtime:
            print '[ ERROR ] Too long duration.'
            print 'Max duration is 1 day.'
            sys.exit()
        global log_stream_name_prefix
        log_stream_name_prefix = sys.argv[4]
    except ValueError:
        print '[ ERROR ] Failed StartTime or EndTime format.'
        print 'Date Format is "%Y-%m-%dT%H:%M:%S".'
        sys.exit()

def find_streams(token, log_stream_name_prefix):
    def is_valid_stream(stream):
        return starttime < stream.get('lastIngestionTime')
    try:
        if token is None:
            data =  cwlogs.describe_log_streams(logGroupName = log_group, logStreamNamePrefix = log_stream_name_prefix)
        else:
            data =  cwlogs.describe_log_streams(logGroupName = log_group, logStreamNamePrefix = log_stream_name_prefix, nextToken = token)

    except ValueError:
        print '[ ERROR ] Failed LogGroupName is invalid.'
        print '"%s" is not found.' % log_group
        sys.exit()

    streams = filter(is_valid_stream, data['logStreams'])
    if 'nextToken' not in data:
        return streams
    time.sleep(0.5)
    streams.extend(find_streams(data['nextToken'], log_stream_name_prefix))
    return streams

def find_events(token, last_token, stream):
    print 'logGroupName = "%s", logStreamName = "%s", startTime = "%s", endTime = "%s"' % (log_group, stream, starttime, endtime)
    if token is None:
        data = cwlogs.get_log_events(logGroupName = log_group, logStreamName = stream, startTime = starttime, endTime = endtime, startFromHead = True)
    else:
        data = cwlogs.get_log_events(logGroupName = log_group, logStreamName = stream, startTime = starttime, endTime = endtime, startFromHead = True, nextToken = token)

    events = data['events']
    if events:
        write_logs(events, stream)
        del events[:]
    if data['nextForwardToken'] != last_token:
        time.sleep(0.5)
        find_events(data['nextForwardToken'], token, stream)

def write_logs(events, stream):
    streams = stream.split(']');
    if (len(streams) > 1):
        #Lambda-Protokoll
        with codecs.open("%s/%s.log" % (log_directory, streams[1]), "a", "utf-8") as f:
            for e in events:
                f.write("%s\n" % e['message'])
    else:
        #Andere Protokolle
        with codecs.open("%s/%s.log" % (log_directory, streams[0]), "a", "utf-8") as f:
            for e in events:
                f.write("%s\n" % e['message'])

def main():
    validate()
    global cwlogs
    cwlogs = boto3.client('logs')
    streams = [stream['logStreamName'] for stream in find_streams(None, log_stream_name_prefix)]
    os.makedirs("%s/" %)
    print(log_directory)

    for stream in streams:
        find_events(None, None, stream)

if __name__ == '__main__':
    main()


cmd


#Für Lambda
python getCWLogs.Startdatum und -zeit des py-Protokollgruppennamens(UTC)Enddatum und -zeit(UTC)Erstes Datum des Protokoll-Stream-Namens
#Anders als Lambda(API-Gateway)Im Falle von
python getCWLogs.Startdatum und -zeit des py-Protokollgruppennamens(UTC)Enddatum und -zeit(UTC)Name des Protokolldatenstroms

Aktuelle Nutzung

Ich verwende es, wenn ich das Lambda-Protokoll für einen bestimmten Zeitraum abrufen, mit grep durchsuchen oder mit Excel aggregieren möchte (es wird).


Ich habe es eine Weile geschrieben, aber Ist es nützlich für andere Menschen? Es war eine typische Geschichte.

Recommended Posts

Eine Geschichte, die ich behoben habe, als ich das Lambda-Protokoll von Cloudwatch Logs erhalten habe
Eine Geschichte, die ich süchtig danach war, Lambda von AWS Lambda anzurufen.
Eine Geschichte, die unter einem Unterschied im Betriebssystem litt, als sie versuchte, ein Papier zu implementieren
Eine Geschichte, der ich nach der SFTP-Kommunikation mit Python verfallen war
Eine Geschichte, die praktisch war, als ich versuchte, das Python-IP-Adressmodul zu verwenden
Eine Geschichte, die beim Versuch, die Python-Version mit GCE zu aktualisieren, hängen blieb
Lambda-Funktion (Python-Version), die Elemente dekomprimiert und in CloudWatch-Protokolle ausgibt, wenn eine komprimierte Datei auf s3 hochgeladen wird
Ich habe einen UnicodeDecodeError erhalten, als ich auf Ubuntu Pip installiert habe
Eine Geschichte, von der ich bei np.where süchtig war
Ich habe einen sqlite3.OperationalError
Eine Geschichte, die verschwunden ist, als ich einen Pfad angegeben habe, der mit tilda (~) in Python Open beginnt
Python-Bedingungsextraktion aus der Liste, die ich oft vergesse
[Python] Exportieren Sie regelmäßig mit Lambda aus CloudWatch-Protokollen nach S3
Eine Geschichte, die nicht funktioniert hat, als ich versucht habe, mich mit dem Python-Anforderungsmodul anzumelden
Verschieben Sie CloudWatch-Protokolle regelmäßig mit Lambda nach S3
Ich habe einen TypeError: 'int'-Objekt ist bei Verwendung von Keras nicht iterierbar
Die Geschichte, dass ein Hash-Fehler bei der Verwendung von Pipenv auftrat
Ich stieß auf einen Lambda-Ausdruck, als ich mir Sorgen um die Funktionalisierung machte
Ich habe in Python einen Discord-Bot erstellt, der übersetzt, wenn er reagiert
Ich habe versucht, einen Formatierer zu entwickeln, der Python-Protokolle in JSON ausgibt
Ich habe einen einfachen Timer erstellt, der vom Terminal aus gestartet werden kann
Eine Erinnerung an das, was ich beim Starten von Atcoder mit Python feststeckte
[Webserver] Eine Geschichte, als ich nachforschte, weil ich nicht auf nginx zugreifen konnte
Ich habe einen Slack-Bot geschrieben, der Verzögerungsinformationen mit AWS Lambda benachrichtigt