如何调试aws lambda函数?

时间:2018-04-23 17:34:09

标签: node.js amazon-web-services aws-lambda amazon-dynamodb

在这个周末,我在与dynamodb集成的aws lambda上运行了一些节点函数,我使用x-ray调试它创建我自己的注释,我想知道是否有一种更好的方法来调试lambda函数就像一个步骤逐步?

7 个答案:

答案 0 :(得分:5)

我认为存在一些误解,请原谅从node.js上下文切换到python(标题不是特定于node的,所以很多人最终都会在这里结束)。

可以逐行调试实际部署的AWS Lambda。该方法涉及在开发机器上运行调试服务器pydevd,并通过长时间运行的TCP连接与lambda与调试服务器进行通信。

它受各种IDE支持吗,我们与PyCharm Pro一起使用,因此对其进行设置(假设您应该能够类似地设置VSCode):

  1. 带有路径映射的调试配置:右上角运行/调试配置下拉菜单->编辑配置-> +(添加新配置)-> Python远程调试->为开发机器指定主机名/端口(需要全局公开的内容:在路由器上设置路径转发;如果先前的选项不可用,请使用ngrok确保以设置路径映射,这是IDE可以将远程脚本映射到本地源的方式。

  2. pip install pydevd。 (对于pycharm,您将需要安装特定于IDE版本的自定义发行版,例如:pip install pydevd-pycharm~=193.5233.109

  3. 添加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一起使用,因此除非设置断点,否则执行不会停止)

  1. 使用以下方式包装您感兴趣的功能:
 with RemoteDebugSession() as session:
    # your code to examine
    pass

实际上,在构建Web服务器时,它可以位于单独的API处理程序中,这将允许您调试多个同时传入的请求,因为其他lambda会在连接时阻塞。

避免在生产中使用此功能。除了安全风险外,远程评估还可以使您做各种令人讨厌的事情。

答案 1 :(得分:4)

Lambda local可用于测试本地计算机中的lambda代码。

答案 2 :(得分:2)

通过附加debugger,您将无法像在常规程序上那样逐步进行调试。 正如您所提到的,您可以使用X-Ray和基本上记录语句来找出问题所在。

正如@ConfusedCoder指出的那样,你可以在本地运行lambda并调试它。

但是也请确保您有足够的登录信息,以确保您可以尝试找出出现问题的未来问题,使用日志,就像在实际执行后通常会查看日志一样。

答案 3 :(得分:2)

Rookout在AWS Lambda上提供NodeJS的实时调试。这为您提供了生产功能的断点,以允许传统的逐步调试。还有许多hacky解决方案可以在本地有效运行Lambda(例如,lambda.local,无服务器框架),但是如果您想使用真实的输入进行调试,那么最好使用Rookout在真实的环境中对其进行调试。

答案 4 :(得分:2)

SAM LocalThe Serverless framework均提供工具以本地执行AWS Lambda函数。如果您需要在AWS环境中调试功能,建议您使用Cloud9 Cloud9 IDE for AWS Lambda debugging

但是,要调试生产中发生的调用失败,可以使用Dashbird之类的东西通过日志,X射线跟踪和其他元数据来检测和调试失败。

答案 5 :(得分:0)

您现在可以在Lambda本身中创建测试:

Lambda test UI

在Lambda函数的右上方

选择测试,以显示一个屏幕,您可以通过该屏幕配置可以运行的新测试。有很多示例模板可供选择,其中包括一个针对DynamoDB的模板,如您建议的那样:

Lambda new test config UI

现在选择您的新测试,然后再次单击 Test 按钮。它会立即运行,并且您会在屏幕上看到控制台结果,包括日志和错误消息。

答案 6 :(得分:0)

您可以使用无服务器框架来调试该功能。通过这种方法,您不必安装docker。

  1. npm install -D无服务器
  2. 无服务器配置凭据--provider aws --key'your_key'--secret'your_secret'--profile'your aws profile'
  3. npm install --save-dev serverless-offline
  4. 在package.json中

"scripts": { "start": "serverless offline -s dev", "test": "mocha" }

  1. 如果使用vscode,请使用以下代码作为launch.json(在#PROFILENAME#中填写个人资料名称)

    { // 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" } } ] }

  2. SET SLS_DEBUG = *

然后,您可以照常调试功能。 如果没有package.json,则必须进行npm init和npm安装,这是第4步。

您必须在本地而不是全球范围内安装无服务器才能使用给定的launch.json