[PYTHON] Der erste Schritt, um langsame Abfragen loszuwerden! Ich habe versucht, Chatwork mit Lambda und AWS CLI v2 über langsame Abfragen für RDS for MySQL zu informieren

Einführung

Hallo. Als Infrastrukturmanager bei Mikatus Co., Ltd. bin ich verantwortlich für den Bau, den Betrieb und die Wartung der Infrastruktur usw. mit Schwerpunkt AWS. Dieses Mal werde ich über das Benachrichtigen von Chatwork über langsame MySQL-Abfragen schreiben.

Unser System verwendet Amazon RDS für MySQL und wir haben ein Überwachungstool verwendet, um das Auftreten langsamer Abfragen zu überwachen, aber Chatwork, damit wir durch Benachrichtigungen in Echtzeit kontinuierliche Verbesserungen erzielen können. Ich habe versucht zu benachrichtigen. Neulich AWS CLI v2-Vorschau-Version wurde angekündigt, also ist es eine große Sache, also CLI v2 AWS zu verwenden Ich habe versucht, eine Ressource zu erstellen.

Über diesen Artikel

Dieser Artikel enthält Schritte zum Arbeiten mit AWS Lambda-Einstellungen und Amazon CloudWatch-Protokolleinstellungen mit AWS CLI v2. Die detaillierten Schritte der Amazon RDS-Protokollexportfunktion und der Chatwork-API-Einstellungen werden nicht behandelt.

Tatsächlicher Inhalt der Chatwork-Benachrichtigung

Dies wird Chatwork schließlich mitgeteilt. Bot veröffentlicht den Inhalt der langsamen Abfrage im Gruppenchat, an dem die betroffenen Parteien teilnehmen. slowquery.png Grundsätzlich wird die Ausgabe von Inhalten in CloudWatch-Protokolle unverändert ausgegeben. Da das langsame Abfrageprotokoll nur für die Zeit in UTC ausgegeben wird, wird es zur Benachrichtigung in JST konvertiert.

Überblick über die Verarbeitung

post-slowquery-to-chatwork.png Die Ausgabe von RDS in CloudWatch-Protokolle erfolgt über RDS Log Export Function ) Wird genutzt. CloudWatch Logs verwendet Abonnementfilter (https://docs.aws.amazon.com/de_jp/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample), um sie an Lambda-Funktionen zu senden und in Python zu schreiben. Die Funktion analysiert die Protokollnachricht und benachrichtigt Chatwork. Sie können die langsame Abfrageausgabe an CloudWatch-Protokolle mit der long_query_time der RDS-Parametergruppe steuern. Die RDS-Einstellung ist jedoch relativ locker und die Lambda-Seite legt einen Schwellenwert fest, damit sie gesteuert werden kann. (Dieses Mal habe ich die RDS long_query_time auf "5" Sekunden und den Lambda-Schwellenwert auf "10" Sekunden gesetzt.)

die Einstellungen

Ich werde den Inhalt des Sets beschreiben.

Installieren von AWS CLI v2

Installieren Sie AWS CLI v2 auf Ihrem Mac. Klicken Sie hier, um den Installationsvorgang zu starten Bitte beachten Sie, dass es sich immer noch um eine Vorschau-Version handelt. Verwenden Sie sie daher nicht in einer Produktionsumgebung.

AWS CLI Version 2 wird für die Testvorschau und -auswertung bereitgestellt. Derzeit empfehlen wir, es nicht in einer Produktionsumgebung zu verwenden.

Die folgende Version wurde installiert.

$ aws2 --version
aws-cli/2.0.0dev2 Python/3.7.4 Darwin/17.7.0 botocore/2.0.0dev1

Als Eindruck hat CLI v1 eine gewisse Abhängigkeit von der Python-Version, daher dauerte die Einführung einige Zeit, aber CLI v2 hat die Installation ohne Python erheblich vereinfacht.

Erstellen Sie eine IAM-Rolle

Wert einstellen

--Rollenname

Rollenerstellung

$ IAM_ROLE_POLICY_DOC="iam-role-policy.json"

#Legen Sie Lambda als vertrauenswürdige Entität fest
$ cat <<EOF > ${IAM_ROLE_POLICY_DOC}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

$ IAM_ROLE_NAME="post-slowquery-to-chatwork-LambdaRole"
$ IAM_POLICY_ARN="arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"

#Erstellen Sie eine IAM-Rolle
$ aws2 iam create-role \
    --role-name ${IAM_ROLE_NAME} \
    --assume-role-policy-document file://./${IAM_ROLE_POLICY_DOC}

#Rufen Sie die ARN der von Ihnen erstellten IAM-Rolle ab
$ IAM_ROLE_ARN=`aws2 iam get-role \
    --role-name ${IAM_ROLE_NAME} \
    --query 'Role.Arn' \
    --output text`

#Fügen Sie der IAM-Rolle AWSLambdaBasicExecutionRole hinzu
$ aws2 iam attach-role-policy \
    --role-name ${IAM_ROLE_NAME} \
    --policy-arn ${IAM_POLICY_ARN}

Erstellen Sie eine Lambda-Funktion

Die Laufzeit verwendet python3.7.

Code

lambda_function.py


import json
import base64
import gzip
import re
import os
import datetime
import urllib
import urllib.request

LONG_QUERY_TIME = int(os.environ['LONG_QUERY_TIME'])

chatwork_endpoint = "https://api.chatwork.com/v2"
chatwork_apikey = os.environ['chatwork_apikey']
chatwork_roomid = os.environ['chatwork_roomid']
path = "/rooms/{0}/messages".format(chatwork_roomid)

def lambda_handler(event, context):
    print(json.dumps(event))
    #Extrahieren Sie den Inhalt, da er in Base64 codiert und im gzip-Format komprimiert ist.
    log_events = json.loads(gzip.decompress(base64.b64decode(event['awslogs']['data'])))
    db_name = log_events['logStream']
    message = log_events['logEvents'][0]['message']
    #Extrahieren Sie die Abfragezeit aus dem Protokoll
    query_time = re.search(r'Query_time: ([0-9]+.[0-9]+)', message)

    #Wenn es größer als die von der Umgebungsvariablen angegebene Zeit ist(Diesmal 10 Sekunden oder länger)Benachrichtigen
    if LONG_QUERY_TIME < float(query_time.group(1)):
        timestamp = re.search(r'timestamp=([0-9]+);', message)
        #Zeitstempel in JST-Zeit konvertieren
        date = datetime.datetime.fromtimestamp(int(timestamp.group(1))) + datetime.timedelta(hours=9)
        log_message = re.sub(r'# Time:.*\n', '# Time: %s(JST)\n' % str(date), message)
        post_to_chatwork({'body': '[info][title]%s[/title]%s[/info]' % (db_name, log_message)})

def post_to_chatwork(data=None):
    try:
        if data != None:
            data = urllib.parse.urlencode(data).encode('utf-8')
            headers = {"X-ChatWorkToken": chatwork_apikey}
            req = urllib.request.Request(chatwork_endpoint + path, data=data, headers=headers)
        with urllib.request.urlopen(req) as res:
            print(res.read().decode("utf-8"))
            return
    except urllib.error.HTTPError as e:
        print('Error code: %s' % (e.code))
        sys.exit('post_to_chatwork Error')

Umgebungsvariable

Erstellung der Lambda-Funktion

$ LAMBDA_FUNCTION_NAME="post-slowquery-to-chatwork"
$ LAMBDA_RUNTIME="python3.7"
$ LAMBDA_ZIP_FILE="${LAMBDA_FUNCTION_NAME}.zip"
$ LAMBDA_HANDLER="lambda_function.lambda_handler"
$ LAMBDA_ENV="{\
    LONG_QUERY_TIME=10,\
    chatwork_apikey=XXXXX,\
    chatwork_roomid=XXXXX}"

#Zippen Sie den Code
$ zip ${LAMBDA_ZIP_FILE} lambda_function.py

#Erstellen Sie eine Lambda-Funktion
$ aws2 lambda create-function \
    --function-name ${LAMBDA_FUNCTION_NAME} \
    --runtime ${LAMBDA_RUNTIME} \
    --zip-file fileb://${LAMBDA_ZIP_FILE} \
    --handler ${LAMBDA_HANDLER} \
    --environment Variables=${LAMBDA_ENV} \
    --role ${IAM_ROLE_ARN}

Legen Sie den Abonnementfilter für CloudWatch-Protokolle fest

$ LOG_GROUP_NAME="/aws/rds/instance/[rdsinstance]/slowquery"
$ LOG_FILTER_NAME="LambdaStream_post-slowquery-to-chatwork"
$ LAMBDA_ARN=`aws2 lambda get-function \
    --function-name ${LAMBDA_FUNCTION_NAME} \
    --query 'Configuration.FunctionArn' \
    --output text`
$ LOG_ACTION="lambda:InvokeFunction"
$ LOG_PRINCIPAL="logs.ap-northeast-1.amazonaws.com"
$ SOURCE_ACCOUNT=`aws sts get-caller-identity \
    --query 'Account' \
    --output text`
$ SOURCE_ARN="arn:aws:logs:ap-northeast-1:${SOURCE_ACCOUNT}:log-group:${LOG_GROUP_NAME}:*"

#Gewähren Sie CloudWatch-Protokollen Zugriff zum Ausführen von Funktionen
$ aws2 lambda add-permission \
    --function-name ${LAMBDA_FUNCTION_NAME} \
    --statement-id ${LAMBDA_FUNCTION_NAME} \
    --action ${LOG_ACTION} \
    --principal ${LOG_PRINCIPAL} \
    --source-arn ${SOURCE_ARN} \
    --source-account ${SOURCE_ACCOUNT}

#Erstellen Sie einen Abonnementfilter. Das Filtermuster ist leer("")Zu
$ aws2 logs put-subscription-filter \
    --log-group-name ${LOG_GROUP_NAME} \
    --filter-name ${LOG_FILTER_NAME} \
    --filter-pattern "" \
    --destination-arn ${LAMBDA_ARN}

Damit sind die Einstellungen abgeschlossen.

schließlich

Dieses Mal habe ich RDS-, Lambda- und CloudWatch-Protokolle verwendet, um langsame Abfragen zu benachrichtigen. In der Vergangenheit war es bei einer langsamen Abfrage etwas mühsam, zu CloudWatch-Protokollen zu gehen, um das Protokoll anzuzeigen. Es scheint also, dass die Schmerzen gelindert werden, wenn Chatwork darüber informiert wird. In Zukunft möchte ich die Protokollanalysetools usw. für eine detailliertere Visualisierung vollständig nutzen, werde aber versuchen, sie bei einer anderen Gelegenheit zu implementieren. Was AWS CLI v2 betrifft, habe ich dieses Mal nicht viele Vorteile im Rahmen der Verwendung genossen, aber ich werde es aktiv nutzen.

Recommended Posts

Der erste Schritt, um langsame Abfragen loszuwerden! Ich habe versucht, Chatwork mit Lambda und AWS CLI v2 über langsame Abfragen für RDS for MySQL zu informieren
Ich habe versucht, das Update von "Hameln" mit "Beautiful Soup" und "IFTTT" zu benachrichtigen.
Ich habe versucht, mit AWS Lambda einen AMI zu erhalten
Ich habe versucht, das Update von "Werde ein Romanautor" mit "IFTTT" und "Werde ein Romanautor API" zu benachrichtigen.
Ich habe versucht, den Index der Liste mithilfe der Aufzählungsfunktion abzurufen
Ich habe zum ersten Mal versucht, mit DynamoDB und Step Functions eine serverlose Stapelverarbeitung zu erstellen
Ich habe versucht, Zabbix Server über einen Ausführungsfehler der AWS Lambda-Funktion zu informieren
Ich habe versucht, die Trefferergebnisse von Hachinai mithilfe der Bildverarbeitung zu erhalten
Ich habe versucht, die Phase der Geschichte mit COTOHA zu extrahieren und zu veranschaulichen
Ich habe versucht, die Einstellungen für verschiedene Datenbanken von Django (MySQL, PostgreSQL) zusammenzufassen.
Ich habe versucht, zum Zeitpunkt der Bereitstellung mit Fabric und ChatWork Api automatisch in ChatWork zu posten
Ich habe versucht, die Standortinformationen des Odakyu-Busses zu erhalten
Ich habe versucht, die Informationen des Webs mit "Requests" und "lxml" abzurufen.
Eine Geschichte über das Schreiben von AWS Lambda und ein wenig Abhängigkeit von den Standardwerten von Python-Argumenten
Ich wurde entsetzt, als ich versuchte, mithilfe von PCA und NMF die Anzahl der Merkmale eines animierten Gesichts zu ermitteln.
Ich habe versucht, die Höhen und Tiefen des Schlusskurses des Aktienkurses von Guru Navi mit TensorFlow vorherzusagen (Fortschritt)
Ich habe versucht, mit Pandas eine Pferderenn-Datenbank zu erstellen
[Python] So erhalten Sie den ersten und den letzten Tag des Monats
Ich habe versucht, mit Boto3 eine Liste der AMI-Namen zu erhalten
Ich habe versucht, die statistischen Daten der neuen Corona mit Python abzurufen und zu analysieren: Daten der Johns Hopkins University
Verwenden Sie AWS Lambda, um Nachrichten zu kratzen und LINE regelmäßig über Updates zu informieren [Python]
Ich habe versucht, E-Mails von Node.js und Python mithilfe des E-Mail-Zustelldienstes (SendGrid) von IBM Cloud zuzustellen!
Ich habe versucht, das Gesichtsbild mit sparse_image_warp von TensorFlow Addons zu transformieren
Ich habe versucht, die Altersgruppe und die Ratenverteilung von Atcoder zu visualisieren
Ich habe versucht, die Ähnlichkeit der Frageabsicht mit Doc2Vec von gensim abzuschätzen
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe versucht, die Beschleunigung von Python durch Cython zu verifizieren und zu analysieren
Ich habe versucht, das RSS des Top-Songs des iTunes Store automatisch abzurufen
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Ich habe die übliche Geschichte ausprobiert, Deep Learning zu verwenden, um den Nikkei-Durchschnitt vorherzusagen
Mit COTOHA habe ich versucht, den emotionalen Verlauf des Laufens von Meros zu verfolgen.
Ich habe versucht, die Lernfunktion im neuronalen Netzwerk sorgfältig zu verstehen, ohne die Bibliothek für maschinelles Lernen zu verwenden (erste Hälfte).
Ich habe versucht, die Informationen der ASPX-Site, die mit Selenium IDE ausgelagert wird, so programmlos wie möglich abzurufen
Ich habe zum ersten Mal Tensorflow ausprobiert
Ich habe versucht, die Verschlechterung des Lithium-Ionen-Akkus mithilfe des Qore SDK vorherzusagen
[Python] Ich habe versucht, das Mitgliederbild der Idolgruppe mithilfe von Keras zu beurteilen
Python-Programmierung: Ich habe versucht, Nachrichtenartikel mit Selenium und BeautifulSoup4 abzurufen (zu crawlen)
Ich habe versucht, das Bild zu verarbeiten und zu transformieren und die Daten für maschinelles Lernen zu erweitern
[Einführung in AWS] Ich habe versucht, eine Konversations-App zu portieren und mit text2speech @ AWS playing zu spielen
Ich habe versucht, die Gesichtsverdeckungsarbeit des Koordinationsbildes für das Tragen zu automatisieren
Ich habe versucht, Twitter Scraper mit AWS Lambda zu verwenden, aber es hat nicht funktioniert.