이 자습서에서는 Azure Monitor를 사용하여 Azure App Service 앱 문제를 해결하는 방법을 보여줍니다. 샘플 앱에는 메모리를 소모하고 HTTP 500 오류를 발생시키는 코드를 포함하므로 Azure Monitor를 사용하여 문제를 진단하고 해결할 수 있습니다. 완료되면 Azure Monitor와 통합된 Linux의 App Service에서 실행되는 샘플 앱이 있습니다.
Azure Monitor는 클라우드 및 온-프레미스 환경에서 시스템 생성 로그를 수집, 분석 및 작동하기 위한 포괄적인 솔루션을 제공하여 애플리케이션 및 서비스의 가용성과 성능을 최대화합니다.
이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.
- Azure Monitor를 사용하여 웹앱 구성
- Log Analytics에 콘솔 로그 보내기
- 로그 쿼리를 사용하여 웹앱 오류 식별 및 해결
macOS, Linux 또는 Windows에서 이 자습서의 단계를 따를 수 있습니다.
필수 조건
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.4" --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 App Service에 샘플 앱을 배포한 후 문제가 발생할 때 앱을 해결하도록 모니터링 기능을 구성합니다. Azure Monitor는 로그 데이터를 Log Analytics 작업 영역에 저장합니다. 작업 영역은 데이터 및 구성 정보를 포함하는 컨테이너입니다.
이 단계에서는 앱을 사용하여 Azure Monitor를 구성하기 위해 Log Analytics 작업 영역을 만듭니다.
az monitor log-analytics workspace create --resource-group myResourceGroup --workspace-name myMonitorWorkspace
진단 설정 만들기
Azure Monitor는 진단 설정을 사용하여 로그 쿼리를 사용하여 다른 모니터링 데이터를 사용하여 분석을 위해 특정 Azure 서비스에 대한 메트릭을 수집합니다. 이 자습서에서는 웹 서버 및 표준 출력/오류 로그를 사용하도록 설정합니다. 로그 유형 및 설명의 전체 목록은 지원되는 리소스 로그를 참조하세요.
다음 명령을 실행하여 (표준 출력/오류) 및 AppServiceConsoleLogs (웹 서버 로그)에 대한 AppServiceHTTPLogs 진단 설정을 만듭니다.
<app-name> 및 <workspace-name>을 사용자 고유의 값으로 바꿉니다.
resourceID=$(az webapp show -g myResourceGroup -n <app-name> --query id --output tsv)
workspaceID=$(az monitor log-analytics workspace show -g myResourceGroup --workspace-name myMonitorWorkspace --query id --output tsv)
az monitor diagnostic-settings create --resource $resourceID \
--workspace $workspaceID \
-n myMonitorLogs \
--logs '[{"category": "AppServiceConsoleLogs", "enabled": true},
{"category": "AppServiceHTTPLogs", "enabled": true}]'
참고 항목
처음 두 명령인 resourceID 및 workspaceID는 az monitor diagnostic-settings create 명령에 사용되는 변수입니다. 자세한 내용은 Azure CLI를 사용하여 진단 설정 만들기를 참조하세요.
앱 문제 해결
http://<app-name>.azurewebsites.net으로 이동합니다.
샘플 앱인 ImageConverter는 포함된 이미지를 JPG 에서 PNG로 변환합니다. 이 자습서의 코드에 버그가 의도적으로 배치되었습니다. 이미지가 충분하게 선택되면 이미지 변환 중에 앱에서 HTTP 500 오류를 생성합니다. 이 시나리오는 개발 단계에서 고려되지 않았다고 가정합니다. Azure Monitor를 사용하여 이 오류를 해결합니다.
앱 작동 확인
이미지를 변환하려면 도구를 선택한 다음 PNG로 변환을 선택합니다.
처음 두 이미지를 선택하고 변환을 선택합니다. 이렇게 하면 성공적으로 변환됩니다.
앱 중단
두 이미지를 성공적으로 변환하여 앱을 확인한 후 처음 5개의 이미지를 변환해 봅니다.
이 작업은 실패하고 개발 중에 테스트되지 않은 HTTP 500 오류를 생성합니다.
로그 쿼리를 사용하여 Azure Monitor 로그 보기
Log Analytics 작업 영역에서 사용할 수 있는 로그를 확인해 보겠습니다.
Azure Portal에서 작업 영역에 액세스하려면 이 Log Analytics 작업 영역 링크를 선택합니다.
Azure Portal에서 Log Analytics 작업 영역을 선택합니다.
로그 쿼리
로그 쿼리를 사용하면 Azure Monitor 로그에서 수집된 데이터의 값을 완벽하게 적용할 수 있습니다. 로그 쿼리를 사용하여 둘 다 AppServiceHTTPLogsAppServiceConsoleLogs에서 로그를 식별합니다. 자세한 내용은 Azure Monitor의 로그 쿼리를 참조하세요.
로그 쿼리를 사용하여 AppServiceHTTPLogs 보기
앱에 액세스한 후 AppServiceHTTPLogs에 있는 HTTP 요청과 연결된 데이터를 봅니다.
사이드바 메뉴에서 로그 를 선택합니다.
appservice를 검색하고 AppServiceHTTPLogs를 두 번 클릭합니다.
실행을 선택합니다.
쿼리는 AppServiceHTTPLogs 지난 24시간 동안의 모든 요청을 반환합니다.
ScStatus 열에는 HTTP 상태가 포함됩니다. HTTP 500 오류를 진단하려면 ScStatus으로 제한 하고 쿼리를 실행합니다.
AppServiceHTTPLogs
| where ScStatus == 500
로그 쿼리를 사용하여 AppServiceConsoleLogs 보기
HTTP 500을 확인한 후 앱의 표준 출력/오류를 살펴봅니다. 이러한 로그는 AppServiceConsoleLogs에서 찾을 수 있습니다.
새 쿼리를 만들려면 선택합니다 + .
AppServiceConsoleLogs 테이블을 두 번 클릭하고 실행을 선택합니다.
5개의 이미지를 변환할 때 서버 오류가 발생하므로, 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 및 표준 오류를 모두 식별한 후에는 이러한 메시지 간에 상관 관계가 있는지 확인해야 합니다. 타임스탬프 기준으로 테이블을 조인합니다.
참고 항목
다음을 수행하는 쿼리가 준비되었습니다.
- 500 오류에 대해 HTTPLogs 필터링
- 콘솔 로그 쿼리
-
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 열에는 웹 서버 오류와 동시에 다음 오류가 표시됩니다.
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 오류를 생성했음을 확인했습니다. 문제를 식별하는 코드를 살펴보겠습니다.
오류 식별
로컬 디렉터리 App-Service-Troubleshoot-Azure-Monitor에서 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
이 명령을 실행하는 데 1분 정도 걸릴 수 있습니다.
다음 명령을 실행하여 진단 설정을 삭제합니다.
az monitor diagnostic-settings delete --resource $resourceID -n myMonitorLogs