Ich habe erfolgreich eine Lambda-Funktion (app1) erstellt, die RDS liest und schreibt.Unabhängiger Python-Subprozess von AWS Lambda-Funktion
Meine Lambda-Funktion wird in python2.7 geschrieben und als gezipptes Paket hochgeladen.
Ich habe das ZIP-Paket auf einer EC2-Instanz in derselben VPC wie meine RDS- und Lambda-Funktion erstellt und getestet.
Als nächstes fügte ich die Funktionalität zu meiner Lambda-Funktion hinzu, um einen unabhängigen Subprozess (app2) mit subprocess.popen zu öffnen und app1 zurückzugeben, während der app2-Subprozess eigenständig fortfuhr. Ich testete, dass App1 die Ausgabe seines Handlers erfolgreich zurückgab, während App2 fortfuhr, indem sie einen 60-Sekunden-Schlaf in app2 setzte und die Ausgabedatei von app2 tailte.
Ich habe die App1- und App2-Funktionalität in der EC2-Instanz erfolgreich getestet. Nach dem Hochladen des neuen Pakets scheint sich meine App1 genau wie erwartet zu verhalten und gibt sofort die Ausgabe ihres Handlers zurück, aber die App2-Funktionalität erscheint nicht als instanziiert, aber es gibt keine Protokolle, Fehler oder Ausgaben Erfassung von App2.
In app1, ich getestet, dass Subprozess arbeitete durch Ausführen eines subprocess.check_output (['ls', '- la']) vor und nach dem unabhängigen subproccess.popen, und der lokale Ordner wird mit meinen Dateien angezeigt. Es wird jedoch keine app2output-Datei wie erwartet erstellt.
Zwei Fragen
- Gibt es etwas Besonderes, dass ich in AWS-Lambda-Konzepte am fehlt die app2 verursacht zu "fail"? Mit "fail" bezeichne ich nicht das Erstellen der neuen Datei und das Schreiben, das Erstellen von Cloudwatch-Protokollen auf die gleiche Weise, wie es bei app1 der Fall ist, oder das Ausdrucken auf der Lambda-Konsole wie bei app1.
- Wie kann ich eine Ausgabe (Logging-Informationen und Fehler) für App2 in einer AWS-Lambda-Umgebung abfangen?
app1.py
import subprocess
import sys
import logging
import rds_config
import pymysql
#rds settings
rds_host = "rdshost"
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name
port = 3306
logger = logging.getLogger()
logger.setLevel(logging.INFO)
server_address = (rds_host, port)
try:
conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
sys.exit()
def handler(event, context):
cur = conn.cursor()
isql = "INSERT ..."
cur.execute(isql)
conn.commit()
newid = cur.lastrowid
cur.close()
args = [str(newid),str(event['name'])]
logger.info('ARGS: '+str(args))
print 'pwd: '
output = subprocess.check_output(['pwd'])
print output
print 'ls -la'
output = subprocess.check_output(['ls','-l'])
print output
pid = subprocess.Popen([sys.executable, "app2.py"]+args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
logger.info('PID: '+str(pid))
output = subprocess.check_output(['ls','-l'])
print output
return "{'status':'success','newid':'"+str(newid)+"'}";
Die Ausgabe von "logger.info ('PID:' + str (pid))" in app1.py
ist wie: „PID : < subprocess.Popen Objekt bei 0x7f51aba2a550 > "
app2
import sys
import logging
from datetime import datetime
import time
fo = open('app2output','a+')
fo.write("starting with: "+str(sys.argv)+"\n")
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info("Starting with: "+str(sys.argv)+"\n")
#log accumulated processing time
t1 = datetime.now();
sleep(60)
t2 = datetime.now();
tstring = "{'t1':'"+str(t1)+"','t2':'"+str(t2)+"','args':'"+str(sys.argv[1])+"'}"
logger.info(tstring+"\n")
fo.write(tstring+"\n")
fo.close()
sys.exit()
Ich dachte, das könnte das Problem sein. Ich habe nach App2 einen 60 Sekunden Schlaf zu app1 hinzugefügt, aber bevor ich den Handler zurückgab, und App2 zeigte immer noch keinen Fortschritt. Ich habe beschlossen, app2 zu einer separaten Lambda-Funktion zu machen und es auf diese Weise unabhängig zu starten. Danke für die Antwort, und es ist korrekt in Bezug auf meinen erklärten Verwendungszweck. – Lance