将连续的非零行标记到不同的分区中,这次使用 kusto——Azure AppInsights 的查询语言
Tag consecutive non zero rows into distinct partitions, this time using kusto - the query language of the Azure AppInsights
我们正在使用 Azure DevOps Server 2019(本地)。因此,构建分析几乎不存在。因此,我们设置了一个流程,将完成的构建指标上传到 Azure AppInsights,这使我们能够编写各种有趣的仪表板。
我的经理想知道三件事:
- 构建失败的频率如何?
- 构建需要多长时间?
- 构建会中断多长时间?
前两个很简单,但最后一个很难。
首先,我将问题翻译成Sql,并在
的帮助下解决了
收到 Sql 的答案后,我能够将其翻译成 Kql(AppInsights 使用的 Kusto 查询语言),如下所示:
customEvents
| where customDimensions.kind == "build"
and name == 'vNext_master_ci_r_git'
| project
startTime = todatetime(customDimensions.startTime),
outcome = tostring(customDimensions.buildResult)
| where outcome in ('succeeded', 'failed')
| order by startTime asc
| extend
nextStartTime = next(startTime, 1)
| extend
duration = case(outcome == 'failed', nextStartTime - startTime, totimespan(0)),
rn = row_number(),
rn2 = row_number(1, prev(outcome) != outcome)
| extend
grp = rn - rn2
| where outcome == 'failed'
| summarize startTime = min(startTime), duration = toreal(sum(duration) / time(1h)) by grp
| order by startTime asc
| project startTime, duration
如您所见,这是相应 Sql 的 1-1 翻译。但是,我想知道在 Kql 中是否有更简洁的方法来实现这个目标。我的理由是Kql是为支持数据分析而设计的,所以也许它可以提供更优雅的解决方案。
我不确定以下是您要查找的内容,但肯定更简洁。此外,我没有数据样本,因此我尝试从您的查询中构建部分数据。所以让我们假设我们有:
let customEvents = datatable (customDimensions: dynamic, name: string)
[
dynamic({ "kind": "build", "startTime": "2021-01-14T10:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T11:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T12:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T13:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T14:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T15:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T16:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T17:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T18:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T19:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T20:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T21:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git"
];
那么我们可以这样做:
customEvents
| where customDimensions.kind == "build"
and name == 'vNext_master_ci_r_git'
| project
startTime = todatetime(customDimensions.startTime),
outcome = tostring(customDimensions.buildResult)
| serialize | extend statusChangedTime = row_window_session(startTime, 24h, 24h, outcome != prev(outcome))
| summarize by outcome, statusChangedTime
| serialize | extend prevStatusChangedTime = prev(statusChangedTime)
| where outcome == "succeeded" and isnotnull(prevStatusChangedTime)
| project startTime = prevStatusChangedTime, duration = (statusChangedTime - prevStatusChangedTime) / 1h
因为您已经在使用 next
and prev
, I assume you are aware of Window functions overview. row_window_session
正是您正在寻找的方法。它可以让您根据行之间的检查按时开窗。所以查询的输出,给定的数据是:
2021-01-14T11:00:00Z 3
2021-01-14T17:00:00Z 2
与您的查询相同。
我们正在使用 Azure DevOps Server 2019(本地)。因此,构建分析几乎不存在。因此,我们设置了一个流程,将完成的构建指标上传到 Azure AppInsights,这使我们能够编写各种有趣的仪表板。
我的经理想知道三件事:
- 构建失败的频率如何?
- 构建需要多长时间?
- 构建会中断多长时间?
前两个很简单,但最后一个很难。
首先,我将问题翻译成Sql,并在
收到 Sql 的答案后,我能够将其翻译成 Kql(AppInsights 使用的 Kusto 查询语言),如下所示:
customEvents
| where customDimensions.kind == "build"
and name == 'vNext_master_ci_r_git'
| project
startTime = todatetime(customDimensions.startTime),
outcome = tostring(customDimensions.buildResult)
| where outcome in ('succeeded', 'failed')
| order by startTime asc
| extend
nextStartTime = next(startTime, 1)
| extend
duration = case(outcome == 'failed', nextStartTime - startTime, totimespan(0)),
rn = row_number(),
rn2 = row_number(1, prev(outcome) != outcome)
| extend
grp = rn - rn2
| where outcome == 'failed'
| summarize startTime = min(startTime), duration = toreal(sum(duration) / time(1h)) by grp
| order by startTime asc
| project startTime, duration
如您所见,这是相应 Sql 的 1-1 翻译。但是,我想知道在 Kql 中是否有更简洁的方法来实现这个目标。我的理由是Kql是为支持数据分析而设计的,所以也许它可以提供更优雅的解决方案。
我不确定以下是您要查找的内容,但肯定更简洁。此外,我没有数据样本,因此我尝试从您的查询中构建部分数据。所以让我们假设我们有:
let customEvents = datatable (customDimensions: dynamic, name: string)
[
dynamic({ "kind": "build", "startTime": "2021-01-14T10:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T11:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T12:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T13:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T14:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T15:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T16:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T17:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T18:00:00Z", "buildResult": "failed" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T19:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T20:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git",
dynamic({ "kind": "build", "startTime": "2021-01-14T21:00:00Z", "buildResult": "succeeded" }), "vNext_master_ci_r_git"
];
那么我们可以这样做:
customEvents
| where customDimensions.kind == "build"
and name == 'vNext_master_ci_r_git'
| project
startTime = todatetime(customDimensions.startTime),
outcome = tostring(customDimensions.buildResult)
| serialize | extend statusChangedTime = row_window_session(startTime, 24h, 24h, outcome != prev(outcome))
| summarize by outcome, statusChangedTime
| serialize | extend prevStatusChangedTime = prev(statusChangedTime)
| where outcome == "succeeded" and isnotnull(prevStatusChangedTime)
| project startTime = prevStatusChangedTime, duration = (statusChangedTime - prevStatusChangedTime) / 1h
因为您已经在使用 next
and prev
, I assume you are aware of Window functions overview. row_window_session
正是您正在寻找的方法。它可以让您根据行之间的检查按时开窗。所以查询的输出,给定的数据是:
2021-01-14T11:00:00Z 3
2021-01-14T17:00:00Z 2
与您的查询相同。