总览
如果将适当的日志记录和错误处理添加到代码中,调试Azure函数将非常容易。 但是,有时使用这些技术进行调试还远远不够。 因此,我们需要一个强大的调试环境来跟踪事务的端到端。 在进行环境设置之前,我想先概述一下Azure Functions的高级事务流(据我了解)。 请参考下图,它被张贴2018年3月在Azure的功能Python的工人维基这里 :
总体而言,Azure Functions Host是为Azure Functions应用程序提供动力的主机/运行时。 从图的顶部开始,传入的HTTP事务首先被路由到WebHost,该WebHost是Azure Functions Host的子组件。 WebHost处理HTTP请求,并将事务发送到Azure Functions Python Worker,也称为Python Worker。 然后,Python Worker将事务路由到适当的功能应用程序。
从此图可以明显看出,适当调试了Azure函数; 您需要将自己插入Azure Functions Host,这是一个用C#编写的dotnet核心应用程序。 请注意,出于本教程的目的,我专注于调试HTTP触发器功能应用程序。 本教程假定您对Azure函数和VS代码有一定的了解。
必备软件
生成和调试Azure Functions主机必须满足两个先决条件:dotnet core 2.x和Visual Studio(VS)代码。
dotnet核心2.2.x:
- 从这里下载dotnetcore-sdk 2.x
- 通过运行来验证下载的校验和
openssl sha512 dotnet-sdk-2.2.207-osx-x64.pkg
VS代码:
- 从这里下载VS Code
- 安装C#和python扩展
环境设定
以下步骤有助于创建一个独立的虚拟环境,您可以在其中独立于其他功能应用程序开发环境单独调试功能应用程序。 首先,创建一个虚拟环境和支持的文件夹结构:
python3 -m venv .afhvenv
cd .afhvenv/
source bin/activate
mkdir afdebugenv
cd afdebugenv
mkdir functions
如您将在本文后面看到的那样,遵循上述文件夹结构将使您可以同时调试多个版本的Azure Functions Host。
Azure Functions主机源代码
下载Azure Functions Host最新生产版本的源代码。 请注意:您当然可以从GitHub下载所需的任何分支; 但是,我想要生产中正在运行的东西,因为非生产分支可能无法成功构建。 从afdebugenv的根目录运行以下命令:
wget https://github.com/Azure/azure-functions-host/archive/2.0.12888.zip
unzip 2.0.12888.zip
完成后,您将构建Azure的调试版本
从命令行使用dotnet可执行文件从源函数主机:
cd azure-functions-host-2.0.12888
dotnet build -c Debug WebJobs.Script.sln
该构建将需要几分钟的时间才能完成,并且构建时不会出现错误(即使在我的MacBook Pro上也是如此)。
Azure Functions主机符号文件
符号文件包含运行二进制文件时实际上并不需要的各种数据,但是在调试过程中可能非常有用。 符号文件特定于该软件的每个版本,因此我们将在Azure Functions Host文件夹中创建一个符号文件夹。 从要调试的Azure Functions Host版本的根目录中运行以下命令:
mkdir symbols
wget https://github.com/Azure/azure-functions-host/releases/download/2.0.12888/Functions.Symbols.2.0.12888.win-x64.zip
unzip Functions.Symbols.2.0.12888.win-x64.zip
Azure Functions Python工作器
Azure Functions主机附带了一个python worker,我们将使用它进行调试。 请注意 :下面的路径是针对我的安装程序(OS X),路径到worker.py会后的一些变化“ ../netcoreapp2.2/workers..
”。 在工作目录中,运行以下命令:
cd /azure-functions-host-2.0.12888/src/WebJobs.Script.WebHost/bin/Debug/netcoreapp2.2/workers/python/3.7/OSX/X64
wget https://gist.githubusercontent.com/gattjoe/2b2e77a14cd461a131eee9ebc1539f0d/raw/a1c52c3bfb5be87b21bcdfd1e09fbea787ae06ed/worker.config.json
将worker.config.json
下载到worker目录后,必须配置python worker在VS Code调用时以调试模式运行。 有关worker.config.json
文件的正确格式的一些背景知识,请参阅此文档 。 要在worker.py进程上启用调试,请将以下指令添加到worker.config.json
:
"Arguments" : [ "-m ptvsd --host 127.0.0.1 --port 9091" ]
VS代码设置
需要自定义Launch.json和task.json以正确构建和调试Azure Functions主机。 我提供的示例文件可让您更快地启动和运行,这就是为什么我如此具体地提到上面的目录。 感到舒适之后,可以随时自定义launch.json
文件以满足您的需求。 在afdebugenv文件夹的根目录下,运行以下命令:
mkdir .vscode
cd .vscode
wget https://gist.githubusercontent.com/gattjoe/ce03f5d7ea8294246efabaf048eb1c39/raw/820109fcdbd72b407c49b2c6e7aa9d68db03318a/tasks.json
wget https://gist.githubusercontent.com/gattjoe/47b9e54f25d1d21800f02dd518d86bbb/raw/177908cf773e27f2936458200ba14484d6a55d4e/launch.json
完成后,从afdebugenv目录打开VS Code。 您
可能会收到一条通知,说:“缺少用于构建和调试的必需资产
来自“ afdebugenv”。 添加它们吗?”。 说是
安装其他Python软件包
我们正在本地有效地运行整个Azure Function堆栈,因此我们需要安装ptvsd和Azure函数。 运行以下命令:
pip install ptvsd azure-functions
验证您的环境
如果您做到了这一点,您将感到很荣幸。 我曾考虑过要使整个过程自动化,但是我认为,鉴于这个领域的快速变化步伐,它会在几个月内过时。 假设您在functions目录中拥有普通的HTTP Trigger函数应用程序,我们将在下面运行简短测试,以确保您的环境已准备好开始调试。 从afdebugenv目录的根目录中,打开“ VS Code”并执行以下步骤:
- 在资源管理器屏幕中,导航到以下路径:“
afdebugenv/azure-functions-host-2.0.12888/src/WebJobs.Script.WebHost/Middleware/FunctionInvocationMiddleware.cs
” - 在代码的前三分之一中,您将找到以下函数定义:“
public async Task Invoke(HttpContext context)
”。 在左侧装订线中设置一个断点,该断点将用红点标记 - 若要调用Azure Functions Host的调试器,请在调试屏幕的“调试并运行”标题下,从下拉列表中选择“ .NET Core启动”,然后按F5键。
- 您会注意到,与执行“ func host start ”时,集成终端打开时会显示类似的启动消息。 唯一的主要区别是Azure功能主机正在侦听TCP 5000端口。请参考下面的屏幕截图:
- 要为python worker调用调试器,请在调试屏幕的“ debug and run”标题下,从下拉列表中选择“ Attach to Python Functions”,然后按F5
- 针对您的HTTPTrigger运行测试事务
- 调试器应达到在步骤2中设置的断点,现在您可以检查传递给该函数的数据。 请参考以下屏幕截图:
- 要继续处理交易,请点击F5 。 在执行命令的终端上,您应该看到输出。 此外,集成终端应反映您已成功处理交易
- 要退出调试过程,请在调试控制面板中按红色方框。
请注意 :停止VS Code调试器不会终止 Azure Functions Host产生的worker.py进程。 因此,您必须手动终止进程以释放TCP 5000备份端口。 请注意x2 :必须首先停止VS Code调试器,否则,Azure Functions Host将在每次杀死它时不断产生worker.py进程。
在以后的文章中,我将介绍依赖于本文作为基础的高级调试主题。 如果您有任何反馈意见,请通过<hotmail>的gattjoseph给我发送说明。