本教程介绍如何使用 Azure Monitor 排查应用服务应用问题。 示例应用中的代码故意耗尽内存并导致 HTTP 500 错误,使你可以使用 Azure Monitor 来诊断和解决问题。 完成后,某个示例应用将在与 Azure Monitor 集成的“Linux 上的应用服务”中运行。
Azure Monitor 提供用于收集、分析和处理来自云与本地环境的遥测数据的综合解决方案,可将应用程序和服务的可用性和性能最大化。
在本教程中,你将了解如何执行以下操作:
- 使用 Azure Monitor 配置 Web 应用
- 将控制台日志发送到 Log Analytics
- 使用日志查询来识别和排查 Web 应用错误
可以在 macOS、Linux、Windows 中执行本教程中的步骤。
如果没有 Azure 帐户,请在开始前创建一个免费帐户。
先决条件
要完成本教程,需要:
在 Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅 Azure Cloud Shell 入门。
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅 使用 Azure CLI 向 Azure 进行身份验证。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展的详细信息,请参阅 使用和管理 Azure CLI 中的扩展。
运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
创建 Azure 资源
首先在本地运行多个命令,以设置要在本教程中使用的示例应用。 这些命令将创建 Azure 资源,创建部署用户,然后将示例应用部署到 Azure。 系统会提示输入在创建部署用户期间提供的密码。
az group create --name myResourceGroup --___location "South Central US"
az webapp deployment user set --user-name <username> --password <password>
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku B1 --is-linux
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --runtime "PHP|8.1" --deployment-local-git
az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings DEPLOYMENT_BRANCH='main'
git clone https://github.com/Azure-Samples/App-Service-Troubleshoot-Azure-Monitor
cd App-Service-Troubleshoot-Azure-Monitor
git branch -m main
git remote add azure <url-from-app-webapp-create>
git push azure main
配置 Azure Monitor
创建 Log Analytics 工作区
将示例应用部署到 Azure 应用服务后,接下来配置监视功能,以便在出现问题时对应用进行故障排除。 Azure Monitor 将日志数据存储在 Log Analytics 工作区中。 工作区是包含数据和配置信息的容器。
此步骤将创建一个用来为应用配置 Azure Monitor 的 Log Analytics 工作区。
az monitor log-analytics workspace create --resource-group myResourceGroup --workspace-name myMonitorWorkspace
创建诊断设置
使用诊断设置可将特定 Azure 服务的指标收集到 Azure Monitor 日志中,以使用日志查询结合其他监视数据进行分析。 在本教程中,请启用 Web 服务器和标准输出/错误日志。 有关日志类型和说明的完整列表,请参阅支持的日志类型。
运行以下命令创建 AppServiceConsoleLogs(标准输出/错误)和 AppServiceHTTPLogs(Web 服务器日志)的诊断设置。 请将 <app-name> 和 workspace-name< 替换为你自己的值。
注意
前两个命令 resourceID
和 workspaceID
是在 az monitor diagnostic-settings create 命令中使用的变量。 有关此命令的详细信息,请参阅使用 Azure CLI 创建诊断设置。
resourceID=$(az webapp show -g myResourceGroup -n <app-name> --query id --output tsv)
workspaceID=$(az monitor log-analytics workspace show -g myResourceGroup --workspace-name <workspace-name> --query id --output tsv)
az monitor diagnostic-settings create --resource $resourceID \
--workspace $workspaceID \
-n myMonitorLogs \
--logs '[{"category": "AppServiceConsoleLogs", "enabled": true},
{"category": "AppServiceHTTPLogs", "enabled": true}]'
排查应用问题
浏览到 http://<app-name>.azurewebsites.net
。
示例应用 ImageConverter 将包含的图像从 JPG
转换为 PNG
。 我们有意在本教程的代码中安排了一个 bug。 如果选择了足够多的图像,该应用会在转换图像期间生成 HTTP 500 错误。 假设在开发阶段并未考虑到这种情况。 你将使用 Azure Monitor 来排查该错误。
验证应用是否正常工作
若要转换图像,请单击 Tools
并选择 Convert to PNG
。
选择前两个图像,然后单击 convert
。 转换将成功。
中断应用
通过成功转换前两个图像来验证应用后,我们将尝试转换前五个图像。
此操作失败,并生成一个在开发期间未测试过的 HTTP 500
错误。
使用日志查询查看 Azure Monitor 日志
让我们看看 Log Analytics 工作区中提供了哪些日志。
单击此 Log Analytics 工作区链接在 Azure 门户中访问工作区。
在 Azure 门户中,选择 Log Analytics 工作区。
日志查询
日志查询可帮助你充分利用在 Azure Monitor 日志中收集的数据的价值。 使用日志查询可以识别 AppServiceHTTPLogs 和 AppServiceConsoleLogs 中的日志。 有关日志查询的详细信息,请参阅日志查询概述。
使用日志查询查看 AppServiceHTTPLogs
访问应用后,让我们查看 AppServiceHTTPLogs
中的与 HTTP 请求关联的数据。
- 在左侧导航栏中单击
Logs
。
- 搜索
appservice
并双击AppServiceHTTPLogs
。
- 单击
Run
。
AppServiceHTTPLogs
查询返回过去 24 小时发出的所有请求。 列 ScStatus
包含 HTTP 状态。 若要诊断 HTTP 500
错误,请将 ScStatus
限制为 500 并运行查询,如下所示:
AppServiceHTTPLogs
| where ScStatus == 500
使用日志查询查看 AppServiceConsoleLogs
确认 HTTP 500 错误后,让我们查看应用发出的标准输出/错误。 可在“AppServiceConsoleLogs”中找到这些日志。
(1) 单击 +
创建新查询。
(2) 双击 AppServiceConsoleLogs
表并单击 Run
。
由于转换五个图像会导致服务器错误,可以根据 ResultDescription
筛选错误以确定应用是否也写入了错误,如下所示:
AppServiceConsoleLogs |
where ResultDescription contains "error"
在 ResultDescription
列中,将看到以下错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 16384 bytes) in /home/site/wwwroot/process.php on line 20,
referer: http://<app-name>.azurewebsites.net/
联接 AppServiceHTTPLogs 和 AppServiceConsoleLogs
识别 HTTP 500 和标准错误后,需要确认这些消息之间是否存在关联。 接下来,根据时间戳 TimeGenerated
联接这些表。
注意
事先已准备好一个可执行以下操作的查询:
- 在 HTTPLogs 中筛选 500 错误
- 查询控制台日志
- 根据
TimeGenerated
联接表
运行以下查询:
let myHttp = AppServiceHTTPLogs | where ScStatus == 500 | project TimeGen=substring(TimeGenerated, 0, 19), CsUriStem, ScStatus;
let myConsole = AppServiceConsoleLogs | project TimeGen=substring(TimeGenerated, 0, 19), ResultDescription;
myHttp | join myConsole on TimeGen | project TimeGen, CsUriStem, ScStatus, ResultDescription;
在 ResultDescription
列中,将会看到发生时间与 Web 服务器错误相同的以下错误:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 16384 bytes) in /home/site/wwwroot/process.php on line 20,
referer: http://<app-name>.azurewebsites.net/
消息在 process.php
的第 20 行指出内存已耗尽。 现已确认应用程序在出现 HTTP 500 错误期间生成了错误。 让我们查看代码以识别问题。
识别错误
在本地目录中,打开 process.php
并查看第 20 行。
imagepng($imgArray[$x], $filename);
第一个参数 $imgArray[$x]
是变量,包含所有需要转换的 JPG(内存中图像)。 但是,imagepng
只需要正在转换的图像,而不需要所有图像。 预先加载图像是没有必要的,可能会导致内存耗尽,从而导致 HTTP 500 错误。 让我们更新代码以按需加载图像,然后查看是否解决了问题。 接下来,改进代码以解决内存问题。
修复应用
在本地更新并重新部署代码
对 process.php
进行以下更改,以处理内存耗尽问题:
<?php
//Retrieve query parameters
$maxImages = $_GET['images'];
$imgNames = explode(",",$_GET['imgNames']);
//Load JPEGs into an array (in memory)
for ($x=0; $x<$maxImages; $x++){
$filename = './images/converted_' . substr($imgNames[$x],0,-4) . '.png';
imagepng(imagecreatefromjpeg("./images/" . $imgNames[$x]), $filename);
}
提交在 Git 中所做的更改,然后将代码更改推送到 Azure。
git commit -am "Load images on-demand in process.php"
git push azure main
转到 Azure 应用
浏览到 http://<app-name>.azurewebsites.net
。
转换图像应该不再会生成 HTTP 500 错误。
清理资源
在前面的步骤中,你在资源组中创建了 Azure 资源。 如果认为将来不需要这些资源,请在 Cloud Shell 中运行以下命令删除资源组:
az group delete --name myResourceGroup
此命令可能需要花费一点时间运行。
使用以下命令删除诊断设置:
az monitor diagnostic-settings delete --resource $resourceID -n myMonitorLogs
你已了解:
- 使用 Azure Monitor 配置 Web 应用
- 将日志发送到 Log Analytics
- 使用日志查询来识别和排查 Web 应用错误