如何在 Kusto 中混合使用表格参数和标量参数来编写表格函数,以便您可以在整个组织中重复使用和共享它?

How do you write a tabular function in Kusto taking a mix of tabular and scalar arguments so you can reuse and share it across the organization?

几天来我一直在谷歌上搜索和摆弄这个问题,但一直找不到答案。

我想要实现的是计算服务器的数量 运行 一个特定时间段内的 azure 函数,我希望我的组织将此查询重用为表格函数,接收应用洞察请求 table 与我们正在监控的任何资源相关联,以及 用于对数据进行分类的时间桶查询的开始日期结束日期

我理解的基本签名应该是这样的:

let TotalServerCount = (T:(timestamp:datetime, customDimensions:dynamic, instanceId:guid), 
                          binBucket:timespan = 2m, startDate:datetime, endDate:datetime)
{
    T
    | "tabular expression"
}

我尝试了多种变体,但总是得到相同的错误:可调用表达式的主体不能为空

我遵循了以下链接中的指南:

  1. Scalar data types
  2. User defined functions
  3. Queries

完整的功能代码如下:

let TotalServerCount = (T:(timestamp:datetime, customDimensions:dynamic, instanceId:guid), 
                           binBucket:timespan = 2m, startDate:datetime, endDate:datetime)
{
    T
    | extend instanceId = toguid(customDimensions.HostInstanceId)
    | where timestamp >= startDate and timestamp <= endDate
    | summarize instanceIdCount=dcount(instanceId) by bin(timestamp, binBucket)
    | union (
        range x from 1 to 1 step 1
            | mvexpand timestamp=range(startDate, endDate, binBucket) to typeof(datetime) 
            | extend instanceIdCount=0
            | project timestamp, instanceIdCount
    )
    | order by timestamp asc
    | summarize instanceIdCount=sum(instanceIdCount) by bin(timestamp, binBucket)
    | render timechart
};

然后我会在一个单独的查询中调用 window,如下所示:

TotalServerCount(requests, 2m, ago(30d), now())

根据提供的示例here

A tabular function:

  • Is a function with no inputs, or at least one tabular input, and produces a tabular output
  • Can be used wherever a tabular expression is allowed

Note

All tabular parameters must appear before scalar parameters.

Example of a tabular function that uses a tabular input and a scalar input:

let MyFilter = (T:(x:long), v:long) {
  T | where x >= v 
};
MyFilter((range x from 1 to 10 step 1), 9)

有谁知道我在这里误解了什么?我正在努力实现的目标有可能实现吗?

注意: 上述查询存在一个已知问题,其中 0 服务器计数未正确呈现在折线图中,但这与此问题无关。我的问题特别关注查询作为多个资源的函数的可重用性。

编辑: 根据下面 Yoni 的评论,这里有几个简单的例子。

有效的一个:

let T = range x from todatetime("04/01/2020 00:00:00 AM") to now() step 1d;
T 
| where x >= ago(5d)

一个没有:

let T = range x from todatetime("04/01/2020 00:00:00 AM") to now() step 1d;
let TotalServerCount = (T:(x:datetime), v:datetime) {
  T | where x >= v 
};
TotalServerCount(T, ago(5d))

可以查看上面例子执行失败here.

失败的请求 ID: 9d8649f4-58e3-4ade-a698-ee0856961ac0

Body of the callable expression cannot be empty 是当可调用表达式的主体为空时返回的错误消息。例如在这个例子中:

let F = (a:string) { }; // <-- there's nothing in the curly braces
F("hello world")

您能否提供一个相关但最小的查询示例,该示例既可运行(不需要访问您的 cluster/database),但结果会出现您所看到的错误,并且您不明白为什么?

例如

let T = datatable(a:string)
[
    "hello", "world", "foo", "bar", "3"
]
;
let F = (T:(a:string), x:string) 
{
    T
    | project a = tolong(a)
    | where isnotnull(a)
    | join (range y from 1 to 4 step 1)
      on $left.a == $right.y
}
;
F(T, 3)

显然这是 Azure 门户本身的一个 Azure 问题。

截至今天 2020 年 5 月 15 日,我在此问题中发布的相同代码在 Application Insights 上运行良好,Microsoft 支持部门仍在调查原始问题。

我可以放心地猜测 azure 门户中存在共享功能的错误,因为在最新版本的门户中,相同的代码现在可以使用,而且我以前保存的查询功能已从我的帐户中删除自动神奇地。

鉴于这现在可​​以正常工作,从我的角度来看没有任何变化,我将回答我自己的问题并将其标记为已关闭。