【发布时间】:2018-10-03 20:12:06
【问题描述】:
在这个周末,我在与 dynamodb 集成的 aws lambda 上运行了一些节点函数,我使用 X 射线对其进行调试,创建了我自己的注释,我想知道是否有更好的方法来调试 lambda 函数,比如一个步骤- 一步一步?
【问题讨论】:
标签: node.js amazon-web-services aws-lambda amazon-dynamodb
在这个周末,我在与 dynamodb 集成的 aws lambda 上运行了一些节点函数,我使用 X 射线对其进行调试,创建了我自己的注释,我想知道是否有更好的方法来调试 lambda 函数,比如一个步骤- 一步一步?
【问题讨论】:
标签: node.js amazon-web-services aws-lambda amazon-dynamodb
Lambda local 可用于在本地机器上测试 lambda 代码。
【讨论】:
我认为有一些误解,请原谅从 node.js 上下文切换到 python(标题不是特定于节点的,所以无论如何很多人都会在这里结束)。
您可以逐行调试实际部署的 AWS lambdas。该方法涉及在开发机器上运行调试服务器pydevd,并通过长时间运行的 TCP 连接与调试服务器通信的 lambdas。
它是否被各种 IDE 支持,我们使用的是 PyCharm Pro,所以设置它(假设你应该能够类似地设置 VSCode):
使用路径映射调试配置:右上角运行/调试配置下拉菜单 -> 编辑配置 -> +(添加新配置)-> Python 远程调试 -> 为您的开发机器指定主机名/端口(需要全局公开:在您的路由器上设置路径转发或使用ngrok,如果以前的选项不可用)。 确保设置路径映射,这样您的 IDE 才能将远程脚本映射到本地源。
pip install pydevd。 (对于 pycharm,您需要安装特定于 IDE 版本的自定义发行版,例如:pip install pydevd-pycharm~=193.5233.109)
添加 RemoteDebugSession 上下文管理器抽象(因为调试会话是通过长时间运行的 tcp 连接,它需要在您的 lambda 中显式关闭,否则 lambda 将超时)如:
# from config import config
from logging import getLogger
logger = getLogger(__name__)
class RemoteDebugSession:
def __init__(self):
self.active = False
if not self.is_available():
logger.warning(f"Remote debugging is not available")
return
try:
# pydevd_pycharm exposes only settrace() from pydevd, import pydevd directly instead
# import pydevd_pycharm
import pydevd
self.pydevd = pydevd
except Exception as e:
logger.warning(f"Remote debugging is unavailable")
logger.warning(e)
self.pydevd = None
def __enter__(self):
if not self.is_available() or self.pydevd is None:
return
self.pydevd.settrace(config.REMOTE_DEBUG_HOST, port=config.REMOTE_DEBUG_PORT,
suspend=False,
stdoutToServer=True,
stderrToServer=True)
logger.warning("Starting remote dubugging session")
self.active = True
def __exit__(self, exc_type, exc_val, exc_tb):
if not self.active:
return
if exc_type or exc_val or exc_tb:
logger.warning(
f"Remote debugging on {config.REMOTE_DEBUG_HOST}:{config.REMOTE_DEBUG_HOST} failed")
logger.warning(exc_type)
logger.warning(exc_val)
logger.warning(exc_tb)
else:
logger.warning(f"Remote debugging on {config.REMOTE_DEBUG_HOST}:{config.REMOTE_DEBUG_HOST} closed")
self.pydevd.stoptrace()
@staticmethod
def is_available():
return hasattr(config, 'REMOTE_DEBUG_ENABLED') \
and hasattr(config, 'REMOTE_DEBUG_HOST') \
and hasattr(config, 'REMOTE_DEBUG_PORT') \
and config.REMOTE_DEBUG_ENABLED \
and config.REMOTE_DEBUG_HOST \
and config.REMOTE_DEBUG_PORT
您需要设置带有 REMOTE_DEBUG_ENABLED、REMOTE_DEBUG_HOST、REMOTE_DEBUG_PORT 的配置对象。
(pydevd.settrace 与suspend=False 一起使用,因此除非我们设置断点,否则执行不会停止)
with RemoteDebugSession() as session:
# your code to examine
pass
实际上,在构建 Web 服务器时,这可以在单独的 API 处理程序中进行,这将允许您调试多个同时传入的请求,因为其他 lambdas 会阻塞连接。
请REFRAIN不要在生产中使用它。除了安全风险之外,远程评估还可以让您做各种令人讨厌的事情。
【讨论】:
SAM Local 和 The Serverless framework 都提供了在本地执行 AWS Lambda 函数的工具。如果您需要在 AWS 环境中调试您的功能,我建议使用 Cloud9Cloud9 IDE for AWS Lambda debugging。
但是,要调试生产中发生的调用失败,您可以使用 Dashbird 之类的东西,通过日志、X 射线跟踪和其他元数据来检测和调试失败。
【讨论】:
您将无法像在常规程序上那样通过附加debugger 进行逐步调试。
正如您所提到的,您可以使用 X-Ray 和基本上记录语句来找出问题所在。
正如@ConfusedCoder 指出的那样,您可以通过多种方式在本地运行 lambda 并对其进行调试。
但还要确保您有足够的登录权限,以确保您可以尝试找出问题所在,以应对未来的问题,使用您通常在实际执行发生后查看的日志。
【讨论】:
Rookout 在 AWS Lambda 上提供 NodeJS 的实时调试。这为您提供了生产功能上的断点,以允许传统的分步调试。还有许多 hacky 解决方案可以在本地有效地运行您的 Lambda(例如 lambda.local、无服务器框架),但如果您想使用真实输入进行调试,那么使用 Rookout 在其真实环境中调试它是一个不错的选择。
【讨论】:
您可以使用无服务器框架来调试该功能。在这种方法中,您不必安装 docker。
"scripts": {
"start": "serverless offline -s dev",
"test": "mocha"
}
如果您使用 vscode,请使用以下代码作为 launch.json(在 #PROFILENAME# 中填写您的 aws 配置文件名称)
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Serverless Offline",
"program": "${workspaceRoot}/node_modules/serverless/bin/serverless",
"args": [
"offline",
"--noTimeout",
"--dontPrintOutput",
"--stage=local",
"-P",
"4000",
"--aws-profile=#PROFILENAME#"
],
"sourceMaps": true,
"runtimeArgs": ["--lazy"],
"outFiles": ["${workspaceFolder}/.webpack/**/*.js"],
"protocol": "inspector",
"runtimeExecutable": "node",
"env": {
// Here we set some environment vars that should be set locally.
// They can and will overwrite the ones coming from your serverless.yml
},
"windows": {
"program": "${workspaceRoot}\\node_modules\\serverless\\bin\\serverless"
}
}
]
}
SET SLS_DEBUG=*
然后你就可以像往常一样调试函数了。 如果您没有 package.json,则必须将 npm init 和 npm install 作为第四步。
您必须在本地而不是全局安装 serverless 才能使用给定的 launch.json
【讨论】: