【问题标题】:How to debug a aws lambda function?如何调试 aws lambda 函数?
【发布时间】:2018-10-03 20:12:06
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      它是否被各种 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 处理程序中进行,这将允许您调试多个同时传入的请求,因为其他 lambdas 会阻塞连接。

      REFRAIN不要在生产中使用它。除了安全风险之外,远程评估还可以让您做各种令人讨厌的事情。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

          正如@ConfusedCoder 指出的那样,您可以通过多种方式在本地运行 lambda 并对其进行调试。

          但还要确保您有足够的登录权限,以确保您可以尝试找出问题所在,以应对未来的问题,使用您通常在实际执行发生后查看的日志。

          【讨论】:

            【解决方案5】:

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

            【讨论】:

              【解决方案6】:

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

              选择您的 Lambda 函数右上角的 测试 以显示一个屏幕,允许您配置可以运行的新测试。有许多示例模板可供选择,包括您建议的 DynamoDB 模板:

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

              【讨论】:

                【解决方案7】:

                您可以使用无服务器框架来调试该功能。在这种方法中,您不必安装 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# 中填写您的 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=*

                然后你就可以像往常一样调试函数了。 如果您没有 package.json,则必须将 npm init 和 npm install 作为第四步。

                您必须在本地而不是全局安装 serverless 才能使用给定的 launch.json

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-17
                  • 2016-09-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-02-26
                  • 2018-07-02
                  相关资源
                  最近更新 更多