你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

查询通话日志

概览和访问权限

在为通信服务日志使用 Log Analytics 之前,必须首先按照在诊断设置中启用日志记录中所述的步骤进行操作。 启用日志和 Log Analytics 工作区后,你将有权访问许多有用的默认查询包,这些包将帮助你快速可视化并了解日志中的可用数据,如下所述。 通过 Log Analytics,你还可以使用 Azure Monitor 工作簿访问更多通信服务见解,创建自己的查询和工作簿,并使用 Log Analytics API 概述进行任何查询。

Access

可以通过以下方式访问查询:转到你的通信服务资源页,然后在左侧导航栏的“监视”部分中单击“日志”:

Log Analytics 导航

在这里,你会看到一个模式屏幕,其中包括可用于你的通信服务的所有默认查询包,左侧带有可用于进行导航的查询包列表。

日志分析查询模式

如果关闭模式屏幕,仍可以根据在诊断设置中启用的日志和指标的架构导航到各种查询包,并以表的形式直接访问数据。 此处,可以使用 KQL (Kusto) 从数据创建自己的查询。 有关使用、编辑和创建查询的详细信息,请参阅:Log Analytics 查询

资源中的 Log Analytics 查询

资源中的 Log Analytics 表

适用于呼叫摘要和呼叫诊断日志的默认查询包

以下是默认查询包中每个查询的说明,适用于呼叫摘要和呼叫诊断日志,其中包括每个可用查询的代码示例和示例输出:

呼叫概览查询

每个呼叫的参与者数量

// Count number of calls and participants,
// and print average participants per call
ACSCallSummary
| distinct CorrelationId, ParticipantId, EndpointId
| summarize num_participants=count(), num_calls=dcount(CorrelationId)
| extend avg_participants = todecimal(num_participants) / todecimal(num_calls)

示例输出:

呼叫概览查询

每个群组呼叫的参与者数量

// Count number of participants per group call
ACSCallSummary
| where CallType == 'Group'
| distinct CorrelationId, ParticipantId
| summarize num_participants=count() by CorrelationId
| summarize participant_counts=count() by num_participants
| order by num_participants asc 
| render columnchart with  (xcolumn = num_participants, title="Number of participants per group call")

示例输出:

每个群组呼叫的参与者数量查询

呼叫类型的比例

// Ratio of call types
ACSCallSummary
| summarize call_types=dcount(CorrelationId) by CallType
| render piechart title="Call Type Ratio"

示例输出:

呼叫类型的比例查询

呼叫持续时间分布

// Call duration histogram
ACSCallSummary
| distinct CorrelationId, CallDuration
|summarize duration_counts=count() by CallDuration
| order by CallDuration asc
| render columnchart with (xcolumn = CallDuration, title="Call duration histogram")

示例输出:

呼叫持续时间查询

呼叫持续时间百分位数

// Call duration percentiles
ACSCallSummary
| distinct CorrelationId, CallDuration
| summarize avg(CallDuration), percentiles(CallDuration, 50, 90, 99)

示例输出:

呼叫持续时间百分位数查询

终结点信息查询

每个呼叫的终结点数量

// Count number of calls and endpoints,
// and print average endpoints per call
ACSCallSummary
| distinct CorrelationId, EndpointId
| summarize num_endpoints=count(), num_calls=dcount(CorrelationId)
| extend avg_endpoints = todecimal(num_endpoints) / todecimal(num_calls)

示例输出:

每个呼叫的终结点数量查询

SDK 版本的比例

// Ratio of SDK Versions
ACSCallSummary
| distinct CorrelationId, ParticipantId, EndpointId, SdkVersion
| summarize sdk_counts=count() by SdkVersion
| order by SdkVersion asc
| render piechart title="SDK Version Ratio"

示例输出:

显示 SDK 版本比例的饼图。显示 SDK 版本的表

OS 版本的比例(简化的 OS 名称)

// Ratio of OS Versions (simplified OS name)
ACSCallSummary
| distinct CorrelationId, ParticipantId, EndpointId, OsVersion
| extend simple_os = case(  indexof(OsVersion, "Android") != -1, tostring(split(OsVersion, ";")[0]),
                            indexof(OsVersion, "Darwin") != -1, tostring(split(OsVersion, ":")[0]),
                            indexof(OsVersion, "Windows") != -1, tostring(split(OsVersion, ".")[0]),
                            OsVersion
                        )
| summarize os_counts=count() by simple_os
| order by simple_os asc
| render piechart title="OS Version Ratio"

示例输出:

显示操作系统比例的饼图显示 OS 版本的表

媒体流查询

每个呼叫的流数量

// Count number of calls and streams,
// and print average streams per call
ACSCallDiagnostics
| summarize num_streams=count(), num_calls=dcount(CorrelationId)
| extend avg_streams = todecimal(num_streams) / todecimal(num_calls)

示例输出:

每个呼叫的流数量查询

每个呼叫的流数量直方图

// Distribution of streams per call
ACSCallDiagnostics
| summarize streams_per_call=count() by CorrelationId
| summarize stream_counts=count() by streams_per_call
| order by streams_per_call asc
| render columnchart title="Streams per call histogram"

每个呼叫的流数量直方图

媒体类型的比例

// Ratio of media types by call
ACSCallDiagnostics
| summarize media_types=count() by MediaType
| render piechart title="Media Type Ratio"

显示媒体类型比例的饼图

质量指标查询

平均遥测值

// Average telemetry values over all streams
ACSCallDiagnostics
| summarize Avg_JitterAvg=avg(JitterAvg),
            Avg_JitterMax=avg(JitterMax),
            Avg_RoundTripTimeAvg=avg(RoundTripTimeAvg),
            Avg_RoundTripTimeMax=avg(RoundTripTimeMax),
            Avg_PacketLossRateAvg=avg(PacketLossRateAvg),
            Avg_PacketLossRateMax=avg(PacketLossRateMax)

平均遥测值

JitterAvg 直方图

// Jitter Average Histogram
ACSCallDiagnostics
| where isnotnull(JitterAvg)
| summarize JitterAvg_counts=count() by JitterAvg
| order by JitterAvg asc
| render columnchart with (xcolumn = JitterAvg, title="JitterAvg histogram")

抖动平均值直方图

JitterMax 直方图

// Jitter Max Histogram
ACSCallDiagnostics
| where isnotnull(JitterMax)
|summarize JitterMax_counts=count() by JitterMax
| order by JitterMax asc
| render columnchart with (xcolumn = JitterMax, title="JitterMax histogram")

抖动最大值直方图

PacketLossRateAvg 直方图

// PacketLossRate Average Histogram
ACSCallDiagnostics
| where isnotnull(PacketLossRateAvg)
|summarize PacketLossRateAvg_counts=count() by bin(PacketLossRateAvg, 0.01)
| order by PacketLossRateAvg asc
| render columnchart with (xcolumn = PacketLossRateAvg, title="PacketLossRateAvg histogram")

数据包丢失平均值直方图

PacketLossRateMax 直方图

// PacketLossRate Max Histogram
ACSCallDiagnostics
| where isnotnull(PacketLossRateMax)
|summarize PacketLossRateMax_counts=count() by bin(PacketLossRateMax, 0.01)
| order by PacketLossRateMax asc
| render columnchart with (xcolumn = PacketLossRateMax, title="PacketLossRateMax histogram")

数据包丢失最大值直方图

RoundTripTimeAvg 直方图

// RoundTripTime Average Histogram
ACSCallDiagnostics
| where isnotnull(RoundTripTimeAvg)
|summarize RoundTripTimeAvg_counts=count() by RoundTripTimeAvg
| order by RoundTripTimeAvg asc
| render columnchart with (xcolumn = RoundTripTimeAvg, title="RoundTripTimeAvg histogram")

RTT 平均值直方图

RoundTripTimeMax 直方图

// RoundTripTime Max Histogram
ACSCallDiagnostics
| where isnotnull(RoundTripTimeMax)
|summarize RoundTripTimeMax_counts=count() by RoundTripTimeMax
| order by RoundTripTimeMax asc
| render columnchart with (xcolumn = RoundTripTimeMax, title="RoundTripTimeMax histogram")

RTT 最大值直方图

抖动质量较差

// Get proportion of calls with poor quality jitter
// (defined as jitter being higher than 30ms)
ACSCallDiagnostics
| extend JitterQuality = iff(JitterAvg > 30, "Poor", "Good")
| summarize count() by JitterQuality
| render piechart title="Jitter Quality"

抖动质量

PacketLossRate 质量

// Get proportion of calls with poor quality packet loss
// rate (defined as packet loss being higher than 10%)
ACSCallDiagnostics
| extend PacketLossRateQuality = iff(PacketLossRateAvg > 0.1, "Poor", "Good")
| summarize count() by PacketLossRateQuality
| render piechart title="Packet Loss Rate Quality"

数据包丢失率质量

RoundTripTime 质量

// Get proportion of calls with poor quality packet loss
// rate (defined as packet loss being higher than 10%)
ACSCallDiagnostics
| extend PacketLossRateQuality = iff(PacketLossRateAvg > 0.1, "Poor", "Good")
| summarize count() by PacketLossRateQuality
| render piechart title="Packet Loss Rate Quality"

RTT 质量

可参数化查询

上周的每日呼叫数量

// Histogram of daily calls over the last week
ACSCallSummary
| where CallStartTime > now() - 7d
| distinct CorrelationId, CallStartTime
| extend hour  = floor(CallStartTime, 1d)
| summarize event_count=count() by day
| sort by day asc
| render columnchart title="Number of calls in last week"

上周的每日呼叫数量

前一天每小时的呼叫数量

// Histogram of calls per hour in the last day
ACSCallSummary
| where CallStartTime > now() - 1d
| distinct CorrelationId, CallStartTime
| extend hour = floor(CallStartTime, 1h)
| summarize event_count=count() by hour
| sort by hour asc
| render columnchart title="Number of calls per hour in last day"

前一天每小时的呼叫数量