使用 Azure Insights and/or Analytics 警告错误率超过阈值

Alert on error rate exceeding threshold using Azure Insights and/or Analytics

我正在向 Azure Application Insights 发送 customEvents,如下所示:

timestamp                 |  name          |  customDimensions
----------------------------------------------------------------------------
2017-06-22T14:10:07.391Z  |  StatusChange  |  {"Status":"3000","Id":"49315"}
2017-06-22T14:10:14.699Z  |  StatusChange  |  {"Status":"3000","Id":"49315"}
2017-06-22T14:10:15.716Z  |  StatusChange  |  {"Status":"2000","Id":"49315"}
2017-06-22T14:10:21.164Z  |  StatusChange  |  {"Status":"1000","Id":"41986"}
2017-06-22T14:10:24.994Z  |  StatusChange  |  {"Status":"3000","Id":"41986"}
2017-06-22T14:10:25.604Z  |  StatusChange  |  {"Status":"2000","Id":"41986"}
2017-06-22T14:10:29.964Z  |  StatusChange  |  {"Status":"3000","Id":"54234"}
2017-06-22T14:10:35.192Z  |  StatusChange  |  {"Status":"2000","Id":"54234"}
2017-06-22T14:10:35.809Z  |  StatusChange  |  {"Status":"3000","Id":"54234"}
2017-06-22T14:10:39.22Z   |  StatusChange  |  {"Status":"1000","Id":"74458"}

假设状态 3000 是错误状态,我想在过去一小时内有一定百分比的 Ids 最终处于错误状态时收到警报。

据我所知,Insights 默认情况下无法执行此操作,因此我想尝试 approach described here 编写可以触发警报的 Analytics 查询。这是我能想到的最好的:

customEvents
| where timestamp > ago(1h)
| extend isError = iff(toint(customDimensions.Status) == 3000, 1, 0)
| summarize failures = sum(isError), successes = sum(1 - isError) by timestamp bin = 1h
| extend ratio = todouble(failures) / todouble(failures+successes)
| extend failure_Percent = ratio * 100
| project iff(failure_Percent < 50, "PASSED", "FAILED")

但是,为了让我的警报正常工作,查询应该:

  1. Return "PASSED" 即使在一小时内没有事件(另一个警报会处理没有事件)
  2. 只考虑小时内每个Id的最终状态

写入请求时,如果没有事件,则查询 return 既不是 "PASSED" 也不是 "FAILED"。

它还考虑了带有 Status == 3000any 条记录,这意味着上面的示例将 return "FAILED"(5 个10 条记录的状态为 3000),而实际上 4 个 ID 中只有 1 个最终处于错误状态。

谁能帮我找出正确的查询?

(以及可选的次要问题:是否有人使用 Insights 设置了类似的警报?这是正确的方法吗?)

我假设如果您在一小时内没有数据,查询 return 没有行,因为 timestamp bin = 1h(又名 bin(timestamp,1h))不会 return 有垃圾桶吗?

但是如果您只查询最后一个小时,我认为您根本不需要时间戳上的 bin?

如果没有你的数据,很难准确地重现,但是......你可以尝试类似的东西(当心语法错误):

customEvents
| where timestamp > ago(1h)
| extend isError = iff(toint(customDimensions.Status) == 3000, 1, 0)
| summarize totalCount = count(), failures = countif(isError == 1), successes = countif(isError ==0) 
| extend ratio = iff(totalCount == 0, 0, todouble(failures) / todouble(failures+successes))
| extend failure_Percent = ratio * 100
| project iff(failure_Percent < 50, "PASSED", "FAILED")

假设,摆脱小时分级应该只会让你回到这里的一行

totalCount = 0, failures = 0, successes = 0,所以失败百分比的数学计算应该返回 0 失败率,这应该让你 "PASSED".

没有尝试,我不确定这是否有效,或者仍然return如果没有数据,你没有行吗?

对于你的第二个问题,你可以使用类似

let maxTimestamp = toscalar(customEvents where timestamp > ago(1h)
| summarize max(timestamp));
customEvents | where timestamp == maxTimestamp ...
// ... more query here

只获取具有该小时最后一个事件的时间戳的行?

如前所述,由于您只查询一个小时,因此不需要对 timestamp 进行分类,也根本不需要将其用作聚合的一部分。
回答您的问题:

  1. 克服完全没有数据的方法是在您的 table 中插入一个合成行,如果没有找到其他结果,这将转化为成功结果
  2. 如果您希望 pass/fail 标准基于每个 ID 的最终状态,那么您需要在 summarize 中使用 argmax - 它会 return 最大时间戳对应的状态。

总结一下:

customEvents
| where timestamp > ago(1h)
| extend isError = iff(toint(customDimensions.Status) == 3000, 1, 0)
| summarize argmax(timestamp, isError) by tostring(customDimensions.Id) 
| summarize failures = sum(max_timestamp_isError), successes = sum(1 - max_timestamp_isError)
| extend ratio = todouble(failures) / todouble(failures+successes)
| extend failure_Percent = ratio * 100
| project Result = iff(failure_Percent < 50, "PASSED", "FAILED"), IsSynthetic = 0
| union (datatable(Result:string, IsSynthetic:long) ["PASSED", 1])
| top 1 by IsSynthetic asc 
| project Result 

关于奖励问题 - 您可以使用 Flow 设置基于 Analytics 查询的警报。有关相关 question/answer

,请参阅