简体   繁体   English

如何调试 aws lambda 函数?

[英]How to debug a aws lambda function?

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

Lambda local可用于在本地机器上测试 lambda 代码。

Both SAM Local and The Serverless framework provide tools to locally execute an AWS Lambda functions. SAM Local无服务器框架都提供了在本地执行 AWS Lambda 函数的工具。 In case you need to debug your function in the AWS environment, I suggest using Cloud9 Cloud9 IDE for AWS Lambda debugging .如果您需要在 AWS 环境中调试您的函数,我建议使用 Cloud9 Cloud9 IDE 进行 AWS Lambda 调试

However, to debug invocation failures occurred in production, you could use something like Dashbird to detect and debug failures using logs, X-ray traces and other metadata.但是,要调试生产中发生的调用失败,您可以使用Dashbird 之类的工具使用日志、X 射线跟踪和其他元数据来检测和调试失败。

I think there is some misconception, pardon for switching from node.js context to python (the title is not specific to node so many folks will end up here anyway).我认为有一些误解,请原谅从 node.js 上下文切换到 python(标题不是特定于节点的,所以无论如何很多人都会在这里结束)。

You CAN debug actual deployed AWS lambdas line-by-line.可以调试实际部署AWS lambda表达式行由行。 The approach involves running a debug server pydevd on the development machine and lambdas communicating with a debug-server over long-running TCP connection.该方法涉及在开发机器上运行调试服务器pydevd以及通过长时间运行的 TCP 连接与调试服务器通信的 lambdas。

Is it supported by various IDEs, we use is with PyCharm Pro, so setup for it (hypothetically you should be able to setup VSCode similarly):它是否受各种 IDE 支持,我们使用的是 PyCharm Pro,因此对其进行设置(假设您应该能够类似地设置 VSCode):

  1. Debug configuration with Path mapping: right-top corner run/debug configuration dropdown -> Edit Configurations -> + (add new configuration) -> Python remote debug -> specify host name / port for your dev machine (which needs globally exposed: setup path forwarding on your router or use ngrok if previous option is not available).带有路径映射的调试配置:右上角运行/调试配置下拉菜单 -> 编辑配置 -> +(添加新配置)-> Python 远程调试 -> 为您的开发机器指定主机名/端口(需要全局公开:setup)在您的路由器上进行路径转发,或者如果之前的选项不可用,请使用ngrok )。 Make sure to setup path mappings, that is how your IDE can map the remote scripts to local sources.确保设置路径映射,这是您的 IDE 可以将远程脚本映射到本地源的方式。

  2. pip install pydevd . pip install pydevd (For pycharm, you will need to install IDE-version specific custom distribution like: pip install pydevd-pycharm~=193.5233.109 ) (对于 pycharm,您需要安装特定于 IDE 版本的自定义发行版,例如: pip install pydevd-pycharm~=193.5233.109

  3. Add the RemoteDebugSession context manager abstraction(since debug session is over long-running tcp connection, its needs to be closed explicitly in your lambda otherwise lambda will timeout) like:添加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

You need to have config object with REMOTE_DEBUG_ENABLED, REMOTE_DEBUG_HOST, REMOTE_DEBUG_PORT set.您需要设置带有 REMOTE_DEBUG_ENABLED、REMOTE_DEBUG_HOST、REMOTE_DEBUG_PORT 的配置对象。 (pydevd.settrace is used with suspend=False so the executing won't stop unless we set a breakpoint) (pydevd.settrace 与suspend=False一起使用,因此除非我们设置断点,否则执行不会停止)

  1. Wrap your feature of interest with it like:用它包裹您感兴趣的功能,例如:
 with RemoteDebugSession() as session:
    # your code to examine
    pass

In practice, when building web servers, this can be inside an individual API handler, which will allow you to debug multiple simultaneous incoming requests as other lambdas will block on connection.实际上,在构建 Web 服务器时,这可以在单独的 API 处理程序中,这将允许您调试多个同时传入的请求,因为其他 lambda 将在连接时阻塞。

Please REFRAIN from using this in production.避免在生产中使用它。 Apart from security risk, remote evaluation can allow you to do all sort of nasty things.除了安全风险,远程评估可以让你做各种讨厌的事情。

You wont be able to do a step by step debug like you would on a regular program by attaching a debugger .您将无法像在常规程序中那样通过附加debugger进行逐步调试。 As you mentioned you can use X-Ray and basically logging statements to figure out what went wrong.正如您所提到的,您可以使用 X-Ray 和基本上记录语句来找出问题所在。

As @ConfusedCoder pointed out there are ways in which you can run a lambda locally and debug it.正如@ConfusedCoder 指出的那样,您可以通过多种方式在本地运行 lambda 并对其进行调试。

But also make sure you have enough logging in to ensure that you can try to figure out what went wrong, for future issues, using the logs as you would typically be looking at it after the actual execution happened.但还要确保您有足够的登录信息,以确保您可以尝试找出问题所在,以备将来出现问题时,使用日志,就像您在实际执行发生后通常会查看的那样。

Rookout offers live debugging of NodeJS on AWS Lambda. Rookout在 AWS Lambda 上提供NodeJS 的实时调试。 This gives you breakpoints on the production function to allow traditional step-debugging.这为您提供了生产函数上的断点,以允许进行传统的单步调试。 There are also lots of hacky solutions that effectively run your Lambda locally (eg lambda.local, serverless framework) but if you want to debug with true inputs, then debugging it in its true environment using Rookout is a good option.还有很多 hacky 解决方案可以有效地在本地运行您的 Lambda(例如 lambda.local、无服务器框架),但是如果您想使用真实输入进行调试,那么使用 Rookout 在其真实环境中调试它是一个不错的选择。

You can now create tests within Lambda itself:您现在可以在 Lambda 本身内创建测试:

Lambda 测试界面

Choose Test at the top right of your Lambda function to bring up a screen that allows you to configure a new test that can be run.选择 Lambda 函数右上角的测试以显示一个屏幕,允许您配置可以运行的新测试。 There are lots of example templates to choose from, including one for DynamoDB like you suggested:有很多示例模板可供选择,包括您建议的 DynamoDB 模板:

Lambda 新的测试配置 U​​I

Now choose your new test and click the Test button again.现在选择您的新测试并再次单击“测试”按钮。 It will run immediately and you'll see console results on your screen, including logs and error messages.它将立即运行,您将在屏幕上看到控制台结果,包括日志和错误消息。

You can use the serverless framework to debug the function.您可以使用无服务器框架来调试该功能。 In this approach, you don't have to install docker.在这种方法中,您不必安装 docker。

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

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

  1. use following code as launch.json if you use vscode (Fill you aws profile name in #PROFILENAME#)如果您使用 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" } } ] }

  2. SET SLS_DEBUG=*设置 SLS_DEBUG=*

Then you can debug function as usual.然后你可以像往常一样调试功能。 If you don't have package.json you have to npm init and npm install as a 4th step.如果您没有 package.json,您必须将 npm init 和 npm install 作为第四步。

You must install serverless in locally not globally to use the given launch.json您必须在本地而非全局安装 serverless 才能使用给定的 launch.json

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM