我已成功创建一个读取和写入 RDS 的 Lambda 函数 (app1)。
我的Lambda函数是用python2.7编写的,并作为压缩包上传。
我在与 RDS 和 Lambda 函数相同的 VPC 中的 EC2 实例上创建并测试了压缩包。
接下来,我向 Lambda 函数添加了使用 subprocess.popen 弹出独立子进程 (app2) 的功能,并让 app1 返回,而 app2 子进程继续自行运行。我测试了 app1 将成功返回其处理程序的输出,而 app2 通过在 app2 中放置 60 秒睡眠并跟踪 app2 的输出文件来继续。
我在 EC2 实例中成功测试了 app1 和 app2 功能。
上传新包后,我的 app1 的行为似乎与预期完全一致,并立即返回其处理程序的输出,但 app2 功能并未“出现”实例化,但没有日志、错误或可从 app2 捕获的输出。
在 app1 中,我通过在独立的 subprocess.popen 之前和之后执行 subprocess.check_output(['ls','-la']) 来测试子进程的工作情况,并且本地文件夹与我的文件一起显示。除非没有按预期创建 app2output 文件。
两个问题
- AWS-Lambda 概念中我缺少什么特别的东西吗
这导致app2“失败”?我所说的“失败”是指不写入创建新文件并写入该文件,也不像 app1 成功那样在 Cloudwatch 中创建任何日志,也不像 app1 那样打印到 Lambda 控制台。
- 如何在 AWS-Lambda 环境中捕获 app2 的任何输出(日志记录信息和错误)?
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)+"'}";
app1.py 中“logger.info('PID: '+str(pid))”的输出
就像:“PID:”
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()