Voice/Video KQL Overview¶
Analyze call quality, media performance, and per-participant call outcomes using the calling log tables that ACS actually emits.
Log Analytics Tables¶
ACS calling emits multiple log types. The three tables covered here are the ones most commonly queried for post-call quality and outcome analysis. CorrelationId joins call-scoped rows across ACSCallSummary and ACSCallDiagnostics; the survey table uses a participant-scoped correlator described in the key columns section below.
| Table | Grain | Purpose |
|---|---|---|
ACSCallSummary | One row per call participant | Call-level and participant-level metadata: CallDuration, CallStartTime, ParticipantEndReason, ParticipantType, EndpointType, PSTN participant info. |
ACSCallDiagnostics | One row per media stream per participant | Per-stream network quality metrics: RoundTripTimeAvg/Max, JitterAvg/Max, PacketLossRateAvg/Max, plus stream metadata like MediaType, StreamDirection, CodecName. |
ACSCallSurvey | One row per submitted survey | Participant-reported ratings: OverallRatingScore, AudioRatingScore, VideoRatingScore, ScreenshareRatingScore, plus reported issue categories. |
Key columns used across the queries below:
CorrelationId— joins call-scoped rows acrossACSCallSummaryandACSCallDiagnostics. ForACSCallSurvey, the table reference documentsCorrelationIdas the participant ID used to correlate survey rows with other calling logs, so survey joins go through the participant identifier rather than the call correlator.ParticipantEndReason— participant's call end reason onACSCallSummary. There is noCallEndReasoncolumn; the reason is scoped per participant.RoundTripTimeAvg,JitterAvg— integers in milliseconds onACSCallDiagnostics.PacketLossRateAvg— a real between 0 and 1 onACSCallDiagnostics.MediaType,StreamDirection— filter dimensions onACSCallDiagnostics(for exampleAudiovsVideo,InboundvsOutbound).OverallRatingScore,AudioRatingScore,VideoRatingScore— integers onACSCallSurvey; each has a companion*RatingScoreLowerBound,*RatingScoreUpperBound, and*RatingScoreThresholdfor interpretation.
No preset quality score column
The documented columns for ACSCallDiagnostics and ACSCallSummary do not include a preset per-call or per-stream quality-score column. Objective network quality is expressed as raw metrics (RoundTripTimeAvg, JitterAvg, PacketLossRateAvg) that engineers bucket against their own thresholds. Subjective quality comes from ACSCallSurvey ratings, which are user-reported and optional.
Key Scenarios¶
| Scenario | KQL Query | Description |
|---|---|---|
| Per-Stream Network Quality | Call Quality Metrics | Aggregate RoundTripTimeAvg, JitterAvg, and PacketLossRateAvg per call across degraded streams. |
| Participant End Reasons | Participant End Reasons | Track why participants left calls over time, using ParticipantEndReason on ACSCallSummary. |
| Post-Call Subjective Quality | Survey Ratings | Aggregate participant-reported OverallRatingScore from ACSCallSurvey. |
Query Examples¶
Participant End Reasons¶
Track how participants left calls (for example clean hang-up vs error). ACSCallSummary emits one row per participant with ParticipantEndReason populated.
ACSCallSummary
| where TimeGenerated > ago(24h)
| summarize ParticipantCount = count() by ParticipantEndReason, bin(TimeGenerated, 1h)
| render barchart
Survey Ratings¶
Aggregate participant-submitted overall call quality ratings. OverallRatingScore is an integer; use the companion OverallRatingScoreLowerBound, OverallRatingScoreUpperBound, and OverallRatingScoreThreshold columns to interpret the scale for each rating.
ACSCallSurvey
| where TimeGenerated > ago(24h)
| where isnotnull(OverallRatingScore)
| summarize
AverageOverallScore = avg(OverallRatingScore),
SurveyCount = count()
by bin(TimeGenerated, 1h)
| render timechart