Как вы пишете табличную функцию в Kusto, используя комбинацию табличных и скалярных аргументов, чтобы вы могли повторно использовать ее и обмениваться ею в организации? - PullRequest
1 голос
/ 30 апреля 2020

Я уже несколько дней гуглю и тереблю вокруг себя и не могу найти ответ.

Я пытаюсь подсчитать количество серверов, выполняющих функцию azure за период времени в заданном интервале времени c. Я хочу, чтобы моя организация повторно использовала этот запрос как табличную функцию приложение запрашивает таблицу запросов , связанную с любым ресурсом, за которым мы наблюдаем, а также временной интервал , используемый для хранения данных, дата начала и дата окончания запроса.

В моем понимании базовая c подпись должна выглядеть следующим образом:

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

Я пробовал несколько вариантов этого и всегда получаю та же ошибка: Тело вызываемого выражения не может быть пустым

Я следовал инструкциям по следующим ссылкам:

  1. Скалярные типы данных
  2. Пользовательские функции
  3. Запросы

Вот полный код функции:

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
};

Который я бы тогда назвал в отдельном запросе окно y выглядит так:

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

В соответствии с приведенными примерами здесь :

Табличная функция:

  • Является функцией без входов или, по крайней мере, с одним табличным входом и создает табличный вывод
  • Может использоваться везде, где допускается табличное выражение

Примечание

Все табличные параметры должны появляться перед скалярными параметрами.

Пример табличной функции, которая использует табличный вход и скалярный вход:

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))

Вы можете просмотреть неудачное выполнение вышеприведенного примера здесь .

Идентификатор ошибочного запроса: 9d8649f4-58e3-4ade-a698-ee0856961ac0

1 Ответ

0 голосов
/ 30 апреля 2020

Body of the callable expression cannot be empty - это сообщение об ошибке, возвращаемой, когда тело выражения для вызова пустое. например, в этом примере:

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

Не могли бы вы, возможно, предоставить релевантный, но минимальный пример запроса, который является одновременно работоспособным (не требует доступа к вашему кластеру / базе данных), но приводит к ошибке вы видите, и вы не понимаете, почему?

например

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)
...