영업: 1-800-867-1380

Azure 응용 프로그램 개발을 위한 최선의 문제 해결 방법

업데이트 날짜: 2014년 4월

저자: William Bellamy, Microsoft Principal Escalation Engineer

참여자:

  • Bryan Lamos, Microsoft Senior Program Manager, Product Quality

  • Kevin Williamson, Microsoft Senior Escalation Engineer, Azure Developer Support

  • Pranay Doshi, Microsoft Senior Program Manager, Windows Azure Production Services

  • Tom Christian, Microsoft Senior Escalation Engineer, Azure Developer Support

게시 날짜: 2012년 1월

Microsoft가 최우선적으로 고려하는 사항은 Windows Azure 고객이 응용 프로그램을 지속적으로 실행하도록 지원하는 것입니다. Windows Azure 서비스 수준 계약에는 둘 이상의 역할 인스턴스를 배포할 경우 외부 연결 성공률이 99.95%로 정의되어 있습니다. 그러나 외부 연결은 Microsoft 데이터 센터 외부에서 응용 프로그램에 연결할 수 있음을 보장하며, 이는 "사이트 실행"과는 다릅니다. 대부분의 Windows Azure 서비스에는 SQL Azure, 캐싱, 콘텐츠 배달 네트워크, 내부 리소스(Windows Azure Connect 사용) 등 여러 종속성이 있습니다. 이러한 종속성 중 하나에서 오류가 발생하면 Windows Azure 서비스가 정상적으로 작동하지 않을 수 있습니다.

이 문서에서는 Microsoft의 Windows Azure 플랫폼에서 지원 가능성이 보다 뛰어난 응용 프로그램을 디자인 및 개발하기 위한 여러 가지 문제 해결 및 접근 방법을 중점을 다룹니다. 문제가 발생한 경우 시간이 매우 중요합니다. 적절한 계획이 있으면 Microsoft에 지원을 요청하지 않고도 문제를 찾아서 해결할 수 있습니다. 이 문서에서 권장하는 접근 방법은 Microsoft 지원이 필요한 문제를 신속하게 해결하는 데에도 도움이 됩니다.

이 문서는 Windows Azure 솔루션을 디자인, 빌드 및 배포하는 소프트웨어 디자이너, 설계자, IT 전문가, 시스템 통합업체, 개발자, 테스터 등의 기술 소프트웨어 종사자를 대상으로 합니다.

이 문서에서는 Windows Azure 개발 및 런타임 환경의 다양한 구성 요소 및 용어를 비롯하여 Windows Azure 응용 프로그램의 개발 수명 주기를 기본적으로 이해하고 있는 것으로 가정합니다.

또한 최신 버전의 Windows Azure SDK를 사용하고 프로덕션 환경에 적용하기 전에 코드 변경 내용을 테스트하는 등 Windows Azure에 대한 기본 지침을 준수할 것으로 가정합니다.

이 문서는 다음 두 섹션으로 구성되어 있습니다.

  • Windows Azure 진단 리소스 개요

    • Windows Azure 리소스

    • 타사 리소스

  • 지원 가능한 디자인, 개발 및 배포에 대한 모범 사례

    • 응용 프로그램 배포를 시작하기 전에

    • 빠른 오류 디자인 및 모니터링

    • 문제가 발생한 경우 수행할 작업

프로덕션에 적용한 후 응용 프로그램의 작동이 중지될 것이라고 예상하는 개발자는 없습니다. Microsoft는 다음 프로젝트로 전환하는 동안 오류 없이 실행되도록 개발 중 최선을 다해 코드를 테스트합니다. 하지만 코드가 중단되는 경우가 있습니다. 분산된 환경에서는 응용 프로그램 구성 요소의 분리에 내재된 복잡성으로 인해 사소한 오류가 심각한 문제로 발전할 수 있습니다. 따라서 처음부터 응용 프로그램에 대한 로깅 및 추적 전략을 수립해야 합니다. 이 전략에는 구성 요소 수준의 로깅 유형 및 볼륨을 다시 빌드/다시 배포할 필요 없이 동적으로 조정되는 프로비전을 포함하는 것이 가장 좋습니다. 로그 볼륨이 많다고 신속한 문제 해결이 보장되는 것은 아닙니다. 데이터가 많으면 암호를 해독하는 데 오래 걸리고 잠재적으로 응용 프로그램 성능이 저하될 수 있으므로 로그가 반드시 많아야 하는 것은 아닙니다. 조정 가능한 로깅은 로그 데이터의 크기와 저장소 비용을 모두 절감해 줍니다.

Windows Azure 플랫폼에서 실행되는 것과 같은 분산된 응용 프로그램에는 사용자가 응용 프로그램과 상호 작용할 때 서로 상호 작용하는 여러 구성 요소가 있습니다. 외부 서비스를 호출하기 위해 각별한 주의가 필요한 코드 흐름을 일관성 있게 로깅하면 거의 모든 사용자가 응용 프로그램의 실행 흐름을 따를 수 있게 됩니다. 이는 지금부터 프로덕션에서 문제가 발생하는 2년 동안 매우 중요할 수 있습니다. 다시 배포하지 않고 변경할 수 있도록 ServiceConfiguration.cscfg 파일에서 로깅 수준을 조정할 수 있는 것이 가장 좋습니다.

개발 중에 오류 정보를 최대한 많이 얻으려면 디버그 빌드를 사용하는 것이 편리합니다. 개발자는 일반적으로 디버그 문을 추가하며 일부는 오류 로깅용으로 구성하는 경우도 있습니다. 그러나 프로덕션 빌드에서는 디버그 문이 제거되므로 문제가 발생한 경우 활용할 수 없습니다. 대부분의 고객은 프로덕션 문제를 해결하기 위해 디버그 빌드로 다시 배포하기를 원치 않습니다. Mike Kelly는 개발자가 구성해야 하는 네 가지 유형의 진단 출력을 다음과 같이 설명합니다.

  • 디버그 출력 - 디버그 빌드에서만 자산 포함

  • 추적 - 실행 중 제어 흐름 추적

  • 이벤트 로깅 - 주요 이벤트

  • 오류 로깅 - 예외 또는 위험한 상황

대부분의 디버그 메시지는 여러 추적 수준을 활용하도록 추적 문에 작성될 수 있습니다. Windows Azure 진단을 사용하면 진단을 구성하고 전송을 금지하여 영구 저장소에 정보가 기록되는 경우를 제어할 수도 있습니다.

다음 섹션에서는 Windows Azure에서 응용 프로그램을 빌드하는 개발자가 사용할 수 있는 일부 문제 해결 리소스에 대해 설명합니다.

Windows Azure에 대해 알아보기 전에 먼저 Windows Server 응용 프로그램에 대한 현재의 문제 해결 패러다임을 살펴보겠습니다. 개발자는 일반적으로 프로덕션 문제가 발생한 경우 로그를 검사합니다. 이벤트 로그와 IIS 로그는 기본적으로 설정되며, 다시 시작 후에도 유지됩니다(디스크 오류가 발생하지 않는 한).

이 프로세스는 원격 데스크톱을 사용하는 경우 Windows Azure 응용 프로그램에도 동일하게 적용됩니다. 개발자는 각 인스턴스에 연결하여 진단 데이터를 수집할 수 있습니다. 즉, 로그를 저장소에 복사하여 수집하거나 로컬 컴퓨터에 복사할 수 있도록 RDP를 구성하여 수집할 수 있습니다. 이 프로세스는 시간이 오래 걸리고, 인스턴스를 이미지로 다시 설치하는 경우 실패하며 이로 인해 웹 또는 작업자 역할의 정리 버전이 시작됩니다. 분명히 이 정리 버전에는 이전 로그가 전혀 없습니다. 이미지로 다시 설치는 호스트 또는 게스트 가상 컴퓨터의 운영 체제 업그레이드가 있는 경우 발생할 수 있습니다. 이미지로 다시 설치는 Windows Azure 아키텍처의 정상적인 일부입니다.

원래 Windows Azure SDK 1.0에는 진단 정보를 수집하여 Windows Azure 저장소에 저장하는 기능(총칭하여 WAD(Windows Azure 진단)라고 함)이 있었습니다. ETW(Windows용 이벤트 추적) 프레임워크를 기반으로 하는 이 소프트웨어는 Windows Azure 수평 확장 아키텍처에서 도입된 다음 두 가지 디자인 요구 사항을 충족합니다.

  1. 인스턴스를 이미지로 다시 설치하는 동안 손실될 수 있는 진단 데이터를 저장합니다.

  2. 여러 인스턴스의 진단을 위한 중앙 리포지토리를 제공합니다.

Microsoft.WindowsAzure.Diagnostic 네임스페이스는 Windows Azure 응용 프로그램 내에서 ETW 프레임워크를 사용할 수 있도록 System.Diagnostics 네임스페이스를 확장합니다.

Windows Azure - 진단 흐름 다이어그램

Windows Azure 진단을 역할(ServiceConfiguration.cscfg 및 ServiceDefinition.csdef)에 포함한 후 WAD는 해당 특정 역할의 모든 인스턴스에서 진단 데이터를 수집합니다. 진단 데이터는 디버깅 및 문제 해결, 성능 측정, 리소스 사용 모니터링, 트래픽 분석 및 용량 계획, 감사 등에 사용될 수 있습니다. 지속성을 위해 Windows Azure 저장소 계정으로 데이터를 전송하는 작업은 예약하거나 요청 시 수행할 수 있습니다.

Windows Azure 진단은 다음 네 가지 중요한 방식으로 서버 패러다임을 변화시킵니다.

  1. 응용 프로그램을 만들 때 진단을 사용해야 합니다.

  2. 진단 결과를 시각화하기 위한 특정 도구/단계가 필요합니다.

  3. 영구 저장소(Windows Azure 저장소는 각 인스턴스에 있음)에 기록하지 않으면 크래시로 인해 진단 데이터가 손실됩니다.

  4. 진단 데이터를 Windows Azure 저장소에 저장할 경우 월별 비용이 발생합니다.

Windows Azure 플랫폼의 주요 이점 중 하나가 비용 절감이므로 비용은 특히 중요합니다. 현재 WAD 사용 비용을 없앨 수 있는 방법은 데이터를 가상 컴퓨터에 그대로 두는 방법밖에 없습니다. 이는 소규모 배포에서는 가능하지만 인스턴스가 많은 경우에는 실현하기 어렵습니다. 다음은 재정적 영향을 최소화하는 몇 가지 방법입니다.

  1. 저장소 계정이 응용 프로그램과 동일한 데이터 센터에 있는지 확인합니다. 동일한 데이터 센터에 없는 경우 예약 전송 간격을 적절히 선택합니다. 전송 시간이 짧으면 데이터 연관성이 증가하지만 추가 대역폭 및 처리 오버헤드를 상쇄할 정도로 유익하지 않을 수 있습니다.

  2. Windows Azure 저장소에서 정기적으로 진단 데이터를 복사하고 지웁니다. 진단 데이터는 Windows Azure 저장소를 경유하지만 불필요하게 상주하지는 않습니다. 이 작업을 수행하는 도구에는 Windows Azure용 System Center 모니터링 팩, Cerebrata의 Azure Diagnostics Manager, Windows Azure PowerShell cmdlet 등 여러 가지가 있습니다.

  3. 응용 프로그램 문제를 해결하고 모니터링하는 데 필요한 진단 데이터만 수집합니다. 너무 많은 데이터를 캡처하면 문제 해결이 힘들어질 뿐만 아니라 비용이 크게 증가할 수 있습니다.

  4. 응용 프로그램에 주문형 스위치를 구현하여 진단 데이터의 수집 및 범위를 제어합니다.

  5. 모든 정보를 사용할 수 있도록 로깅 수준(자세한 정보 표시, 정보, 경고, 오류)을 활용하고, 배포 후 WAD 구성을 통해 선택적으로 데이터를 수집합니다.

Windows Azure 저장소는 지원 가능한 모든 응용 프로그램의 기반입니다. 모든 응용 프로그램에서 이 기능을 구성하고 활성화하는 것이 가장 좋습니다.

Windows Azure 저장소 분석은 로깅을 수행하며, 저장소 계정에 대한 메트릭 데이터를 제공합니다. 이 데이터를 사용하여 저장소 요청을 추적하고, 사용 추세를 분석하며, 저장소 계정 문제를 진단할 수 있습니다.

지원 가능한 SQL Azure 코드를 작성하는 열쇠는 반환 코드를 검사하고 오류를 처리하는 견고한 다시 시도 코드를 유지하는 것입니다.

모니터링 팩Microsoft System Center Operations Manager를 사용하여 Windows Azure 응용 프로그램의 가용성 및 성능을 모니터링할 수 있도록 해줍니다.

  • Windows Azure 응용 프로그램을 검색합니다.

  • 각 역할 인스턴스의 상태를 제공합니다.

  • 성능 정보를 수집 및 모니터링합니다.

  • Windows 이벤트를 수집 및 모니터링합니다.

  • 각 역할 인스턴스에서 .NET Framework 추적 메시지를 수집 및 모니터링합니다.

  • Windows Azure 저장소 계정에서 성능, 이벤트 및 .NET Framework 추적 데이터를 영구 제거합니다.

  • 역할 인스턴스 수를 변경합니다.

Windows Azure 응용 프로그램의 상태를 모니터링하려면 Microsoft System Center Operations Manager 2007을 사용하는 것이 가장 좋습니다.

현재 Windows Azure에서는 고객이 호스팅된 서비스를 모니터링하고 관리할 수 있는 완전한 솔루션을 제공하지 않습니다. 네트워킹 정보의 경우 speedtest.net에서 응답 시간, 대역폭 및 전반적인 연결 품질을 측정하는 도구를 제공합니다. 서로 다른 Microsoft 데이터 센터 간의 대기 시간은 Matthew Rosoff의 Azure Statistics를 사용하여 볼 수 있습니다. 몇몇 도구는 Windows Azure와 함께 사용할 경우 매우 유용합니다. 다음 목록은 특정 타사 도구를 보증하거나 권장하지 않습니다.

Windows Azure PowerShell Cmdlet

원격으로 진단을 관리하는 가장 좋은 방법은 Windows Azure PowerShell Cmdlet을 사용하는 것입니다. 이러한 cmdlet은 Windows Azure 관리 및 진단 API를 기반으로 하며, 기본 API에 대한 이해를 돕기 위해 CodePlex 프로젝트를 통해 전체 소스 코드가 제공됩니다. 버전 2.0 릴리스에서는 Windows Azure 진단의 모든 면을 구성/다운로드/정리할 수 있습니다. Michael Washam의 블로그에 몇 가지 유용한 예제 스크립트가 있습니다.

네트워크 모니터링: AlertBot, Gomez, Keynote, Pingdom

Compuware의 Gomez 응용 프로그램 성능 관리, Keynote, PingdomAlertBot은 외부에서 Windows Azure 응용 프로그램을 모니터링하는 솔루션입니다. 이러한 솔루션을 통해 응용 프로그램 가용성을 모니터링하고 성능을 최적화할 수 있습니다. Pingom과 같은 일부 서비스는 오류가 감지된 경우 전자 메일, SMS 또는 데스크톱 알림 프로그램을 통해 알림을 보낼 수 있도록 지원합니다. 이 유형의 모니터링에서는 웹 역할이 제대로 작동하지 않고 홈 페이지를 표시하는 경우가 있으므로 최종 사용자가 수행하는 작업을 시뮬레이션해야 합니다.

Azure Check

Apica의 AzureCheck는 Windows Azure 웹 응용 프로그램을 "외부"에서 모니터링하는 도구입니다. 이 도구를 사용하려면 해당 코드를 다운로드하여 배포에 시작 태스크로 추가해야 합니다. 이 도구의 장점은 로그를 저장소 계정에 저장할 필요가 없으므로 모니터링 비용이 절감된다는 점입니다.

Azure Diagnostics Manager

Cerebrata의 Azure Diagnostic Manager는 Windows Azure 진단을 관리하는 Windows 기반 클라이언트입니다. WAD에서 수집된 로그를 표시하거나 다운로드합니다. 또한 WAD 구성을 관리할 수 있으며 대시보드를 통해 실시간 성능을 모니터링할 수 있습니다.

Azure 저장소 탐색기

여러 가지 방법으로 Windows Azure 저장소를 탐색할 수 있습니다. Windows Azure 저장소 팀이 저장소 탐색기 목록을 만들었습니다. 이러한 탐색기 중 하나를 사용하여 WAD 파일 및 Windows Azure 저장소 분석 파일을 볼 수 있습니다. Cloudberry Lab의 Explorer for Azure Blob StorageStorage Settings를 클릭하여 응용 프로그램에서 저장소 분석을 직접 실행할 수 있는 사용자 인터페이스를 제공합니다.

IntelliTrace

Microsoft Visual Studio 2010 Ultimate에는 프로덕션에 배포하기 전에 응용 프로그램을 디버깅하는 데 사용할 수 있는 IntelliTrace가 포함되어 있습니다. IntelliTrace는 ASP.NET 및 WCF 응용 프로그램을 지원합니다. Intellitrace는 프로덕션 서비스에서 지원되지 않지만 Windows Azure에 배포한 후 응용 프로그램에 대한 예외를 가져오는 데 사용할 수 있습니다. Jim Nakashima의 블로그 게시물엔 IntelliTrace를 사용하여 Windows Azure 클라우드 서비스를 디버깅하는 방법이 설명되어 있습니다.

AVIcode

Microsoft에서는 AVIcode를 구입하여 현재 Microsoft System Center의 일부로 제공하고 있습니다. AVIcode는 포괄적인 응용 프로그램 모니터링 기능과 함께 .NET 응용 프로그램 성능 모니터링 기능을 제공합니다.

Fiddler

Fiddler는 컴퓨터와 인터넷 간의 모든 HTTP(S) 트래픽을 로깅하는 웹 디버깅 프록시입니다. Fiddler를 사용하면 트래픽을 검사하고, 중단점을 설정하고, 들어오거나 나가는 데이터를 "조작"할 수 있습니다. Fiddler는 Windows Azure 저장소 문제를 해결하는 데 특히 유용합니다.

로컬 개발 패브릭에서 Fiddler를 사용하려면 127.0.0.1 대신 ipv4.fiddler를 사용합니다.

  1. Fiddler를 시작합니다.

  2. 개발 패브릭에서 서비스를 시작합니다.

  3. http://ipv4.fiddler:/로 이동합니다. Fiddler에서 요청을 추적합니다.

로컬 개발 저장소에 대해 Fiddler를 사용하려면 Fiddler를 가리키도록 서비스 구성 파일을 수정해야 합니다.

  1. ServiceConfiguration.cscfg 파일을 열고 연결 문자열을 다음으로 변경합니다.

    Value=“UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler”

  2. Fiddler를 시작합니다.

  3. 서비스를 시작합니다. Fiddler에서 모든 저장소 요청을 추적합니다.

성능 프로파일링

Windows Azure에서 Windows Azure 응용 프로그램이 실행될 때 프로파일링으로 모든 성능 문제를 확인할 수 있습니다. Visual Studio에서 Windows Azure 응용 프로그램을 게시하는 경우 응용 프로그램을 프로파일링하도록 선택하고 필요한 프로파일링 설정을 선택할 수 있습니다.

Windows Azure VM Assistant

VM Assitant 도구는 원격 데스크톱이 인스턴스에 설치된 경우 모든 관련 데이터를 한 곳에서 수집하여 문제를 진단하는 시간을 단축해 주는 CodePlex 프로젝트입니다. VM Health 단추를 클릭하면 인스턴스의 현재 상태가 표시됩니다.

클라우드 기반 솔루션에서는 회사 데이터 센터의 서버에 기존의 패키지 소프트웨어 제품을 배포하는 것보다 소프트웨어 디자이너와 개발자가 디자인할 때 문제에 대비하는 것이 더 중요합니다. 이 섹션에서는 개발자가 클라우드에서 완화해야 하는 몇 가지 특정 시나리오를 살펴보고 이러한 문제가 발생할 경우 신속하게 해결할 수 있도록 준비하는 방법에 대해 설명합니다.

기존 서버 기반 배포와의 근본적인 차이점은 더 이상 서버 하드웨어에 액세스할 필요가 없다는 점입니다. Windows Azure SDK 1.3에 원격 데스크톱 서비스를 사용하여 Windows Azure 역할에 액세스할 수 있는 기능이 추가되었습니다. 최신 SDK를 사용하면 최상의 환경을 경험할 수 있습니다. 원격 데스크톱 사용은 지원 가능한 Windows Azure 서비스를 만드는 데 필요한 첫 번째 단계입니다. 이 단계는 배포 전에만 수행할 수 있습니다.

원격 데스크톱을 사용하도록 설정하는 데 필요한 단계 중에 사용자 이름, 암호 및 계정 만료 날짜를 선택하는 단계가 있습니다. 이 세 항목은 Windows Azure 관리 포털에서 변경할 수 있습니다. 이는 서비스를 처음 배포하기 몇 달 전에 설정한 암호를 잊어버린 경우에 편리합니다.

포털에서 구성을 클릭하여 이 세 매개 변수를 변경할 경우 일반적으로 업데이트 중..., 호스트를 기다리는 중..., 역할이 업데이트되었습니다. 호스트를 기다리는 중…, 준비 시퀀스가 표시됩니다. 이는 변경 이벤트를 받은 다음 처리하는 역할에 해당합니다. 고객은 RoleEnvironment 이벤트를 구독한 다음 RoleEnvironment.Changing Event가 발생한 경우 변경 내용을 적용하고 실행을 계속(기본값)하거나, 인스턴스를 오프라인 상태로 전환하고 변경 내용을 적용한 다음 다시 온라인 상태로 전환(e.Cancel = true)할 수 있습니다.

코드가 변경 이벤트에서 역할을 재활용하는 경우 해당 호스팅된 서비스의 모든 역할에서 모든 인스턴스가 재활용됩니다. 역할당 여러 인스턴스가 있는 서비스는 업데이트 도메인 아키텍처로 인해 가동 중지 시간이 발생하지 않지만 각 도메인이 재활용될 때 성능이 저하될 수 있습니다. 특히, 한 달에 한 번만 재현되는 문제가 발생한 경우 인스턴스 상태를 캡처할 기회를 잃게 됩니다. 따라서 만료되지 않은 보안 자격 증명으로 원격 데스크톱 연결을 설정하는 것이 좋습니다.

그런 다음에는 연결이 작동하는지 테스트해야 합니다. 포털에서 연결 단추를 클릭하기만 하면 됩니다. 대부분의 경우 로컬 디스크를 포함하도록 로컬 리소스 섹션을 변경할 수 있게 RDP 파일의 복사본을 유지하는 것이 좋습니다. 그러면 인스턴스와 파일을 쉽게 복사할 수 있습니다. 이 작업을 수행하려면 로컬 리소스 탭을 클릭한 다음 자세히 단추를 클릭하면 됩니다. 일반 탭의 연결 설정을 사용하여 .RDP 파일에 설정을 저장할 수 있습니다.

Windows Azure - 원격 데스크톱 연결 대화 상자

VM에서 문제를 해결하는 방법

인스턴스에 연결한 다음에는 무엇을 해야 할까요? 시작하는 데 실패한 역할의 문제를 해결하려면 이 MSDN 문서를 검토합니다. Kevin Williamson의 블로그 게시물에는 로그 파일을 찾을 위치 및 디버깅 프로세스에 대한 개요가 잘 정리되어 있습니다.

VM Assistant를 설치하여 로그 파일을 확인하고 인스턴스에 대한 유용한 정보를 얻을 수도 있습니다. 또한 네트워크 모니터 또는 Fiddler와 같은 도구를 설치하여 네트워크에서 발생하는 상황을 확인할 수 있습니다. 가장 간단한 테스트 중 하나는 인스턴스에서 Internet Explorer를 실행하고 웹 사이트에 연결하는 것입니다. 이를 통해 예외 정보를 확인할 수 있습니다.

호스팅된 웹 코어 디버깅

호스팅된 웹 코어 역할을 실행하는 경우 가상 컴퓨터에서 하나의 명령 창만 사용할 수 있으므로 명령 프롬프트에서 start를 실행하여 새 Cmd 창을 열어야 합니다. 그러지 않으면 완전한 Windows Server 환경이 제공됩니다. 다음은 몇 가지 기본 명령의 목록입니다.

  • Start – 새 Cmd 창을 엽니다.

  • explorer – Windows 탐색기를 엽니다.

  • eventvwr – 이벤트 로그 뷰어를 엽니다.

  • taskmgr – 작업 관리자를 엽니다.

  • start iexplore – Internet Explorer를 실행합니다.

  • services.msc – 서비스 관리자를 엽니다.

  • control – 제어판을 엽니다.

  • certmgr.msc – 인증서 관리자 스냅인을 엽니다.

  • regedit – 레지스트리 편집기를 엽니다.

  • shutdown /r /t 0 – 가상 컴퓨터 인스턴스를 다시 시작합니다.

  • Start Task Manager – Cmd 프롬프트가 끊어진 경우 새 프롬프트를 시작하는 데 유용합니다(작업 관리자에서 파일 -> 실행 -> Cmd로 이동).

원격 데스크톱은 지원 가능한 Windows Azure 서비스의 기반이지만 역할 및 인스턴스 수가 증가할 경우 제한 사항이 있습니다. 예를 들어 100개 이상의 인스턴스가 있는 경우 연결해야 하는 인스턴스를 어떻게 알 수 있을까요? 이 문제 해결 방법을 사용하면 어디에서 무엇을 찾아야 하는지 모를 경우 사이트를 다시 실행하는 데 소요되는 시간이 실제로 증가할 수 있습니다.

요점은 다음과 같습니다.

  • 배포하는 동안 모든 역할에서 원격 데스크톱을 사용하도록 설정합니다.

  • 알고 있는 강력한 암호를 설정하고 자격 증명이 만료되지 않는지 확인합니다.

  • 문제가 발생하기 전에 액세스를 테스트하여 작동 상태를 확인합니다.

  • 연결을 위해 RDP 파일을 저장합니다.

Windows Azure 진단을 사용하는 네 가지 기본 태스크가 있습니다.

  1. WAD 설정

  2. 데이터 수집 구성

  3. 코드 계측

  4. 데이터 보기

WAD 설정

Windows Azure 진단의 아키텍처는 먼저 인스턴스에서 데이터를 수집한 다음 Windows Azure 저장소에 데이터를 유지하는 것입니다. 따라서 먼저 Windows Azure 관리 포털로 이동하여 저장소 계정(예: mylogs)을 만들어야 합니다. 외부 대역폭 비용을 지불하지 않고 대기 시간을 줄이기 위해서는 Windows Azure 응용 프로그램과 동일한 지리적 위치의 저장소 계정을 찾는 것이 가장 좋습니다.

Windows Azure Tools for Visual Studio 버전 1.4(2011년 8월) 이상의 유용한 개발 기능 중 하나는 로컬용과 클라우드용으로 서로 다른 구성 파일(ServiceConfiguration.cscfg)을 유지할 수 있는 것입니다. Nick Harris가 자신의 블로그에서 설명한 대로 이 기능은 여러 용도에 유용합니다. 여러 서비스 구성은 프로덕션에 대해 별도의 구성 파일을 유지하면서 무료로 로컬 테스트에 대해 저장소 에뮬레이터를 사용할 수 있으므로 진단에 유용합니다. Windows Azure에 게시된 경우 응용 프로그램이 시작되지 않는 이유 중 하나는 UseDevelopmentStorage=true가 포함된 연결 문자열을 false로 변경하지 않았기 때문입니다.

Visual Studio에서 Windows Azure 저장소 에뮬레이터 사용 단추를 클릭하면 테스트 중에 진단을 쉽게 사용할 수 있습니다.

Windows Azure - 저장소 계정 연결 대화 상자

응용 프로그램의 테스트를 완료하고 게시할 준비가 되면 저장소 계정을 클라우드(ServiceConfiguration.Cloug.cscfg)용으로 구성해야 합니다. David Makogon의 블로그에 저장소 계정을 응용 프로그램 데이터 저장소와 별도로 특별히 진단용으로 구성해야 하는 다음 세 가지 이유가 나와 있습니다.

  1. 별도의 진단용 액세스 키가 있으면 응용 프로그램 데이터에 대한 위험 없이 로그에 액세스할 수 있습니다.

  2. 비용은 데이터 크기에 따라 부과되므로 여러 저장소 계정을 유지해도 비용이 발생하지 않습니다.

  3. 별도의 계정을 유지하면 성능이 향상됩니다.

그런 다음 연결 문자열을 설정합니다.

<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=<name>;AccountKey=<key>" />

AccountNameAccountKey 값은 관리 포털의 저장소 계정 섹션에서 확인할 수 있습니다. AccountName은 테이블 및 Blob 저장소 끝점을 나타내는 URL의 첫 부분입니다(“.table.core.windows.net” 앞 부분). AccountKey는 base-64로 인코딩된 저장소 계정의 기본 액세스 키입니다.

기본적으로 Windows Azure 로그만 활성화되지만 영구적이지 않으므로, 다음 단계에서는 수집할 데이터의 양과 로그를 전송할 시점을 결정해야 합니다. 이러한 사항은 응용 프로그램의 성능에 영향을 주며 월별 저장소 비용을 결정하므로 신중하게 결정해야 합니다.

먼저 Windows Azure 진단에서 수집하는 데이터에 필요한 총 저장소 크기를 결정해야 합니다. 이 값은 인스턴스/가상 컴퓨터 크기에 대한 디스크 크기 및 DiagnosticMonitorConfiguration 클래스의 OverallQuotaInMB 속성에 따라 다릅니다. 예를 들어 ExtraSmall 가상 컴퓨터 크기를 사용하도록 서비스 모델을 구성한 경우 사용 가능한 로컬 저장소의 최대 크기는 20GB입니다. 기본적으로 OverallQuotaInMB는 4GB로 설정되므로 로컬 저장소에서는 총 16GB만 사용할 수 있으며, 이는 응용 프로그램 및 임시 파일에 사용하기에 부족할 수 있습니다. OverallQuotaInMB는 다시 쓰기 가능한 래핑 버퍼의 크기를 설정합니다. 반면, 웹 사이트의 트래픽이 많고 많은 성능 카운터를 구성한 경우에는 진단 데이터를 덮어쓸 수 있으며, 특히 데이터를 정기적으로 영구 저장소로 전송하지 않는 경우 그 가능성이 더욱 높습니다.

가상 컴퓨터 크기를 설정한 후 4GB보다 더 크게 설정하고 싶어질 수 있습니다. 이 경우 sizeInMB 특성이 새 크기로 설정된 DiagnosticStore의 <LocalStorage> 요소를 ServiceDefinition.csdef 파일에 추가하고 그에 따라 OverallQuotaInMB 값을 변경하면 됩니다.

<LocalResources>
      <LocalStorage name="DiagnosticStore" sizeInMB="8192" cleanOnRoleRecycle="false" />
    </LocalResources>

cleanOnRoleRecycle 특성 값을 false로 설정하면 역할이 재활용되는 경우 로컬 저장소 "DiagnosticStore"가 삭제되지 않습니다. ServiceDefinition.csdef의 전체 코드는 부록 D: ServiceDefinition.csdef를 참조하세요. 이 설정을 사용해도 인스턴스가 이동한 경우(하드웨어 문제 등)에는 데이터가 그대로 유지되지 않을 수 있습니다. 진단 설정은 하나의 역할에만 특정하므로 각 역할에 대해 DiagnosticStore를 개별적으로 추가해야 합니다.

합계가 OverallQuotaInMB를 초과하면 Windows Azure 진단에 실패하므로 구성한 진단 데이터의 집계 크기를 계산하는 것이 매우 중요합니다. 이 오류를 확인하는 방법은 디버거를 연결하거나 OnStart 메서드에 try catch를 추가하는 방법밖에 없습니다. catch 코드에서 이벤트를 작성한 경우 응용 프로그램 이벤트 로그에 표시되는 내용은 다음과 같습니다.

Windows Azure - 이벤트 로그

그렇다면 "요청된 하위 할당량의 합계"는 어떻게 계산할까요? 각 항목 컬렉션 유형(이벤트 로그, 성능 카운터 등)에는 연결된 데이터 버퍼(기본적으로 0)가 있습니다. BufferQuotaInMB 속성은 기본값(0)으로 그대로 두거나(OverallQuotainMB보다 작음을 의미함) 명시적으로 설정할 수 있습니다. OverallQuotaInMB는 모든 BufferQuotaInMB 속성의 합계보다 작아야 합니다.

할당량에 도달하면 새 데이터가 추가되는 경우 가장 오래된 데이터가 삭제됩니다. 이 삭제 정책은 버퍼에 대해 전송 간격을 구성한 경우에도 적용됩니다. 전송이 발생한 후 데이터는 로컬 저장소에 그대로 유지되며 위 정책에 따라 삭제됩니다.


// Set an overall quota of 8GB.
config.OverallQuotaInMB = 8192;

// Set the sub-quotas and make sure it is less than the OverallQuotaInMB set above
config.Logs.BufferQuotaInMB = 1024;
config.Directories.BufferQuotaInMB = 0; // Use the rest of the storage here
 config.WindowsEventLog.BufferQuotaInMB = 1024;
config.PerformanceCounters.BufferQuotaInMB = 1024;
config.DiagnosticInfrastructureLogs.BufferQuotaInMB = 1024;

디렉터리 하위 할당량은 사용 가능한 나머지 저장소 할당량을 사용하도록 0으로 설정됩니다. 특정 값을 지정하는 경우 이 값은 IIS 로그(웹 역할)와 크래시 덤프를 충분히 포함할 수 있어야 하므로 다른 할당량보다 크거나 같아야 합니다. 기본적으로 Directory.QuotaInMB는 1024MB로 설정됩니다. 이는 크래시 덤프가 1GB보다 큰 경우 덤프를 작성하지 못함을 의미합니다. 미니 덤프는 덤프 크기를 줄이는 한 가지 방법입니다.

전체 덤프 파일은 크래시 당시의 프로세스 메모리(가상 바이트)를 포함합니다. 현재 64비트 버전의 Windows를 실행하므로 메모리 상한값은 컴퓨터의 실제 메모리가 됩니다. 이 값은 이 인스턴스/가상 컴퓨터 크기 테이블의 메모리 열에서 확인할 수 있습니다. 예를 들어 ExtraLarge 인스턴스의 전체 크래시 덤프는 최대 14GB일 수 있습니다. 이는 분명히 프로세스에서 사용 가능한 모든 메모리를 사용하는 최악의 시나리오이지만 실제로 덤프 파일을 캡처하는 경우에는 이러한 상황이 발생하지 않습니다.

수집할 진단 데이터의 크기를 알았으므로 이제 이 데이터의 지속성을 위한 전략을 결정해야 합니다.

문제가 발생한 것을 확인할 때까지 데이터 수집을 시작하지 않는 것이 한 가지 옵션입니다. 이 옵션에는 다음 두 가지 단점이 있습니다.

  1. 문제가 발생한 것을 어떻게 알 수 있을까요? 고객은 중요한 문제가 보고될 것이라고 믿을 수 있지만 메모리 누수와 같은 더 심각한 문제는 어떻게 될까요?

  2. 문제가 시작되는 기준선은 무엇일까요? 응용 프로그램이 항상 80%의 CPU로 실행되어야 하는데 그렇지 않으면 이것이 문제의 증상일까요?

놀랍게도 이 옵션은 비용, 계획 또는 작업이 필요하지 않으므로 가장 일반적으로 사용되고 있습니다. 하지만 분명히 최악의 옵션이기도 합니다.

두 번째 옵션은 필요한 모든 카운터를 설정하되, 데이터를 Window Azure 저장소에 유지하지 않는 것입니다. 문제가 발생한 경우 데이터를 검사하거나 수동으로 전송을 시작할 수 있습니다. 이는 문제가 나타날 때까지 비용이 발생하지 않으므로 이상적인 솔루션처럼 보입니다. 하지만 이 옵션에도 첫 번째 옵션과 동일한 문제가 있으며, 복구 시간이 증가합니다.

세 번째 옵션은 여러 ScheduledTransferPeriod 속성을 인스턴스에서 진단 데이터를 덮어쓰지 않을 만큼 작지만 응용 프로그램 성능에 영향을 주지 않을 만큼 크게 설정하는 것입니다. 지정할 수 있는 가장 짧은 전송 기간은 1분이며, 이보다 작은 값은 지속성이 해제되지 않도록 1로 반올림됩니다. 따라서 진단 데이터가 실제로 필요하기 전에 전송되는지 확인해야 합니다.

대부분의 코드 예제에서 나타나는 한 가지 공통적인 문제는 ScheduledTransferPeriod가 1분으로 설정되어 있다는 것입니다. 이 값은 프로덕션에서 응용 프로그램의 성능을 저하시킵니다. 예제에서 최소값을 사용하는 이유는 작동 여부를 신속하게 확인할 수 있기 때문입니다. 대부분의 개발자는 로그가 전송되었는지 확인하려고 30분을 기다리지 않습니다. 이 문제를 해결하는 방법에는 두 가지 방법이 있습니다. 기타 유용한 도구 중 하나를 사용하여 배포 후 WAD 구성을 시스템적인 방법으로 수정하거나, 이 섹션의 앞부분에서 언급한 여러 서비스 구성 파일 기능을 활용하여 ServiceConfiguration.cscfg 파일에 코드와 설정을 추가하는 것입니다. 이 설정은 ServiceConfiguration.Local.cscfg에서 다음과 같이 생성됩니다.

<ConfigurationSettings>
      <Setting name="ScheduledTransferPeriod" value="1" />

ServiceConfiguration.Cloud.cscfg에서는 다음과 같습니다.

<ConfigurationSettings>
      <Setting name="ScheduledTransferPeriod" value="30" />

OnStart 메서드와 RoleEnvironmentChanging 이벤트의 코드는 다음과 같습니다.

// Get ScheduledTransferPeriod setting from ServiceConfiguration.cscfg and then set it 
var myScheduledTransferPeriod = RoleEnvironment.GetConfigurationSettingValue("ScheduledTransferPeriod");
TimeSpan myTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(myScheduledTransferPeriod));
config.Logs.ScheduledTransferPeriod = myTimeSpan;
config.Directories.ScheduledTransferPeriod = myTimeSpan;
config.WindowsEventLog.ScheduledTransferPeriod = myTimeSpan;
config.PerformanceCounters.ScheduledTransferPeriod = myTimeSpan;
config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = myTimeSpan;

수집되는 데이터의 양에 영향을 주는 다른 변수는 로깅 수준입니다. 수집할 가장 중요한 데이터 원본 중 하나는 응용 프로그램 이벤트 로그입니다. 응용 프로그램 이벤트 로그와 함께 시스템 이벤트 로그도 유용할 수 있습니다. 보안 이벤트 로그는 WAD를 통해 사용할 수 없습니다. 다음 필터 값으로 로그 항목 수준을 지정하여 이러한 파일의 크기를 줄일 수 있습니다.

  • 중요

  • 오류

  • 경고

  • 정보

  • 자세한 정보 표시

로깅 수준은 누적적이므로 필터가 경고로 설정된 경우 오류중요도 전송됩니다. 위 메서드를 사용하여 로컬 및 클라우드 구성에 특정한 LogLevelFilter 수준을 구성할 수 있습니다. ServiceConfiguration.Local.cscfg는 다음과 같습니다.

<Setting name="LogLevelFilter" value="Information" />

ServiceConfiguration.Cloud.cscfg는 다음과 같습니다.

      <Setting name="LogLevelFilter" value="Error" />

OnStart 메서드와 RoleEnvironmentChanging 이벤트의 코드는 다음과 같습니다.

// Get LogLevelFilter setting from ServiceConfiguration.cscfg and then set it
var LogLevelFilter = RoleEnvironment.GetConfigurationSettingValue("LogLevelFilter");
var myLogLevel = LogLevel.Undefined;
switch (LogLevelFilter)
{
    case ("Information"):
        myLogLevel = LogLevel.Information;
        break;
    case ("Verbose"):
        myLogLevel = LogLevel.Verbose;
        break;
    case ("Warning"):
        myLogLevel = LogLevel.Warning;
        break;
    case ("Critical"):
        myLogLevel = LogLevel.Critical;
        break;
    case ("Error"):
        myLogLevel = LogLevel.Error;
        break;
    default:
        break;
} 

// Filter what will be sent to persistent storage.
config.Logs.ScheduledTransferLogLevelFilter = myLogLevel;
config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = myLogLevel;
config.WindowsEventLog.ScheduledTransferLogLevelFilter = myLogLevel;

제안된 코드가 요구 사항에 맞을 수도 있고 그렇지 않을 수도 있을 것입니다. 코드를 추가하지 않고, 코드에 설정된 것 대신 마지막으로 알려진 구성을 사용하려는 경우 다른 솔루션이 있습니다.

구성 파일 사용

Windows Azure SDK 1.3에는 코드를 작성하는 대신 XML 파일에 구성을 저장하는 기능이 추가되었습니다. David Hardin은 이것이 모든 유형의 Windows Azure 역할에 대한 진단을 구성하는 가장 효율적인 방법이라고 주장합니다. 이 방법은 코드를 작성하는 것보다 많은 장점이 있습니다.

  1. OnStart가 실행되기 전에 WAD가 시작되므로 시작 태스크의 오류가 발생하지 않습니다.

  2. 런타임에서 적용한 구성 변경이 다시 시작한 후에도 유지됩니다.

  3. 역할이 시작되지 않는 예외를 일으킬 수 있는 추가 코드 없이, 설정된 구성으로 진단 에이전트를 자동으로 시작합니다.

  4. 베타 가상 컴퓨터 역할에서 진단을 받는 유일한 방법입니다.

  5. 코드를 다시 작성할 필요 없이 구성을 변경할 수 있습니다.

예제 diagnostics.wadcfg부록 F: diagnostics.wadcfg에서 확인할 수 있습니다. diagnostics.wadcfg라는 구성 파일을 다음 위치에 두고 출력 디렉터리로 복사 설정을 항상 복사로 설정해야 합니다.

  • 작업자 역할의 경우 구성 파일이 역할의 루트 디렉터리에 있습니다.

  • 웹 역할의 경우 구성 파일이 역할의 루트 디렉터리 아래 bin 디렉터리에 있습니다.

  • 베타 가상 컴퓨터 역할의 경우 Windows Azure 관리 포털에 업로드하는 서버 이미지의 %ProgramFiles%\Windows Azure Integration Components\<VersionNumber>\Diagnostics 폴더에 구성 파일이 있어야 합니다. <VersionNumber>은 사용 중인 Windows Azure SDK의 버전입니다. 기본 파일은 이 폴더에 있으며, 이 파일을 수정하거나 소유한 다른 파일로 덮어쓸 수 있습니다.

이 파일의 형식은 다음 MSDN 문서에 설명되어 있습니다. wad-control-container Blob 저장소 컨테이너에 XML 구성이 이미 있는 경우 .wadcfg 파일은 무시됩니다. 파일의 모든 내용이 올바른지도 확인해야 합니다. 올바르지 않으면 진단이 수집되지 않습니다.

이제 수집할 정보를 결정할 준비가 완료되었습니다.

데이터 수집 구성

구성 파일을 사용하지 않으려는 경우에는 try/catch 블록 내의 OnStart 메서드에서 진단을 시작하는 것이 가장 좋습니다. 이 블록은 문제가 있는 경우 정상적으로 처리할 수 있도록 함으로써 역할이 재활용되는 것을 방지합니다. OnStart 메서드에 코드를 입력할 경우 모든 예외를 처리하지 않으면 역할이 재활용되어 디버깅하기 어려워지는 문제가 있습니다. 이 방법을 사용하는 동안에는 역할 인스턴스가 Busy로 설정되어 Windows Azure 부하 분산 장치를 통해 인스턴스를 사용할 수 없게 됩니다. OnStart 메서드에서 false를 반환하거나 예외가 발생한 경우에는 역할 인스턴스가 즉시 중지됩니다. 메서드에서 true를 반환한 경우에는 Windows Azure에서 Run 메서드를 호출하여 역할을 시작합니다.

OnStart 코드를 try/catch 블록으로 래핑하면 예외가 발생한 경우 역할이 순환(관리 포털의 상태가 준비 상태로 전환되지 않음)되는 것을 방지할 수 있습니다. catch 코드는 Trace.WriteLine 메서드 호출(MSDN 예제)을 포함하거나 이벤트 로그 오류(ASP.NET 디버깅 블로그)를 로깅할 수 있습니다. 이벤트 로그에 이벤트를 로깅하면 역할이 시작되지 않는 이유를 보다 쉽게 확인할 수 있습니다. Tom Christian이 이 코드를 약간 변경하여 제안한 것은 다음과 같이 응용 프로그램 이벤트 로그에 예외를 로깅하는 것입니다.

catch (Exception e)  
    {
            string sSource;
            string sEvent;
            sSource = "WaAppAgent";
            sEvent = "WorkerRole OnStart Event: " + e.Message;
            EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Error, 0);
    }

전체 코드는 부록 B: 웹 역할 코드 예제에 있습니다. 진단을 구성하는 가장 강력한 방법은 관리 포털에서 구성을 동적으로 변경할 수 있도록 구성 파일과 코드를 둘 다 사용하는 것입니다.

Windows Azure 진단이 설정되었으므로 이제 데이터 수집을 시작할 수 있습니다. 수집할 수 있는 데이터 형식은 다음 5가지입니다.

  • 크래시 덤프

  • Windows 이벤트 로그

  • 성능 카운터

  • IIS 로그

  • FREB 로그

아래 표에는 기본적으로 로컬로 수집되는 데이터 및 명시적으로 구성해야 하는 데이터에 대한 개요가 나와 있습니다.

 

데이터 원본 기본 구성 설명

DiagnosticInfrastructureLogs

사용. 로컬로 저장되며, 영구 저장소로의 전송은 정의되지 않습니다. 저장소 테이블 WADDiagnosticInfrastructureLogsTable로 전송합니다.

진단 인프라 자체에 특정한 로그입니다. 일반적으로 그다지 유용하지 않습니다.

로그

사용. 로컬로 저장되며, 영구 저장소로의 전송은 정의되지 않습니다. 저장소 테이블 WADLogsTable로 전송합니다.

응용 프로그램 코드에 배치되는 System.Diagnostics.Trace 로그입니다.

디렉터리

wad-iis-failedreqlogfiles , wad-iis-logfileswad-crash-dumps Blob이 기본적으로 자동으로 만들어지며, 각각 DirectoryQuotaInMB 속성이 1024MB로 설정됩니다. 또한 추가 디렉터리를 구성할 수 있습니다.

로그 데이터가 ScheduledTransferPeriod 전송 간격으로 전송됩니다.

PerformanceCounters

사용 안 함. 추가된 경우 저장소 테이블 이름은 WADPerformanceCountersTable입니다.

성능 카운터를 명시적으로 지정해야 합니다.

WindowsEventLog

사용 안 함. 추가된 경우 저장소 테이블 이름은 WADWindowsEventLogsTable입니다.

Windows 이벤트 로그에 지정된 DataSources가 없습니다.

CrashDumps

미니 크래시 덤프는 로컬로 수집됩니다. 전체 덤프를 사용할 수 있습니다. wad-crash-dumps는 Blob 저장소에서 만들어지는 이름입니다.

전체 크래시 덤프를 가져오려면 EnableCollection(true) 메서드를 호출합니다.

IIS 7.0 failed request trace data

사용 안 함. 추가된 경우 Blob 저장소 이름은 wad-iis-failedreqlogfiles입니다.

Web.config에서 사용하도록 설정해야 합니다.

  • 크래시 덤프

    Windows Azure 진단에서는 자동으로 크래시 덤프를 수집하지 않습니다. 구문이 혼동되기 때문에 미니 덤프를 수집하려면 다음 코드를 추가해야 합니다.

    // Enable crash mini dump collection.
                    CrashDumps.EnableCollection(false);
    
    전체 덤프를 수집하는 코드는 다음과 같습니다.

                    // Enable full crash dump collection.
                    CrashDumps.EnableCollection(true);
    
    Directory.QuotaInMB 설정의 경우 전체 덤프가 있으면 전체 덤프를 저장할 수 있는 로컬 저장소 및 전체 저장소를 할당해야 합니다.

  • 이벤트 로그

    이벤트 로그는 응용 프로그램 오류를 확인하는 가장 유용한 방법입니다. 응용 프로그램 및 시스템 이벤트를 추가하는 방법은 다음과 같습니다.

    // Add in configuration settings for Windows Event logs           config.WindowsEventLog.DataSources.Add("Application!*");
    config.WindowsEventLog.DataSources.Add("System!*");
    
    Windows Azure 진단이 시작된 이후에 발생한 이벤트만 수집되므로 진단을 시작 및 구성하는 권장 방법을 사용하지 않을 경우 이벤트 로그는 시작 문제를 진단하는 데 사용할 수 없습니다.

    특정 이벤트만 필터링할 수도 있습니다. Steve Marx의 블로그에 유용한 정보만 가져오는 XPath 쿼리를 만드는 방법이 설명되어 있습니다. 예를 들어 Add 메서드에서 다음 XPath 쿼리를 사용하면 WaAppAgent 메시지만 수집할 수 있습니다.

    ("Application!*[System[Provider[@Name='WaAppAgent']]]")
    
  • 성능 카운터

    성능 카운터는 명시적으로 추가해야 합니다. 이러한 카운터를 설정할 때의 어려움은 하나가 잘못된 경우 해당 역할의 모든 카운터가 실패한다는 점입니다. 계산 에뮬레이터 출력 창에 다음 오류가 표시됩니다.

    [MonAgentHost] Error:  PdhExpandWildCardPath(\Process(_Total)) failed
    
    웹 및 작업자 역할에서는 여러 언어를 사용할 수 있습니다. 모든 역할에서 권장되는 기본 성능 카운터는 다음과 같습니다. 웹 역할의 경우 아래 예제에서 프로세스 이름(WaWorkerHost)을 WaIISHost로 변경해야 합니다. .NET 코드를 실행하지 않는 작업자 역할에 특정한 코드는 부록 C: 작업자 역할 코드 예제에서 확인할 수 있습니다.

    • @"\Process(WaWorkerHost)\% Processor Time "

    • @"\Process(WaWorkerHost)\Private Bytes "

    • @"\Process(WaWorkerHost)\Thread Count"

    • @"\Processor(_Total)\% Processor Time"

    • @"\Memory\Available Bytes"

    .NET 언어 코드를 실행하는 웹 역할 또는 작업자 역할의 경우 모니터링해야 하는 추가 카운터가 있습니다. 아래 예제에서 프로세스 이름(w3wp)은 작업자 역할의 경우 WaWorkerHost로 변경하고, 전체 IIS 모드에서 웹 역할을 사용하는 경우 WaIISHost로 변경해야 합니다. .NET 언어 코드를 실행하는 웹 역할에 권장되는 카운터는 부록 B: 웹 역할 코드 예제에서 확인할 수 있습니다.

    • @"\Process(w3wp)\% Processor Time "

    • @"\Process(w3wp)\Private Bytes "

    • @"\Process(w3wp)\Thread Count "

    • @"\Processor(_Total)\% Processor Time"

    • @"\Memory\Available Bytes"

    • @"\ASP.NET\Applications Running"

    • @"\.NET CLR Interop(_Global_)\# of marshalling"

    • @"\.NET CLR Jit(_Global_)\% Time in Jit"

    • @"\.NET CLR Loading(_Global_)\% Time Loading"

    • @"\.NET CLR LocksAndThreads(_Global_)\Contention Rate / sec"

    • @"\.NET CLR Memory(_Global_)\# Bytes in all Heaps"

    • @"\.NET CLR Networking(_Global_)\Connections Established"

    • @"\.NET CLR Remoting(_Global_)\Remote Calls/sec"

    전체 IIS 모드를 사용하지 않는 경우 문자열 WaIISHost를 w3wp로 변경해야 합니다. 앞에서 설명한 것처럼 저장소에 유지되는 경우 또는 카운터가 저장소에 유지되는지 여부는 ScheduledTransferPeriod에 따라 결정됩니다.

  • IIS 로그

    Windows Azure 웹 역할은 기본적으로 로깅을 사용하는 상태로 IIS에서 실행되며, 로그 파일 롤오버가 매시간으로 설정된 응용 프로그램의 리소스 폴더(예: C:\Resources\directory\c5c31518818e46569fa68f0809b5a6aa.fm_WebRole.DiagnosticStore\LogFiles\Web)에 UTF-8로 인코딩된 W3C 형식으로 작성됩니다. 사이트당 하나의 로그 파일이 있습니다. 인스턴스 중 하나에 원격으로 액세스하여 인터넷 정보 서비스 관리자를 연 경우 다음 설정을 볼 수 있습니다.

    Windows Azure - 로깅 대화 상자

    특정 요구 사항에 맞게 기본 로깅 옵션을 수정할 수 있습니다. 각 인스턴스가 다시 시작될 때 설정이 손실되지 않도록 모든 변경 내용을 시작 태스크에 포함해야 합니다. 예를 들어 오류만 로깅하려면 다음 명령을 포함하는 시작 태스크에서 IIS7의 일부인 Appcmd.exe를 사용합니다.

    appcmd set config /section:httpLogging /dontLog:False /selectiveLogging:LogError
    
  • 실패한 요청 추적

    웹 역할이 있는 경우 실패한 요청 추적(이전의 FREB(실패한 요청 버퍼링)) 로그를 수집할 수 있습니다. 이 로그를 수집하려면 Web.config 파일에서 <system.webServer> 섹션에 다음 줄을 추가하면 됩니다.

    <tracing>
          <traceFailedRequests>
            <add path="*">
              <traceAreas>
                <add provider="ASP" verbosity="Verbose" />
                <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
                <add provider="WWW Server" areas="Authentication, Security, Filter, StaticFile, CGI, Compression, Cache, RequestNotifications,Module" verbosity="Verbose" />
              </traceAreas>
              <failureDefinitions timeTaken="00:00:20" statusCodes="400-599" />
            </add>
          </traceFailedRequests>
        </tracing>
    
    그러면 15초가 경과하거나 상태 코드가 400에서 599 사이(failureDefinitions 요소)인 모든 요청에 대한 로깅에 실패합니다. FREB 로그는 생성된 후 저장소에 자동으로 유지됩니다.

  • 기타 디렉터리

    인스턴스에 작성된 다른 파일, 특히 게스트 에이전트 파일을 수집할 수도 있습니다. 이러한 파일은 게스트 에이전트와 Windows Azure 패브릭 컨트롤러 사이에서 발생하는 사항에 대한 정보를 제공할 수 있습니다. 이러한 파일을 수집하려면 Windows Azure 진단에서 복사할 디렉터리를 설정해야 합니다.

              // Add a custom directory transfer
              DirectoryConfiguration directoryConfiguration = new DirectoryConfiguration();
              directoryConfiguration.Container = "wad-custom-logs";
              directoryConfiguration.DirectoryQuotaInMB = 0;
              directoryConfiguration.Path = @"c:\logs\WaAppAgent.log";
              config.Directories.DataSources.Add(directoryConfiguration);
    
    여기에서도 구성에 실패한 경우 발생할 수 있는 사항에 대해 동일한 주의 사항이 적용됩니다. 계산 에뮬레이터에서 테스트하려면 이 폴더를 만들고 여러 역할에서 이 코드를 실행하지 않도록 해야 합니다. 그렇지 않으면 공유 위반이 발생합니다. 클라우드 구성에서는 각 인스턴스가 구분되므로 이 오류가 발생하지 않습니다.

WAD 문제 해결

모든 사항을 구성했으므로 이제 계산 에뮬레이터와 Windows Azure 둘 다에서 테스트해야 합니다. 진단이 표시되지 않는 경우 어떻게 된 것일까요? 다음은 확인할 사항의 목록입니다.

  1. 진단 저장소 계정의 wad-control-container Blob 컨테이너에서 Blob을 확인합니다. 이름이 <deploymentID>/<RoleName>/<RoleInstance>인 Blob(예: 3981bcff0eb743ddb9b7574a8821e955/WebRole1/WebRole1_IN_0)을 찾습니다.

    1. XML 파일을 열고 예상대로 구성되었는지 확인합니다. 지정된 데이터 원본에 대해 <ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>가 표시되는 경우 이는 진단이 데이터를 전송하도록 구성되지 않았음을 의미합니다.

    2. 여러 인스턴스가 있고 그 중 일부만 진단을 전송하는 경우 XML 파일을 비교하여 모두 올바르게 구성되었는지 확인합니다.

    3. 배포 후 진단을 구성한 경우 진단이 임의로 작동 중지되면 이는 역할이 재활용되거나 인스턴스가 다시 시작되었기 때문일 수 있습니다. 인스턴스가 다시 시작되면 사용자 지정 배포 후 설정이 손실되며 코드에 구성된 진단이 사용됩니다. .wadcfg 파일을 사용할 경우의 주요 이점 중 하나는 역할 재활용 시 이 구성을 덮어쓰지 않는다는 점입니다.

  2. 진단 저장소 계정의 WADDiagnosticInfrastructureLogsTable 테이블에서 로그를 확인합니다. DeploymentId를 기준으로 필터링할 수 있습니다(예: DeploymentId eq 'bd9e149f76e8413aba8865c77326e449'). 진단이 전송되지 않는 이유를 나타낼 수 있는 예외 또는 오류 메시지를 확인합니다.

  3. Diagnostics.Trace 정보가 수집되지 않는 경우 DiagnosticMonitorTraceListener가 web.config 또는 app.config에 구성되어 있는지 확인합니다. 클라우드 프로젝트에서 기본적으로 구성되지만 간혹 변경될 수 있으며 이로 인해 진단에서 추적 문을 수집하지 않는 경우가 있습니다.

  4. 일반적인 문제는 진단 저장소를 제대로 쿼리하지 않아 결과가 반환되지 않으며, 진단이 캡처되지 않는 것으로 간주된다는 것입니다. DeploymentID로 필터링하여 진단 테이블을 쿼리하고 진단이 올바르게 전송되는지 확인합니다. 일반적인 쿼리 실수에는 DeploymentID로 필터링하지 않은 경우, 연속 토큰을 따르지 않는 경우 등이 있습니다.

  5. 배포 후 인스턴스가 시작되지 않으면 ServiceConfiguration.cscfg 파일에 구성된 저장소 계정이 "UseDevelopmentStorage=true"로 설정되어 있지 않은지 확인합니다. 2011년 8월 이후 버전의 Windows Azure Tools for Visual Studio 2011을 사용하는 경우 경고가 표시됩니다. 그렇지 않으면 인스턴스에서 RDP를 실행하여 C:\Config 폴더에 있는 역할 구성 파일을 확인해야 합니다.

  6. 인스턴스에 연결한 경우 DiagnosticsAgent.exe 및 MonAgentHost.exe가 실행 중인지도 확인해야 합니다. 실행 중이면 WinDBG를 설치하고 연결하여 예외가 throw되는지 확인할 수 있습니다.

  7. 또한 진단이 로컬로 작성되는지 확인할 수 있습니다.

    • 개발 환경의 .tsf 파일은 다음 위치에 작성됩니다.

      c:\Users\<username>\AppData\Local\dftmp\Resources\<deploymentID>\directory\DiagnosticStore\Monitor\Tables

    • 실행 중인 인스턴스의 경우 파일은 다음 위치에 작성됩니다.

      c:\Resources\<deploymentID>.<role>\directory\DiagnosticStore\Monitor\Tables

    현재 이러한 파일을 읽으려면 지원 케이스를 만들어 Microsoft로 보내야 합니다.

  8. 여러 인스턴스가 있고 그 중 일부만 진단을 올바르게 전송하지 않는 경우 관리 포털에서 역할을 이미지로 다시 설치합니다. 그러나 이 방법을 사용하면 문제가 발생한 근본 원인을 확인하지 못하게 되므로 최후의 수단으로 사용해야 합니다.

코드 계측

가장 중요한 진단 데이터는 개발자가 자신의 코드에 추가하는 추적 메시지일 것입니다. 시스템 데이터는 예외를 표시하거나 오류 메시지를 기록할 수 있습니다. 종속 시스템에 대한 특정 호출을 추적할 수 있습니다. 최상의 방법은 실패할 수 있는 종속 시스템(예: 타사 인증 서비스)을 호출할 때 추적 메시지를 추가하는 것입니다.

ETW 프레임워크에서는 TraceEventType을 각 이벤트에 연결합니다.

 

TraceEventType 수준 의미

중요

1

0x0001

심각한 오류 또는 응용 프로그램 크래시

오류

2

0x0002

복구할 수 없는 오류

경고

3

0x0004

중요하지 않은 문제 - 보다 심각한 문제의 발생 가능성을 나타낼 수 있음

정보

4

0x0008

정보 메시지

자세한 정보 표시

5

0x0010

디버깅 추적(예: 자세한 실행 흐름 정보, 매개 변수 등)

Start

0x0100

논리 연산 시작

Stop

0x0200

논리 연산 중지

코드 계측 방법을 계획한 후에는 System.Diagnostics 네임스페이스를 추가한 다음 추적 메시지를 추가하기만 하면 됩니다. C#의 경우 다음과 같습니다.

Trace.WriteLine("LoggingWorkerRole entry point called", "Information");

Windows Azure가 전체 IIS(SDK 1.3)에서 실행을 시작했으므로 웹 응용 프로그램 코드는 RoleEntryPoint와 다른 응용 프로그램 도메인 및 프로세스에서 실행됩니다. 이는 Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener 아래의 Web.Config에 추가 추적 수신기를 추가하지 않는 한 계산 에뮬레이터에 추가 메시지가 표시되지 않음을 의미합니다.

<add type="Microsoft.ServiceHosting.Tools.DevelopmentFabric.Runtime.DevelopmentFabricTraceListener, Microsoft.ServiceHosting.Tools.DevelopmentFabric.Runtime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="DevFabricListener">
    <filter type=""/>
</add>

보다 복잡한 응용 프로그램의 경우 EventId 방법을 사용하면 로그를 보다 효율적으로 필터링하여 보다 신속하게 문제를 해결할 수 있습니다. C# WriteLine을 사용하는 EventId는 항상 0입니다. EventId를 지정하려면 TraceEvent 메서드(traceType은 위 표에서 확인할 수 있음)를 사용해야 합니다.

Trace.TraceEvent(traceType, eventId, message);

추적 메시지는 WADLogsTable 테이블에 유지됩니다. Windows Azure는 자동으로 타임스탬프, 틱 수(자세한 타이밍에 100나노초 단위 제공) 및 배포, 역할, 역할 인스턴스에 대한 정보를 각각의 로깅된 이벤트에 연결합니다. 이를 통해 로그 범위를 특정 인스턴스로 좁힐 수 있습니다. 메시지는 다음과 같이 XML 형식으로 저장됩니다.


<Properties>
 <EventTickCount>634402131502204503</EventTickCount>
 <DeploymentId>deployment(28)</DeploymentId>
 <Role>WebRole1</Role>
 <RoleInstance>deployment(28).Sample.WebRole1.0</RoleInstance>
 <Level>3</Level>
 <EventId>20</EventId>
 <Pid>10796</Pid>
 <Tid>7172</Tid>
 <Message>trace message; TraceSource 'Data' event</Message> 
</Properties>

수준은 TraceEventType에 해당합니다. 위 표에서 수준 3은 경고에 해당하는 것을 알 수 있습니다. TraceEventType을 지정하지 않거나 Trace.WriteLine을 사용하는 경우에는 수준이 5(자세한 정보 표시)로 설정됩니다.

대부분 표준 로깅에 충분한 시간입니다. 보다 자세한 로깅 유형의 경우 사용자 지정 추적 수신기를 만들 수 있습니다.

Azure 테이블 쿼리는 LINQ 쿼리로 WADLogsTable을 쿼리할 수 있는 웹 역할의 CodePlex 프로젝트입니다.

데이터 보기

진단을 수집하는 이유는 문제가 발생한 경우 즉시 사용할 수 있도록 하기 위한 것입니다. 따라서 데이터 백업이 올바르게 작동하는지 확인할 때와 동일한 방법으로, 문제가 발생하기 전에 모든 요소가 작동하는지 확인해야 합니다. 이는 응용 프로그램을 테스트하는 동안 진단 데이터를 확인한 다음 정기적으로 여전히 작동하는지 확인해야 함을 의미합니다. 또한 비정상적인 성능이 발생한 경우를 알 수 있도록 기준선을 구축해야 함을 의미합니다.

모든 Windows Azure 진단 데이터는 WAD가 시작되면 지정한 저장소 계정에 저장됩니다. Visual Studio 서버 탐색기 또는 여러 storage explorers 중 하나를 사용하여 이 데이터를 시각화할 수 있습니다.

wad-control-container Blob에는 진단 인프라 자체에 대한 로깅이 포함됩니다. 여기에서는 지정된 인스턴스에서 데이터가 전송되는지 확인할 수 있습니다. Blob의 ID 형식은 다음과 같습니다.

0aef2b51ad1d49ef915dd41d3ca01f24/WorkerRole1/WorkerRole1_IN_0

이 ID는 다음 세 부분으로 구분됩니다.

  1. 긴 숫자는 배포 ID - 0aef2b51ad1d49ef915dd41d3ca01f24

  2. 역할 이름 - WorkerRole1

  3. 인스턴스 이름 - WorkerRole1_IN_0

여러 인스턴스가 있는 경우 0부터 시작되는 접미사가 증분됩니다. 예를 들어 WorkerRole1_IN_1은 두 번째 인스턴스입니다.

아래 표에는 각 로그가 작성되는 위치가 나와 있습니다.

 

로그 유형 Windows Azure 저장소 형식 참고

사용자의 코드에서 생성된 Windows Azure 로그

테이블

추적 수신기를 web.config 또는 app.config 파일에 추가해야 합니다. 이러한 파일은 WADLogsTable에 저장됩니다.

IIS 7.0 로그

Blob

웹 역할에만 적용됩니다. wad-iis-logfiles\<deployment ID>\<web role name>\<role instance>\W3SVC1 경로 아래의 Blob 컨테이너에 저장됩니다.

Windows 진단 인프라 로그

테이블

진단 서비스 자체에 대한 정보입니다. WADDiagnosticInfrastructureLogs 테이블에 저장됩니다.

실패한 요청 로그

Blob

웹 역할에만 적용됩니다. web.config의 system.WebServer 설정에서 추적 옵션을 설정하여 사용합니다. wad-iis-failedreqlogfiles\<deployment ID>\<web role name>\<role instance>\W3SVC1 경로 아래의 Blob 컨테이너에 저장됩니다.

Windows 이벤트 로그

테이블

초기 구성을 설정할 때 DiagnosticMonitor Configuration.WindowsEventLog를 변경하여 사용합니다. WADWindowsEventLogs 테이블에 저장됩니다.

성능 카운터

테이블

DiagnosticMonitor 구성을 변경하여 사용합니다. 성능 카운터이며, WADPerformanceCounters 테이블에 저장됩니다. 예제 코드 작업 역할에서 성능 카운터를 설정합니다.

크래시 덤프

Blob

CrashDumps.EnableCollection을 호출하여 사용합니다. wad-crash-dumps 경로 아래의 Blob 컨테이너에 저장됩니다. ASP.NET에서 대부분의 예외를 처리하기 때문에 크래시 덤프는 작업자 역할에서만 유용합니다.

사용자 지정 오류 로그

Blob

이 로그의 사용 방법에 대한 유용한 예제는 Neil Mackenzie의 블로그를 참조하세요.

크래시 덤프 데이터는 영구 저장소로 전송되면 wad-crash-dumps Blob 컨테이너에 저장됩니다. IIS 로그는 wad-iis-logfiles Blob 컨테이너로 전송됩니다. 실패한 요청은 wad-iis-failedreqlogfiles Blob 컨테이너에 저장됩니다.

이벤트 로그는 영구 저장소의 WADWindowsEventLogs 테이블로 전송됩니다. 성능 카운터는 지정된 간격으로 WADPerformanceCounters 테이블로 전송됩니다. WADDiagnosticInfrastructureLogs는 진단 인프라에 대한 로그를 포함합니다. 추적 수신기는 WADLogsTable 테이블에서 확인할 수 있습니다.

진단 데이터를 볼 수 있는 또 다른 도구에는 LINQPad가 있습니다(Jason Haley의 AzureLogsWithLINQPad 예제 사용).

진단 관리

이 모든 로그 파일을 Windows Azure 저장소에 유지하면 시간과 비용이 듭니다. 가장 좋은 방법은 특정 문제를 해결하는 데 필요할 때 "적시에" 추적하는 것입니다. 진단 설정을 동적으로 변경할 때는 일부 설정이 항상 필요한 경우 수동으로 원래 설정으로 되돌리거나 원래 설정을 변경해야 한다는 점에 유의해야 합니다. 이 단계는 .wadcfg 파일을 사용하지 않는 경우, 인스턴스가 다시 시작되면 새 설정이 코드에 구성된 진단 설정으로 대체되기 때문에 특히 중요합니다.

Windows Azure PowerShell Cmdlet을 사용하여 진단을 비롯한 실행 중인 Windows Azure 서비스의 많은 부분을 관리할 수 있습니다. 이러한 cmdlet은 로컬 시스템에서 실행되며, Windows Azure 관리 및 진단 API를 사용하여 인터넷을 통해 서비스에 연결한 후 정보를 제공하고 매개 변수를 조정합니다.

Windows PowerShell은 Windows 7과 함께 설치되며, Windows Azure 관리 도구(MMC)와 함께 설치되는 서비스 관리 cmdlet에서 진화한 버전입니다. 보다 유용한 cmdlet의 예를 들면 다음과 같습니다.

  • Get-DiagnosticConfiguration - 지정된 버퍼 이름(Logs, Directories, PerformanceCounters, WindowsEventLogs 또는 DiagnosticInfrastructureLogs)에 대한 버퍼 구성을 가져옵니다.

  • 역할에 대한 구성을 변경하려면 Set-DiagnosticConfiguration cmdlet을 사용합니다.

  • Start-OnDemandTransfer - 지정된 데이터 버퍼에 대한 요청 시 전송을 시작합니다. 데이터를 Windows Azure 저장소(테이블 또는 Blob 저장소)로 이동합니다.

David Aiken의 블로그에 일부 로그 파일(IIS 로그 파일 및 wad-control-container XML 파일)을 정리하는 스크립트가 있습니다. 각 컨테이너에 대해 Clear-Container cmdlet을 호출해야 합니다. 또한 예약된 전송이 삭제와 겹쳐지지 않도록 해야 하며, 테이블에 저장되는 로그(성능 카운터, 이벤트 로그 등)에 대한 전략을 수립해야 합니다. 일부 사용자는 Windows Azure 저장소에서 모든 데이터를 다운로드하여 SQL Server 데이터베이스에 저장합니다. 이렇게 하면 더 이상 저장소 요금이 청구되지 않으며 데이터에서 더 복잡한 쿼리를 실행할 수 있습니다.

Windows Azure 진단 리소스를 이해하면 개발자는 아래에 설명된 디자인 모범 사례를 사용하여 지속 가능한 응용 프로그램을 빌드할 수 있습니다.

응용 프로그램의 상태를 측정하여 기준선과 비교해야 합니다. 홈 페이지가 표시된다고 응용 프로그램이 정상 상태인 것은 아닙니다. 완벽한 상태 기준선을 만들려면 비즈니스 논리의 상태 및 성능도 이해해야 합니다.

그런 다음 상태가 롤업되는 방식을 이해해야 합니다. 정상 상태의 첫 번째 원칙은 Windows Azure 청구서를 정해진 기간 내에 결제하는 것입니다. 미납된 구독이 있으면 결과가 점진적으로 나빠지며, 결국 응용 프로그램이 삭제됩니다.

Windows Azure 호스팅된 서비스에서는 각 구독에 대해 응용 프로그램의 상태에 영향을 줄 수 있는 네 가지 수준을 적용합니다.

Windows Azure - 상태 수준

예를 들어 인스턴스가 하드웨어 오류로 인해 실패하거나 소프트웨어 업데이트로 인해 다시 시작될 수 있습니다. 이 경우 구성된 인스턴스가 하나밖에 없는 경우가 아니면 역할이 실패하지 않습니다. 마찬가지로 각 호스팅된 서비스는 특정 지역(예: 미국 중남부)에 있습니다. 이 중요한 정보에 따라 응용 프로그램이 서비스 중단 이벤트(가동 중단이라고 함)의 영향을 받는지 여부가 결정됩니다. 응용 프로그램 디자인에 중복성이 구축되어 있지 않으면 하위 수준의 오류로 인해 호스팅된 서비스가 실패할 수 있습니다.

대부분의 Windows Azure 응용 프로그램에는 위 다이어그램보다 복잡한 아키텍처가 필요합니다. 응용 프로그램은 다음과 같은 모습일 수 있습니다.

Windows Azure - 아키텍처 예제

분산된 특성은 가능한 여러 실패 지점을 유발합니다. 이러한 중요 경로를 문서화하면 보다 효율적으로 문제를 해결할 수 있습니다. 예를 들어 위 다이어그램의 경우 액세스 제어에서 오류가 발생했는지 테스트하려면 어떻게 해야 할까요?

응용 프로그램에서 발생한 문제의 원인을 이해하려면 응용 프로그램의 상태를 모니터링하고 기록해야 합니다. 일반적으로 응용 프로그램에 대해 다음 네 가지 범주의 정보를 기록할 수 있습니다.

  • 프로그래밍: 예외, 키 변수 값, 응용 프로그램을 디버깅하는 데 필요한 모든 정보

  • 비즈니스 프로세스: 보안에 필요한 감사, 변경 내용 추적, 규정 준수

  • 시스템 안정성: 성능, 확장성, 처리량, 대기 시간

  • 비즈니스 가정 검증: 응용 프로그램이 의도된 방식으로 사용되는지 여부

인간의 가장 기본적인 속성 중 하나는 위치에 처했을 때 그대로 멈춰버린다는 것입니다. 교육과 실습을 통해 이러한 속성을 극복할 수 있습니다. 화재 대피 훈련을 실시하거나 일부 항공사에서 충돌 안전 과정을 권장하는 것도 이러한 이유에서입니다. 대부분의 대기업은 재해 복구 계획에 많은 예산을 투입합니다. 관련 모범 사례는 Microsoft IT의 데이터 센터 내 재해 복구 구현을 참조하세요.

문제가 발생한 경우 신속하게 문제를 해결하는 기술만 강조하는 경향이 있습니다. 응용 프로그램이 문제 해결에 용이하도록 빌드되었는지를 알면 문제가 발생한 경우 부담감을 더는 동시에 사이트를 가동하는 데 소요되는 시간을 줄일 수 있습니다. 비용 효율성 분석에서는 시스템에 구축할 내결함성의 수준을 결정합니다. 예를 들어 가동 중지 시간을 줄이기 위해 트래픽 관리자가 제공하는 핫 백업을 수행하는 데 추가 비용을 들일 가치가 있는지의 여부를 결정합니다.

Windows Azure 트래픽 관리자를 사용하면 동일한 데이터 센터에 배포되든, 전 세계 여러 데이터 센터에 배포되든 상관없이 Windows Azure 호스팅된 서비스로 들어오는 트래픽을 관리 및 배포할 수 있습니다. Windows Azure 트래픽 관리자는 기본 서비스의 작동이 중지된 경우 목록의 사용 가능한 다음 서비스로 트래픽이 전송되도록 장애 조치(failover) 서비스를 구성할 수 있는 기능을 제공합니다. Akamai 또는 Limelight와 같은 타사 소프트웨어에서도 부하 분산 솔루션을 제공합니다.

다음은 신속한 문제 해결을 위한 5단계 계획입니다.

계획의 첫 번째 단계에서는 문제가 발생하는 즉시 문제를 파악하는 것입니다. 문제를 빨리 알수록 재해 계획 구현을 보다 빠르게 시작할 수 있습니다. 모니터링 중요한 이유가 바로 이 때문입니다.

두 번째 단계에서는 문제의 원인을 파악해야 합니다. 즉, Windows Azure 플랫폼이 원인인지, 응용 프로그램이 원인인지 알아야 합니다. 먼저 Windows Azure 서비스 대시보드를 확인해야 합니다. 이 사이트에서는 응용 프로그램에서 사용하는 모든 서비스와 각 서비스가 배포된 데이터 센터를 알아야 합니다. 응용 프로그램에 영향을 주는 서비스 성능 저하를 하나만 선택합니다.

Windows Azure 플랫폼 서비스 이벤트를 모니터링하는 한 가지 방법은 응용 프로그램의 모든 RSS 피드를 구독하는 것입니다. 예를 들어 응용 프로그램이 미국 중북부에서 호스팅되는 경우 이 RSS 피드를 구독합니다.

Windows Azure 저장소에서는 장애 도메인(랙, 네트워크 스위치, 전원)을 사용하여 하드웨어 오류의 영향을 제한합니다. 일반적으로 Windows Azure 저장소에 대해 잘못 알고 있는 한 가지는 단일 위치(예: 미국 중남부) 외부에 있는 데이터의 복제본이 하나의 복제본으로 자동으로 장애 조치(failover)된다는 것입니다. 주어진 위치에서 저장소에 문제가 발생한 경우에는 데이터 액세스가 영향을 받습니다. 이 저장소 팀 블로그에서는 새로운 지역에서 복제 기능에 대한 자세한 정보를 제공합니다.

세 번째 단계에서는 문제를 지역화해야 합니다. 여러 Windows Azure 서비스를 사용하는 복잡한 응용 프로그램에서는 이 단계가 가장 까다로운 단계일 것입니다. 상태 비저장 서비스를 빌드하면 응용 프로그램의 여러 부분을 격리시킬 수 있습니다. 모든 종속 서비스가 정상적으로 실행되면 계산 서비스의 상태를 확인해야 합니다. 이 작업은 관리 포털에서 호스팅된 서비스, 저장소 계정 및 CDN 섹션을 열고 배포를 선택하여 수행할 수 있습니다. 속성 창에 다음과 같은 내용이 표시됩니다.

Windows Azure - 배포 속성

이 예제에서는 마지막 작업이 완료된 시간과 마지막으로 새로 고친 시간 사이의 시간 간격으로 계산할 때 지난 8일 동안 배포가 정상적으로 실행되었음을 알 수 있습니다. 반면, 배포가 최근에 중단되거나 다시 시작된 경우 이 창에서 확인을 시작할 위치를 파악할 수 있습니다. 지정된 데이터 센터의 모든 배포에 영향을 주는 서비스 이벤트를 나타내는 경우에는 (866) 676-6546으로 Microsoft에 즉시 연락해야 합니다.

네 번째 단계에서는 로그 파일 및 이벤트 로그 확인, 디버거 연결, 도구(예: Procmon 또는 네트워크 모니터) 사용 등 표준 문제 해결 단계를 수행하여 문제의 일부 원인을 찾을 수 있는지 확인해야 합니다. 먼저 응용 프로그램 이벤트 로그에서 Windows Azure 호스팅된 서비스 배포를 확인합니다. 응용 프로그램에서 예외가 throw되지 않았는지 확인해야 합니다. 현재 모든 지원이 무료이므로 이는 불필요해 보일 수도 있습니다. 하지만 전체 응용 프로그램 범위에 대한 지식이 없는 숙련된 Microsoft 지원 엔지니어보다 사용자가 더 빨리 문제를 찾아서 해결할 수 있는 경우가 많은 것이 사실입니다. "사이트 가동"이 긴급한 경우에는 먼저 최상의 대안을 찾아야 합니다.

다섯 번째 단계에서는 Microsoft 지원에 문의해야 합니다. 신속한 문제 해결을 위해 구독의 계정 소유자와 연관된 페더레이션 ID(Windows Live ID)를 제공해야 합니다. 이는 구독을 관리하기 위해 Microsoft Online Services 고객 포털에 로그인하는 데 사용되는 전자 메일 주소입니다. 또한 여러 로그 파일에서 발견된 문제 및 오류의 원인에 대한 분석 결과를 제공해야 합니다. Microsoft 지원 엔지니어는 사용자와 정확히 동일하게 관리 포털을 볼 수 있도록 자신을 구독에 공동 관리자로 추가하도록 요청할 수 있습니다.

성능은 아름다움과 같이 보는 사람마다 다를 수 있습니다. 성능이 허용되지 않는 임계값은 무엇일까요? 페이지가 시간 초과되는 것은 언제일까요? 최대 부하 시간을 수량화한 경우에도 일부 고객에게 페이지가 로드되지 않을 수 있습니다. DNS 경로 및 네트워크 안정성은 페이지 로드 시간을 결정하는 두 가지 주요 요소입니다. 예를 들어 테네시 주 멤피스에 있는 고객이 텍사스 주 샌안토니오로 ISP를 보낸 경우 이 트래픽은 먼저 시카고로 전송됩니다. Microsoft Online Services에서는 응답 시간, 대역폭 및 전반적인 연결 품질을 측정하는 성능 도구 테스트를 제공합니다. 여러 Microsoft 데이터 센터 간의 대기 시간을 확인하고 싶은 경우 Matthew Rosoff의 Azure Statistics를 사용할 수 있습니다.

성능에 대한 자세한 논의는 이 문서의 범위를 벗어납니다. Windows Azure에서 개발하는 모범 사례는 TechNet 문서 SQL Azure 성능 및 탄력성 가이드를 참조하세요. 성능 문제 해결은 기준선을 정하는 것에서 시작됩니다. 그렇기 때문에 장기간에 걸쳐 성능 데이터를 수집해야 합니다. 기준선이 있으면 추세와 비정상 상태를 볼 수 있습니다.

Windows Azure 플랫폼에서는 여러 서비스의 가용성/연결 수준을 정의하는 SLA(서비스 수준 계약)을 제공합니다. SLA란 무엇일까요? 어떤 ISP에서 패키지에 SLA가 없어 연결을 업무용으로 사용할 수 없다는 이야기를 한 적이 있습니다. 안정성은 고객의 기본 네트워크 연결에 종속되고 실제로 보는 사람마다 다르다는 점에서 성능과 약간 비슷합니다. 위 링크는 네트워크 연결 성능을 이해하는 데 도움이 될 수 있습니다.

한 가지 일반적인 실수는 Windows Azure 플랫폼 SLA가 응용 프로그램에 대한 동일한 SLA를 보장하는 것으로 생각하는 것입니다. 우선, 일부 사용자는 다음 두 번째 문장을 읽지 않기 때문입니다.

계산의 경우 둘 이상의 역할 인스턴스를 서로 다른 장애 및 업그레이드 도메인에 배포할 경우 인터넷 연결 역할의 외부 연결 성공률은 99.95%가 될 것임을 보장합니다.

이 문장에는 "역할당 둘 이상의 역할 인스턴스"에 있는 두 단어의 추가 한정자가 없습니다. 즉, 웹 역할과 작업자 역할이 있는 경우 역할당 하나의 인스턴스가 있으면 호스트 OS 업데이트 또는 일부 유형의 시스템 복구 시 응용 프로그램을 사용할 수 없습니다. Windows Azure 계산에서는 장애 도메인을 사용하여 SLA를 준수하는지 확인합니다.

또 다른 오해는 특정 OS 버전을 선택할 경우 OS 업데이트로 인한 중단이 없다는 것입니다. 인스턴스에서 실행되는 게스트 OS에는 맞지만, 데이터 센터의 실제 컴퓨터에서 실행되는 호스트 OS에는 맞지 않습니다.

안정성을 극대화하려면 Window Azure 진단 데이터를 사용하여 내부적으로 모니터링하는 한편, Apica의 AzureCheck, Compuware의 Gomez 또는 Pingdom을 사용하여 외부적으로 모니터링해야 합니다. 또한 최신 보안 패치를 적용했으며 코드 변경 확인 계획을 수립했는지 확인해야 합니다.

Visual Studio를 사용하여 새 응용 프로그램을 만들 때 기본 동작은 ServiceConfiguration.cscfg 파일에서 다음과 같이 게스트 OS 버전을 설정하는 것입니다.

osFamily="1" osVersion="*"

PaaS의 주요 이점 중 하나인 자동 업데이트를 받을 수 있는 이점은 있지만 최신 OS를 사용하지 않으므로 최적 설정은 아닙니다. 최신 OS 버전(Windows Server 2008 R2)을 사용하려면 설정이 다음과 같아야 합니다.

osFamily="2" osVersion="*"

그러나 많은 고객이 게스트 OS 업데이트를 피하면 가동 시간을 늘릴 수 있다는 바람에서 특정 버전의 OS를 잠그는 경우가 많습니다. 이는 준비 단계에서 각 업데이트를 시스템적으로 테스트하고 프로덕션에서 실행되는 중요 업무용 응용 프로그램에 대한 VIP 교체를 예약하는 대기업 고객에게만 타당한 전략입니다. 각 게스트 OS 업데이트를 테스트하지 않는 모든 사용자는 자동 업데이트를 구성하지 않을 경우 Windows Azure 응용 프로그램이 위험에 상황에 놓이게 됩니다.

특히 비상 시, 서비스를 업데이트해야 할 때 어떤 계획이 있나요? 종종 무시되는 이 단계는 사이트 가동 중지와 사소한 준비 문제 해결 간의 차이점일 수 있습니다. Windows Azure 응용 프로그램에 대한 초기 계획 및 릴리스에 대부분의 시간과 노력이 필요하지만, 변경 해결의 기준이 패키지 제품보다 낮으므로 업데이트에 광범위한 테스트가 필요하지 않습니다. 재발을 신속하게 해결할 수 있습니다. 반면, 심각한 오류를 쉽게 일으킬 수도 있습니다.

프로덕션 응용 프로그램을 변경할 때마다 프로덕션에 최종 배포하기 전에 테스트해야 합니다. 남은 시간에는 오류의 가능한 결과를 살펴보는 것이 좋습니다. 자세한 내용은 Windows Azure 서비스 업데이트 개요를 참조하세요.

이 문서의 항목을 검토해 주셔서 감사합니다. 의견이 있으면 보내 주시기 바랍니다. 서비스 가동 중지 비용은 진단 데이터 수집 비용을 기준으로 가중치가 적용되어야 합니다. 프로덕션으로 전환하기 전에 이러한 비용을 계산해야 합니다. 안정적인 Windows Azure 응용 프로그램을 개발하는 데 필요한 작업은 새롭거나 혁신적이거나 기술적인 어려운 일이 아닙니다. 디자이너와 개발자가 응용 프로그램에서 발생할 수 있는 잠재적 문제를 고려하고 이 문서에 설명된 모범 사례를 적용하기만 하면 됩니다.

  • Christian, Tom, "Help with Windows Azure role stuck in Initializing/Busy/Stopped state", 블로그, 2011년 2월 25일

  • Cross, Andy, "Tracing to Azure Compute Emulator SDK V1.3", 블로그, 2011년 1월 22일

  • Haley, Jason, "How To: Query Azure Log Tables with LINQPad", 블로그, 2010년 1월 28일 15:09

  • Hardin, David, "Configuring WAD via the diagnostics.wadcfg Config File", 블로그, 2011년 3월 29일

  • Kelly, Mike, "Take Control of Logging and Tracing in Windows Azure", MSDN Magazine, 2010년 6월

  • Mackenzie, Neil, "Custom Diagnostics in Windows Azure", 블로그, 2009년 12월 8일

  • Makogon, David, "Azure Tip of the Day: Separate Diagnostic Storage Account", 블로그, 2010년 8월 15일

  • Marx, Steve, "Capturing Filtered Windows Events with Windows Azure Diagnostics", 블로그, 2010년 4월 21일

  • Mladenov, Toddy, "Collecting Event Logs in Windows Azure", 블로그, 2010년 5월 2일

  • Myers, Walter, "Setting Up Performance Counters In Your Azure Web and Worker Roles", 블로그, 2011년 1월 31일

  • Nakashima, Jim, "Using IntelliTrace to debug Windows Azure Cloud Services", 블로그, 2010년 6월 7일

  • O’Neil, Jim, "500 and Other Errors in Azure Deployments Blog", 블로그, 2011년 4월 11일 오전 4:47

  • Stiefel, Michael, "Why Did My Azure Application Crash? Using the Windows Azure Diagnostics API to Find Code Problems", 블로그, 2011년 9월 8일

  • Washam, Michael, "Managing Log Files with Windows Azure PowerShell Cmdlets 2.0", 블로그, 2011년 9월 20일

  • Williamson, Kevin, " Windows Azure Role Architecture", 블로그, 2011년 5월 5일

  • Windows Azure 관리 포털 http://manage.windowsazure.com.

  • Windows Azure 플랫폼 교육 과정 - 연습 3 - Windows Azure에서 응용 프로그램 모니터링

  • Windows Azure 포털 http://www.microsoft.com/windowsazure/

 

패브릭

가상 컴퓨터 내에서 역할 실행 환경을 제공하는 컴퓨터의 논리적 클러스터입니다.

FREB

실패한 요청 추적(이전의 실패한 요청 버퍼링)

관리 포털

Windows Azure 관리 포털은 Windows Azure 서비스를 관리, 배포 및 모니터링하는 관리자 포털입니다. 관리 포털에는 http://manage.windowsazure.com에서 액세스할 수 있습니다.

REST

REpresentational State Transfer의 약어로서, 웹 서비스를 리소스로 표시하고 해당 URL로 식별할 수 있는 상태 비저장 클라이언트-서버 아키텍처를 사용하는 소프트웨어 디자인입니다.

SLA

서비스 수준 계약

가상 컴퓨터

실제 컴퓨터의 격리된 파티션에서 실행되는 컴퓨터의 소프트웨어 에뮬레이션입니다.

WAD

Windows Azure 진단

웹 역할

웹 역할은 IIS 7 및 ASP.NET에서 지원하는 대로 웹 응용 프로그램 프로그래밍에 대해 사용자 지정된 역할입니다.

작업자 역할

작업자 역할은 일반적인 개발에 유용한 역할이며, 웹 역할에 대한 백그라운드 처리를 수행할 수 있습니다.

이 부록에서는 Windows Azure 진단을 구성하는 데 필요한 코드에 중점을 둡니다. 역할 인스턴스 시작을 사용자 지정할 수 있도록 RoleEntryPoint.OnStart 메서드가 호출됩니다. 사용자 고유의 OnStart 구현을 제공하여 역할에 대한 WAD를 구성하는 데 필요한 코드를 실행할 수 있습니다.

public override bool OnStart()
{
    string sSource = "WaAppAgent";
    string sEvent = null;

    try
    {
        DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();

        // Set an overall quota of 8GB.
        config.OverallQuotaInMB = 8192;

        // Set the sub-quotas and make sure it is less than the OverallQuotaInMB set above
        config.Logs.BufferQuotaInMB = 1024;
        config.Directories.BufferQuotaInMB = 0; // Use the rest of the storage here
        config.WindowsEventLog.BufferQuotaInMB = 1024;
        config.PerformanceCounters.BufferQuotaInMB = 1024;
        config.DiagnosticInfrastructureLogs.BufferQuotaInMB = 1024;

        // Get ScheduledTransferPeriod setting from ServiceConfiguration.cscfg and then set it 
        var myScheduledTransferPeriod = RoleEnvironment.GetConfigurationSettingValue("ScheduledTransferPeriod");
        TimeSpan myTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(myScheduledTransferPeriod));
        config.Logs.ScheduledTransferPeriod = myTimeSpan;
        config.Directories.ScheduledTransferPeriod = myTimeSpan;
        config.WindowsEventLog.ScheduledTransferPeriod = myTimeSpan;
        config.PerformanceCounters.ScheduledTransferPeriod = myTimeSpan;
        config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = myTimeSpan;

        // Get LogLevelFilter setting from ServiceConfiguration.cscfg and then set it
        var LogLevelFilter = RoleEnvironment.GetConfigurationSettingValue("LogLevelFilter");
        var myLogLevel = LogLevel.Undefined;
        switch (LogLevelFilter)
        {
            case ("Information"):
                myLogLevel = LogLevel.Information;
                break;
            case ("Verbose"):
                myLogLevel = LogLevel.Verbose;
                break;
            case ("Warning"):
                myLogLevel = LogLevel.Warning;
                break;
            case ("Critical"):
                myLogLevel = LogLevel.Critical;
                break;
            case ("Error"):
                myLogLevel = LogLevel.Error;
                break;
            default:
                break;
        } 

        // Filter what will be sent to persistent storage.
        config.Logs.ScheduledTransferLogLevelFilter = myLogLevel;
        config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = myLogLevel;
        config.WindowsEventLog.ScheduledTransferLogLevelFilter = myLogLevel;

        // Add in configuration settings for Windows Event logs
        config.WindowsEventLog.DataSources.Add("Application!*");
        config.WindowsEventLog.DataSources.Add("System!*");

        // Add a custom directory transfer
        DirectoryConfiguration directoryConfiguration = new DirectoryConfiguration();
        directoryConfiguration.Container = "wad-custom-logs";
        directoryConfiguration.DirectoryQuotaInMB = 0;
        directoryConfiguration.Path = @"c:\logs";
        config.Directories.DataSources.Add(directoryConfiguration);
 

        // Enable full crash dump collection.
        CrashDumps.EnableCollection(true);

        // Use 30 seconds for the perf counter sample rate.
        TimeSpan perfSampleRate = TimeSpan.FromSeconds(30D);

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Memory\Available Bytes",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Processor(_Total)\% Processor Time",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Process(w3wp)\% Processor Time",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Process(w3wp)\Private Bytes",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Process(w3wp)\Thread Count",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\.NET CLR Interop(_Global_)\# of marshalling",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
             CounterSpecifier = @"\.NET CLR Jit(_Global_)\% Time in Jit",
             SampleRate = perfSampleRate
         });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\.NET CLR Loading(_Global_)\% Time Loading",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\.NET CLR LocksAndThreads(_Global_)\Contention Rate / sec",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\.NET CLR Memory(_Global_)\# Bytes in all Heaps",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\.NET CLR Networking(_Global_)\Connections Established",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\.NET CLR Remoting(_Global_)\Remote Calls/sec",
            SampleRate = perfSampleRate
        });

        // Apply the updated configuration to the diagnostic monitor.
        // The first parameter is for the connection string configuration setting.
        DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);

        sEvent = "Management OnStart called diagnostics";
        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType. Information, 0);
    }
    catch (Exception e)
    {
        sEvent = "Management OnStart Event: " + e.Message;
        EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Error, 0);
    }

    return base.OnStart();
}

이 부록에서는 작업자 역할에서 Windows Azure 진단을 구성하는 데 필요한 코드에 중점을 둡니다.

public override bool OnStart()
{
    // Set the maximum number of concurrent connections 
    ServicePointManager.DefaultConnectionLimit = 12;
    string sSource = "WaAppAgent";
    string sEvent = "WorkerRole OnStart Event: ";

    try
    {
        // For information on handling configuration changes
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

        DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();

        // Set an overall quota of 8GB.
        config.OverallQuotaInMB = 8192;
        // Set the sub-quotas and make sure it is less than the OverallQuotaInMB set above
        config.Logs.BufferQuotaInMB = 1024;
        config.Directories.BufferQuotaInMB = 0; // Use the rest of the storage here
        config.WindowsEventLog.BufferQuotaInMB = 1024;
        config.PerformanceCounters.BufferQuotaInMB = 1024;
        config.DiagnosticInfrastructureLogs.BufferQuotaInMB = 1024;

        // Get ScheduledTransferPeriod setting from ServiceConfiguration.cscfg and then set it 
        var myScheduledTransferPeriod = RoleEnvironment.GetConfigurationSettingValue("ScheduledTransferPeriod");
        TimeSpan myTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(myScheduledTransferPeriod));
        config.Logs.ScheduledTransferPeriod = myTimeSpan;
        config.Directories.ScheduledTransferPeriod = myTimeSpan;
        config.WindowsEventLog.ScheduledTransferPeriod = myTimeSpan;
        config.PerformanceCounters.ScheduledTransferPeriod = myTimeSpan;
        config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = myTimeSpan;

        // Get LogLevelFilter setting from ServiceConfiguration.cscfg and then set it
        var LogLevelFilter = RoleEnvironment.GetConfigurationSettingValue("LogLevelFilter");
        var myLogLevel = LogLevel.Undefined;
        switch (LogLevelFilter)
        {
            case ("Information"):
                myLogLevel = LogLevel.Information;
                break;
            case ("Verbose"):
                myLogLevel = LogLevel.Verbose;
                break;
            case ("Warning"):
                myLogLevel = LogLevel.Warning;
                break;
            case ("Critical"):
                myLogLevel = LogLevel.Critical;
                break;
            case ("Error"):
                myLogLevel = LogLevel.Error;
                break;
            default:
                break;
        }

        // Filter what will be sent to persistent storage.
        config.Logs.ScheduledTransferLogLevelFilter = myLogLevel;
        config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = myLogLevel;
        config.WindowsEventLog.ScheduledTransferLogLevelFilter = myLogLevel;

        // Add in configuration settings for Windows Event logs
        config.WindowsEventLog.DataSources.Add("Application!*");
        config.WindowsEventLog.DataSources.Add("System!*");

        // Add a custom directory transfer
        DirectoryConfiguration directoryConfiguration = new DirectoryConfiguration();
        directoryConfiguration.Container = "wad-custom-logs";
        directoryConfiguration.DirectoryQuotaInMB = 0;
        directoryConfiguration.Path = @"c:\logs";
        config.Directories.DataSources.Add(directoryConfiguration);

        // Enable full crash dump collection.
        CrashDumps.EnableCollection(true);

        // Use 30 seconds for the perf counter sample rate.
        TimeSpan perfSampleRate = TimeSpan.FromSeconds(30D);

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Memory\Available Bytes",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Processor(_Total)\% Processor Time",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Process(WaWorkerHost)\% Processor Time",
            SampleRate = perfSampleRate
        });

        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Process(WaWorkerHost)\Private Bytes",
            SampleRate = perfSampleRate
        }); 
                
        config.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration()
        {
            CounterSpecifier = @"\Process(WaWorkerHost)\Thread Count",
            SampleRate = perfSampleRate
        });

        // Apply the updated configuration to the diagnostic monitor.
        // The first parameter is for the connection string configuration setting.
        DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);

    }
    catch (Exception e)  
        {
                sEvent += e.Message;
                EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Error, 0);
        } 
            
    return base.OnStart();   
}

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Windows_Azure_Full_Diagnostics" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole1">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="8080" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
    <ConfigurationSettings>
      <Setting name="ScheduledTransferPeriod" />
      <Setting name="LogLevelFilter" />
    </ConfigurationSettings>
    <LocalResources>
      <LocalStorage name="DiagnosticStore" cleanOnRoleRecycle="false" sizeInMB="8192" />
    </LocalResources>
  </WebRole>
  <WorkerRole name="WorkerRole1" vmsize="Small">
    <Imports>
      <Import moduleName="Diagnostics" />
      <Import moduleName="RemoteAccess" />
    </Imports>
    <LocalResources>
      <LocalStorage name="DiagnosticStore" sizeInMB="8192" cleanOnRoleRecycle="false" />
    </LocalResources>
    <ConfigurationSettings>
      <Setting name="ScheduledTransferPeriod" />
      <Setting name="LogLevelFilter" />
    </ConfigurationSettings>
  </WorkerRole>
</ServiceDefinition>

note참고
이 구성 파일은 계산 에뮬레이터와 함께 로컬로 사용됩니다.

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="Windows_Azure_Full_Diagnostics" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="2" osVersion="*">
  <Role name="WebRole1">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="ScheduledTransferPeriod" value="1" />
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
      <Setting name="LogLevelFilter" value="Verbose" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" value="me" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" value="MIIBnQYJKoZIhvcNAQcDoIIBjjCCAYoCAQAxggFOMIIBSgIBADAyMB4xHDAaBgNVBAMME1dpbmRvd3MgQXp1cmUgVG9vbHMCEDra5x6UQkuIRHdUChkiglEwDQYJKoZIhvcNAQEBBQAEggEAp8ADE0ov0pKTFo6V1AI94NmsUr8YcQ/dl4M63zbBQkrjSvqqzgofMcMwxYVO8gTwmr3eXawTNp2fbPdN68ZynNgRwEHBm67QP3y6lcAFvx8Amxvp8GZ6qxpAYGE8LhpqBNzoel55mot6IZg0I3qfXtl6SHyfLcyGuPv3nDEzhuYGuPSFR+UF82G2ZK0omLzSuI3KQcbFyTxaUYDIu/fSNOkHVOWwgpNND3SIvg+nSHfS38w+nskAA7bo7oN06LnC+3lLNRrpoKsPBaqogqfyhTkivc3+AJoQ6UAHIyyAJU6kfp4iP7gMl0ZU1mLVeqX5oDwmywf9FGRf7vSn2uEfiTAzBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECAw305eQdOSogBA6i8i7rTruZOxAadm1g545" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" value="2011-12-31T23:59:59.0000000-05:00" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" value="true" />
    </ConfigurationSettings>
    <Certificates>
      <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="D91092F38C839BE56787A0528591E49510FCC711" thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>
  <Role name="WorkerRole1">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
      <Setting name="ScheduledTransferPeriod" value="1" />
      <Setting name="LogLevelFilter" value="Verbose" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" value="me" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" value="MIIBnQYJKoZIhvcNAQcDoIIBjjCCAYoCAQAxggFOMIIBSgIBADAyMB4xHDAaBgNVBAMME1dpbmRvd3MgQXp1cmUgVG9vbHMCEDra5x6UQkuIRHdUChkiglEwDQYJKoZIhvcNAQEBBQAEggEAp8ADE0ov0pKTFo6V1AI94NmsUr8YcQ/dl4M63zbBQkrjSvqqzgofMcMwxYVO8gTwmr3eXawTNp2fbPdN68ZynNgRwEHBm67QP3y6lcAFvx8Amxvp8GZ6qxpAYGE8LhpqBNzoel55mot6IZg0I3qfXtl6SHyfLcyGuPv3nDEzhuYGuPSFR+UF82G2ZK0omLzSuI3KQcbFyTxaUYDIu/fSNOkHVOWwgpNND3SIvg+nSHfS38w+nskAA7bo7oN06LnC+3lLNRrpoKsPBaqogqfyhTkivc3+AJoQ6UAHIyyAJU6kfp4iP7gMl0ZU1mLVeqX5oDwmywf9FGRf7vSn2uEfiTAzBgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECAw305eQdOSogBA6i8i7rTruZOxAadm1g545" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" value="2011-12-31T23:59:59.0000000-05:00" />
    </ConfigurationSettings>
    <Certificates>
      <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" thumbprint="D91092F38C839BE56787A0528591E49510FCC711" thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>
</ServiceConfiguration>

웹 역할의 diagnostics.wadcfg 파일에 대한 예제입니다.

<?xml version="1.0" encoding="utf-8" ?>
<DiagnosticMonitorConfiguration xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"
      configurationChangePollInterval="PT1M"
      overallQuotaInMB="4096">
  <DiagnosticInfrastructureLogs bufferQuotaInMB="0"
     scheduledTransferLogLevelFilter="Verbose"
     scheduledTransferPeriod="PT1M" />
  <Logs bufferQuotaInMB="0"
     scheduledTransferLogLevelFilter="Verbose"
     scheduledTransferPeriod="PT1M" />
  <Directories bufferQuotaInMB="0"
     scheduledTransferPeriod="PT1M">

    <!-- These three elements specify the special directories 
           that are set up for the log types -->
    <CrashDumps container="wad-crash-dumps" directoryQuotaInMB="0" />
    <FailedRequestLogs container="wad-frq" directoryQuotaInMB="0" />
    <IISLogs container="wad-iis" directoryQuotaInMB="0" />
  </Directories>

  <PerformanceCounters bufferQuotaInMB="0" scheduledTransferPeriod="PT1M">
    <!-- The counter specifier is in the same format as the imperative 
           diagnostics configuration API -->
    <PerformanceCounterConfiguration counterSpecifier="\Memory\Available Bytes" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\Processor(_Total)\% Processor Time" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\Process(w3wp)\% Processor Time" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\Process(w3wp)\Private Bytes" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\Process(w3wp)\Thread Count" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Interop(_Global_)\# of marshalling" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Loading(_Global_)\% Time Loading" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR LocksAndThreads(_Global_)\Contention Rate / sec" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Memory(_Global_)\# Bytes in all Heaps" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Networking(_Global_)\Connections Established" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Remoting(_Global_)\Remote Calls/sec" sampleRate="PT30S" />
    <PerformanceCounterConfiguration counterSpecifier="\.NET CLR Jit(_Global_)\% Time in Jit" sampleRate="PT30S" />
  </PerformanceCounters>
  <WindowsEventLog bufferQuotaInMB="0"
     scheduledTransferLogLevelFilter="Verbose"
     scheduledTransferPeriod="PT1M">
    <!-- The event log name is in the same format as the imperative 
           diagnostics configuration API -->
    <DataSource name="Application!*" />
    <DataSource name="System!*" />
  </WindowsEventLog>
</DiagnosticMonitorConfiguration>

wad-control-container Blob에 작성된 기본 구성입니다.

<?xml version="1.0"?>
<ConfigRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <DataSources>
    <OverallQuotaInMB>4080</OverallQuotaInMB>
    <Logs>
      <BufferQuotaInMB>0</BufferQuotaInMB>
      <ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>
      <ScheduledTransferLogLevelFilter>Undefined</ScheduledTransferLogLevelFilter>
    </Logs>
    <DiagnosticInfrastructureLogs>
      <BufferQuotaInMB>0</BufferQuotaInMB>
      <ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>
      <ScheduledTransferLogLevelFilter>Undefined</ScheduledTransferLogLevelFilter>
    </DiagnosticInfrastructureLogs>
    <PerformanceCounters>
      <BufferQuotaInMB>0</BufferQuotaInMB>
      <ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>
      <Subscriptions />
    </PerformanceCounters>
    <WindowsEventLog>
      <BufferQuotaInMB>0</BufferQuotaInMB>
      <ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>
      <Subscriptions />
      <ScheduledTransferLogLevelFilter>Undefined</ScheduledTransferLogLevelFilter>
    </WindowsEventLog>
    <Directories>
      <BufferQuotaInMB>0</BufferQuotaInMB>
      <ScheduledTransferPeriodInMinutes>0</ScheduledTransferPeriodInMinutes>
      <Subscriptions>
        <DirectoryConfiguration>
          <Path>C:\Users\me\AppData\Local\dftmp\Resources\c95f5289-7d10-4bff-b105-198904c9ad93\directory\DiagnosticStore\FailedReqLogFiles</Path>
          <Container>wad-iis-failedreqlogfiles</Container>
          <DirectoryQuotaInMB>1024</DirectoryQuotaInMB>
        </DirectoryConfiguration>
        <DirectoryConfiguration>
          <Path>C:\Users\me\AppData\Local\dftmp\Resources\c95f5289-7d10-4bff-b105-198904c9ad93\directory\DiagnosticStore\LogFiles</Path>
          <Container>wad-iis-logfiles</Container>
          <DirectoryQuotaInMB>1024</DirectoryQuotaInMB>
        </DirectoryConfiguration>
        <DirectoryConfiguration>
          <Path>C:\Users\me\AppData\Local\dftmp\Resources\c95f5289-7d10-4bff-b105-198904c9ad93\directory\DiagnosticStore\CrashDumps</Path>
          <Container>wad-crash-dumps</Container>
          <DirectoryQuotaInMB>1024</DirectoryQuotaInMB>
        </DirectoryConfiguration>
      </Subscriptions>
    </Directories>
  </DataSources>
  <IsDefault>true</IsDefault>
</ConfigRequest>

이 정보가 도움이 되었습니까?
(1500자 남음)
의견을 주셔서 감사합니다.
표시:
© 2014 Microsoft