모니터링은 시스템의 동작과 상태에 대한 인사이트를 제공하며 환경과 과거 추세에 대해 전체적으로 파악하고, 다양한 요소의 상관 관계를 지정하고, 성능, 소비 또는 오류율의 변화를 측정하는 데 도움이 됩니다.
Azure Functions는 Application Insights와의 기본 제공 통합을 제공합니다. Application Insights에서 함수 앱 인스턴스 수 또는 함수의 요청과 종속성 원격 분석과 같은 정보를 얻을 수 있습니다. Functions 및 Event Hubs를 사용할 때 Application Insights는 이벤트 허브로 나가는 종속성 원격 분석을 추적하여 처리 시간을 계산하고 Event Hubs를 통해 연결된 시스템의 엔드 투 엔드 흐름을 표시할 수도 있습니다.
이 섹션에서는 Event Hubs와 Functions 솔루션에 대해 Application Insights에서 얻을 수 있는 유용한 기능과 인사이트를 소개합니다.
애플리케이션 맵
애플리케이션 맵은 시스템의 구성 요소가 서로 상호 작용하는 방법을 보여 줍니다. Application Insights에서 제공하는 종속성 원격 분석으로 인해 Event Hubs에서 각 함수 실행의 평균 및 평균 이벤트 기간을 포함하여 Azure Functions와 Event Hubs 간의 이벤트 흐름을 매핑하고 빨간색으로 표시된 오류가 포함된 트랜잭션을 표시합니다.
시스템에 예상 부하를 보낸 후 Azure Portal에서 Application Insights로 이동하고 사이드바에서 애플리케이션 맵을 선택할 수 있습니다. 다음은 다운스트림 데이터베이스에 쓸 때 세 가지 함수, 세 개의 이벤트 허브와 명백한 오류를 보여 주는 맵입니다.
엔드투엔드 트랜잭션 세부 정보
엔드투엔드 트랜잭션 세부 정보는 시스템 구성 요소가 서로 상호 작용하는 방식을 시간순으로 보여 줍니다. 또한 이 보기는 이벤트가 처리에 소요된 시간을 보여줍니다. 또한 이 보기에서 각 구성 요소의 원격 분석을 자세히 살펴볼 수 있으므로 문제가 발생했을 때 동일한 요청 내의 구성 요소 간에 문제를 더 쉽게 해결할 수 있습니다.
플랫폼 메트릭과 원격 분석
Event Hubs용 Azure Monitor와 Azure Functions 플랫폼 생성 메트릭을 솔루션 동작과 상태를 전반적으로 모니터링하는 데 사용할 수 있습니다.
Azure Monitor의 Azure Event Hubs 메트릭은 Event Hubs에 대한 유용한 인사이트(예: 들어오는 요청, 나가는 요청, 제한된 요청, 성공적인 요청, 들어오는 메시지, 보내는 메시지, 캡처된 메시지, 들어오는 바이트, 보내는 바이트, 캡처된 바이트, 사용자 오류)를 캡처하는 데 유용합니다.
Azure Functions 메트릭은 Azure App Service의 많은 메트릭을 공유하며 함수 실행 횟수와 함수 실행 단위를 추가하여 사용률과 소비 계획의 비용을 이해하는 데 사용할 수 있습니다. 관심 있는 다른 메트릭으로는 연결, 데이터 입력, 데이터 출력, 평균 메모리 작업 세트, 스레드 수, 요청, 응답 시간이 있습니다.
Azure Functions는 Application Insights와 통합되어 Functions 호스트와 함수 실행에 대한 자세한 고급 원격 분석 및 인사이트를 제공합니다. 자세한 내용은 Application Insights에서 Azure Functions 원격 분석을 참조하세요. Application Insights를 사용하여 토폴로지를 모니터링하는 경우 다양한 구성을 사용할 수 있습니다. 자세한 내용은 Azure Functions에 대한 모니터링을 구성하는 방법을 참조하세요.
다음은 추적 테이블에서 생성된 Event Hubs 트리거 함수에 대한 추가 원격 분석의 예입니다.
Trigger Details: PartionId: 6, Offset: 3985758552064-3985758624640, EnqueueTimeUtc: 2022-10-31T12:51:58.1750000+00:00-2022-10-31T12:52:03.8160000+00:00, SequenceNumber: 3712266-3712275, Count: 10
이 정보를 사용하려면 Event Hubs 확장 4.2.0 이상 버전을 사용해야 합니다. 이 데이터는 함수 실행을 트리거한 메시지에 대한 정보를 포함하고 쿼리와 인사이트에 사용할 수 있으므로 매우 유용합니다. 함수가 트리거될 때마다 다음 데이터가 포함됩니다.
- 파티션 ID(6)
- 파티션 오프셋 범위(3985758552064-3985758624640)
- UTC 기준 큐에 넣기 시간 범위(2022-10-31T12:51:58.1750000+00:00-2022-10-31T12:52:03.8160000+00:00)
- 시퀀스 번호 범위 3712266-3712275
- 그리고 메시지 수(10)
이 원격 분석을 사용하는 방법에 대한 예제는 Application Insights 쿼리 예제 섹션을 참조하세요.
사용자 지정 원격 분석은 다양한 언어(C# 클래스 라이브러리, C# 격리, C# 스크립트, JavaScript, Java, PowerShell, Python)에서도 가능합니다. 이 로깅은 Application Insights의 추적 테이블에 표시됩니다. Application Insights에 고유한 항목을 만들고 데이터를 쿼리하고 사용자 지정 대시보드를 만드는 데 사용할 수 있는 사용자 지정 차원을 추가할 수 있습니다.
마지막으로 함수 앱이 출력 바인딩을 사용하여 이벤트 허브에 연결되면 Application Insights 종속성 테이블에도 항목이 기록됩니다.
Event Hubs의 경우 상관 관계가 이벤트 페이로드에 삽입되고 이벤트에 Diagnostic-Id 속성이 표시됩니다.
이는 Functions에서 만든 원격 분석에서 작업 ID 및 작업 링크로도 사용되는 W3C 추적 컨텍스트 형식을 따르며, 이를 통해 Application Insights는 이벤트 허브 이벤트와 함수 실행 간의 상관 관계를 구성할 수 있습니다.
Application Insights 쿼리 예제
다음은 Azure Functions로 Event Hubs를 모니터링할 때 유용한 Application Insights 쿼리 목록입니다. 이 쿼리는 Event Hubs 확장 4.2.0 이상에서 내보낸 원격 분석을 사용하여 이벤트 허브 트리거 함수에 대한 자세한 정보를 표시합니다.
Application Insights에서 샘플링을 사용하도록 설정하면 데이터에 간격이 있을 수 있습니다.
자세한 이벤트 처리 정보
일괄 처리된 디스패치를 사용하는 경우에만 데이터가 올바른 형식으로 내보내집니다. 일괄 처리 디스패치는 함수가 각 실행에 대해 여러 이벤트를 수락함을 의미하며 이는 성능을 위해 권장됩니다. 다음과 같은 고려 사항을 염두에 둡니다.
-
dispatchTimeMilliseconds
값은 이벤트가 이벤트 허브에 쓰인 시점과 처리를 위해 함수 앱에서 선택된 시점 사이의 대략적인 시간입니다. -
dispatchTimeMilliseconds
는 이벤트 허브 서버와 함수 앱 간의 클록 드리프트로 인해 음수가 되거나 부정확할 수 있습니다. - Event Hubs 파티션은 순차적으로 처리됩니다. 이전 메시지가 모두 처리될 때까지 처리를 위해 메시지가 함수 코드로 디스패치되지 않습니다. 실행 시간이 길면 디스패치 지연이 발생하므로 함수의 실행 시간을 모니터링합니다.
- 계산은 일괄 처리에서 첫 번째 메시지의 enqueueTime을 사용합니다. 일괄 처리의 다른 메시지에 대한 디스패치 시간이 더 낮을 수 있습니다.
-
dispatchTimeMilliseconds
은 시점을 기준으로 합니다. - 시퀀스 번호는 파티션당이며 Event Hubs는 정확히 한 번 메시지가 배달됨을 보장하지 않으므로 중복 처리가 발생할 수 있습니다.
traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| extend dispatchTimeMilliseconds = (timestamp - enqueueTimeStart) / 1ms
| project timestamp, cloud_RoleInstance, operation_Name, processId =
customDimensions.ProcessId, partitionId, messageCount, sequenceNumberStart,
sequenceNumberEnd, enqueueTimeStart, enqueueTimeEnd, dispatchTimeMilliseconds
디스패치 대기 시간 시각화
이 쿼리는 지정된 이벤트 허브 트리거 함수에 대한 50번째와 90번째 백분위수 이벤트 디스패치 대기 시간을 시각화합니다. 자세한 내용과 참고 사항은 위의 쿼리를 참조하세요.
traces
| where operation_Name == "<ENTER THE NAME OF YOUR FUNCTION HERE>"
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| extend dispatchTimeMilliseconds = (timestamp - enqueueTimeStart) / 1ms
| summarize percentiles(dispatchTimeMilliseconds, 50, 90) by bin(timestamp, 5m)
| render timechart
디스패치 대기 시간 요약
이 쿼리는 위와 비슷하지만 요약 보기를 보여 줍니다.
traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| extend dispatchTimeMilliseconds = (timestamp - enqueueTimeStart) / 1ms
| summarize messageCount = sum(messageCount),
percentiles(dispatchTimeMilliseconds, 50, 90, 99, 99.9, 99.99) by operation_Name
파티션 간 메시지 배포
이 쿼리는 파티션 간에 메시지 배포를 시각화하는 방법을 보여 줍니다.
traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| summarize messageCount = sum(messageCount) by cloud_RoleInstance,
bin(timestamp, 5m)
| render areachart kind=stacked
인스턴스 간 메시지 배포
이 쿼리는 인스턴스 간에 메시지 배포를 시각화하는 방법을 보여 줍니다.
traces
| where message startswith "Trigger Details: Parti"
| parse message with * "tionId: " partitionId:string ", Offset: "
offsetStart:string "-" offsetEnd:string", EnqueueTimeUtc: "
enqueueTimeStart:datetime "+00:00-" enqueueTimeEnd:datetime "+00:00, SequenceNumber: "
sequenceNumberStart:string "-" sequenceNumberEnd:string ", Count: "
messageCount:int
| summarize messageCount = sum(messageCount) by cloud_RoleInstance,
bin(timestamp, 5m)
| render areachart kind=stacked
인스턴스와 할당된 인스턴스 실행
이 쿼리는 Event Hubs에서 이벤트를 처리하는 Azure Functions 인스턴스 수와 총 인스턴스 수(처리 및 임대 대기)를 시각화하는 방법을 보여 줍니다. 대부분의 경우 이는 동일해야 합니다.
traces
| where message startswith "Trigger Details: Parti"
| summarize type = "Executing Instances", Count = dcount(cloud_RoleInstance) by
bin(timestamp, 60s)
| union (
traces
| summarize type = "Allocated Instances", Count = dcount(cloud_RoleInstance) by
bin(timestamp, 60s)
)
| project timestamp, type, Count
| render timechart
특정 함수 실행에 대한 모든 원격 분석
operation_Id 필드는 Application Insights의 여러 테이블에서 사용할 수 있습니다. Event Hubs가 트리거한 Azure Functions의 경우 예를 들어 다음 쿼리는 트리거 정보, 함수 코드 내 로그의 원격 분석, 종속성 및 예외를 제공합니다.
union isfuzzy=true requests, exceptions, traces, dependencies
| where * has "<ENTER THE OPERATION_ID OF YOUR FUNCTION EXECUTION HERE>"
| order by timestamp asc
이벤트에 대한 엔드투엔드 대기 시간
트리거 세부 정보 추적의 enqueueTimeUtc 속성은 함수가 처리한 각 일괄 처리의 첫 번째 이벤트만 큐에 넣기 시간을 표시하므로, 고급 쿼리를 사용하여 Event Hubs를 사용하는 두 함수 간의 엔드투엔드 이벤트 대기 시간을 계산할 수 있습니다. 이 쿼리는 두 번째 함수의 요청에서 작업 링크(있는 경우)를 확장하고 종료 시간을 첫 번째 함수 시작 시간의 동일한 해당 작업 ID에 매핑합니다.
let start = view(){
requests
| where operation_Name == "FirstFunction"
| project start_t = timestamp, first_operation_Id = operation_Id
};
let link = view(){
requests
| where operation_Name == "SecondFunction"
| mv-expand ex = parse_json(tostring(customDimensions["_MS.links"]))
| extend parent = case(isnotempty(ex.operation_Id), ex.operation_Id, operation_Id )
| project first_operation_Id = parent, second_operation_Id = operation_Id
};
let finish = view(){
traces
| where customDimensions["EventName"] == "FunctionCompleted" and operation_Name
== "SecondFunction"
| project end_t = timestamp, second_operation_Id = operation_Id
};
start
| join kind=inner (
link
| join kind=inner finish on second_operation_Id
) on first_operation_Id
| project start_t, end_t, first_operation_Id, second_operation_Id
| summarize avg(datetime_diff('second', end_t, start_t))
참가자
Microsoft에서 이 문서를 유지 관리합니다. 원래 다음 기여자가 작성했습니다.
보안 주체 작성자:
- David Barkol | 수석 솔루션 전문가 GBB
비공개 LinkedIn 프로필을 보려면 LinkedIn에 로그인하세요.
다음 단계
자세히 알아보려면 다음 관련 문서를 검토하는 것이 좋습니다.