Написание выражений-запросов
Серверные выражения позволяют обрабатывать данные, возвращённые запросами, с помощью математических и других операций. Выражения создают новые данные и не изменяют данные, возвращаемые источниками данных.
О выражениях
Серверные выражения позволяют обрабатывать данные, возвращённые запросами, с помощью математических и других операций. Выражения создают новые данные и не изменяют данные, возвращаемые источниками данных, за исключением небольшой реструктуризации данных, чтобы сделать их приемлемыми для выражений.
Использование выражений
Чаще всего выражения используются для Grafana Alerting. Обработка выполняется на стороне сервера, поэтому выражения могут работать без сессии браузера. Однако выражения можно также использовать с бэкенд-источниками данных и визуализацией.
Note
Выражения не работают с алертами дашборда предыдущего поколения.
Выражения предназначены для дополнения источников данных: они позволяют объединять запросы из разных источников данных или предоставлять операции, недоступные в источнике данных.
Note
Когда это возможно, обработку данных следует выполнять внутри источника данных. Копирование данных из хранилища на сервер Grafana для обработки неэффективно, поэтому выражения рассчитаны на лёгкую обработку данных.
Выражения работают с запросами к источникам данных, возвращающими временные ряды или числовые данные. Они также работают с многомерными данными. Например, с запросом, возвращающим несколько рядов, где каждый ряд идентифицируется метками или тегами.
Отдельное выражение принимает на вход один или несколько запросов или других выражений и добавляет данные к результату. Каждое отдельное выражение или запрос представлено переменной — именованным идентификатором, известным как его RefID (например, буква по умолчанию A или B).
Чтобы сослаться на вывод отдельного выражения или запроса к источнику данных в другом выражении, этот идентификатор используется как переменная.
Типы выражений
Выражения работают с двумя типами данных.
- Набор временных рядов.
- Набор чисел, где каждое число — это элемент.
Каждый набор возвращается одним запросом к источнику данных или выражением и обозначается RefID. Каждый набор — это множество, в котором каждый элемент однозначно идентифицируется своими измерениями, хранящимися как метки или пары «ключ — значение».
Запросы к источникам данных
Серверные выражения поддерживают запросы к источникам данных только для бэкенд-источников. Обычно предполагается, что данные представляют собой временные ряды с метками. В будущем мы планируем добавить проверку типа возвращаемых данных запроса (число или временной ряд), чтобы выражения лучше обрабатывали ошибки.
Запросы к источникам данных при использовании с выражениями выполняются движком выражений. При этом он реструктурирует данные так, чтобы на каждый фрейм данных приходился один временной ряд или одно число. Так, например, если используется источник данных, возвращающий несколько рядов в одном фрейме в табличном представлении, вы можете заметить, что при выполнении с выражениями данные выглядят иначе.
В настоящее время единственный формат, отличный от временных рядов (число), поддерживается, когда вы используете фреймы данных и у вас есть табличный ответ, возвращающий фрейм данных без времени, со строковыми столбцами и одним числовым столбцом:
Приведённый выше пример даст число, которое работает с выражениями. Строковые столбцы становятся метками, а числовой столбец — соответствующим значением. Например, {"Loc": "MIA", "Host": "A"} со значением 1.
Операции
В выражениях можно использовать следующие операции: math, reduce и resample.
Math
Math предназначена для произвольных математических формул над временными рядами или числовыми данными. Математические операции принимают на вход числа и временные ряды и превращают их в другие числа и временные ряды.
Данные из других запросов или выражений указываются через RefID с префиксом в виде знака доллара, например $A. Если в имени переменной есть пробелы, можно использовать синтаксис с фигурными скобками, например ${my variable}.
Числовые константы могут быть в десятичной (2.24), восьмеричной (с ведущим нулём, например 072) или шестнадцатеричной (с ведущим 0x, например 0x2A) форме. Также поддерживаются экспоненциальная запись и знаки (например, -0.8e-2).
Операторы
Поддерживаются арифметические (+, бинарный и унарный -, *, /, %, возведение в степень **), реляционные (<, >, ==, !=, >=, <=) и логические (&&, || и унарный !) операторы.
Поведение операции с данными зависит от того, являются ли они числом или временным рядом.
В бинарных операциях, таких как $A + $B или $A || $B, оператор применяется следующим образом в зависимости от типа данных:
- Если и
$A, и$B— числа, операция выполняется между двумя числами. - Если одна переменная — число, а другая — временной ряд, операция выполняется между значением каждой точки временного ряда и числом.
- Если и
$A, и$B— данные временных рядов, операция выполняется между каждым значением в двух рядах для каждой метки времени, которая есть и в$A, и в$B. Для выравнивания меток времени можно использовать операцию Resample. (Примечание: в будущем мы планируем добавить в операцию Math параметры для различного поведения).
Резюме:
- Число OP число = число
- Число OP ряд = ряд
- Ряд OP ряд = ряд
Поскольку выражения работают с несколькими рядами или числами, представленными одной переменной, бинарные операции также выполняют объединение (join) двух переменных. Это делается на основе идентифицирующих меток, связанных с каждым отдельным рядом или числом.
Так, если у вас есть числа с метками вида {host=web01} в $A и другое число в $B с такими же метками, операция выполняется между этими двумя элементами внутри каждой переменной, и результат будет иметь те же метки. Правила поведения этого объединения таковы:
- Элемент без меток объединится с чем угодно.
- Если и
$A, и$Bсодержат только по одному элементу (один ряд или одно число), они объединятся. - Если метки полностью совпадают, они объединятся.
- Если метки одного элемента являются подмножеством другого, например элемент в
$Aимеет метки{host=A,dc=MIA}, а элемент в$B— метки{host=A}, они объединятся. - В настоящее время, если внутри такой переменной, как
$A, у разных элементов разные ключи тегов, поведение объединения не определено.
Реляционные и логические операторы возвращают 0 для ложного значения и 1 для истинного.
Математические функции
Хотя большинство функций существует в собственных операциях выражений, в математической операции есть несколько функций, похожих на математические операторы или символы. Когда функция может принимать как числа, так и ряды, возвращается тот же тип, что и у аргумента. Если это ряд, операция выполняется для значения каждой точки ряда.
abs
abs возвращает абсолютное значение своего аргумента, который может быть числом или рядом. Например, abs(-1) или abs($A).
is_inf
is_inf принимает число или ряд и возвращает 1 для значений Inf (отрицательных или положительных) и 0 для остальных значений. Например, is_inf($A).
Note
Если вам нужно специально проверить отрицательную бесконечность, можно выполнить сравнение вида
$A == infn().
is_nan
is_nan принимает число или ряд и возвращает 1 для значений NaN и 0 для остальных значений. Например, is_nan($A). Эта функция существует потому, что NaN не равен NaN.
is_null
is_null принимает число или ряд и возвращает 1 для значений null и 0 для остальных значений. Например, is_null($A).
is_number
is_number принимает число или ряд и возвращает 1 для всех значений действительных чисел и 0 для остальных значений (то есть null, Inf+, Inf- и NaN). Например, is_number($A).
log
log возвращает натуральный логарифм своего аргумента, который может быть числом или рядом. Если значение меньше 0, возвращается NaN. Например, log(-1) или log($A).
inf, infn, nan, and null
Функции inf, infn, nan и null возвращают единственное значение с соответствующим именем. В основном они существуют для тестирования. Пример: null().
round
Round возвращает округлённое целочисленное значение. Например, round(3.123) или round($A). (Эта функция, вероятно, должна принимать аргумент, чтобы можно было задать точность округляемого значения).
ceil
Ceil округляет число вверх до ближайшего целочисленного значения. Например, ceil(3.123) возвращает 4.
floor
Floor округляет число вниз до ближайшего целочисленного значения. Например, floor(3.123) возвращает 3.
Reduce
Reduce принимает один или несколько временных рядов, возвращённых запросом или выражением, и превращает каждый ряд в одно число. Метки временного ряда сохраняются как метки для каждого выходного сокращённого числа.
Поля:
- Function - используемая функция сокращения
- Input - переменная (refID, например
A) для пересэмплирования - Mode - позволяет управлять поведением функции сокращения, когда ряд содержит нечисловые значения (null, NaN, +-Inf)
Функции сокращения
Count
Count возвращает количество точек в каждом ряду.
Mean
Mean возвращает сумму всех значений в каждом ряду, делённую на количество точек в этом ряду. В режиме strict, если какие-либо значения в ряду равны null или nan, или если ряд пуст, возвращается NaN.
Min and Max
Min и Max возвращают соответственно наименьшее или наибольшее значение в ряду. В режиме strict, если какие-либо значения в ряду равны null или nan, или если ряд пуст, возвращается NaN.
Sum
Sum возвращает сумму всех значений в ряду. Если ряд имеет нулевую длину, сумма будет равна 0. В режиме strict, если в ряду есть значения NaN или Null, возвращается NaN.
Last
Last возвращает последнее число в ряду. Если в ряду нет значений, возвращается NaN.
Режимы сокращения
Strict
В режиме Strict входной ряд обрабатывается как есть. Если какие-либо значения в ряду нечисловые (null, NaN или +-Inf), возвращается NaN.
Drop Non-Numeric
В этом режиме все нечисловые значения (null, NaN или +-Inf) во входном ряду отфильтровываются перед выполнением функции сокращения.
Replace Non-Numeric
В этом режиме все нечисловые значения заменяются заданным значением.
Resample
Resample изменяет метки времени в каждом временном ряду, чтобы обеспечить согласованный временной интервал. Основной сценарий использования — пересэмплировать временные ряды, которые не имеют одинаковых меток времени, чтобы между ними можно было выполнять математические операции. Это можно сделать, пересэмплировав каждый из двух рядов, а затем выполнив математическую операцию со ссылкой на пересэмплированные переменные.
Поля:
- Input - переменная с данными временных рядов (refID, например
A) для пересэмплирования - Resample to - длительность интервала пересэмплирования, например
10s. Единицы измерения:s— секунды,m— минуты,h— часы,d— дни,w— недели,y— годы. - Downsample - функция сокращения, используемая, когда на одно окно выборки приходится более одной точки данных. Подробности поведения см. в описании операции сокращения.
- Upsample - метод заполнения окна выборки, в котором нет точек данных.
- pad заполняет последним известным значением
- backfill — следующим известным значением
- fillna заполняет пустые окна выборки значениями NaN
Написание выражения
Note
Шаги в этом разделе описывают классический, общедоступный редактор запросов панели. Сведения о новом интерфейсе редактора запросов панели, который сейчас находится в статусе публичного предварительного просмотра, см. в документации по запросам и преобразованию данных.
Если ваш источник данных поддерживает выражения, Grafana отображает кнопку Expression и показывает существующие выражения в списке редактора запросов.
Подробнее о выражениях см. в разделе О выражениях.
-
Откройте панель.
-
Под запросом нажмите Expression.
-
В поле Operation выберите тип выражения, которое хотите написать.
Подробнее об операциях выражений см. в разделе О выражениях.
-
Напишите выражение.
-
Нажмите Apply.
Особые случаи
Когда любой из опрашиваемых источников данных не возвращает ни рядов, ни чисел, движок выражений возвращает NoData. Например, если запрос содержит два запроса к источникам данных, объединяемых выражением, и хотя бы один из запросов к источникам данных вернул NoData, то возвращаемый результат всего запроса — NoData.
Подробнее о том, как
Grafana Alerting обрабатывает результаты NoData, см. в разделе
Обработка отсутствия данных и ошибок.
При использовании выражения для нескольких запросов движок выражений требует, чтобы все запросы возвращали идентичную метку времени. Например, если с помощью математики объединяются результаты нескольких SQL-запросов, каждый из которых использует SELECT NOW() AS "time", выражение сработает только если все запросы вычислят NOW() в одну и ту же метку времени, что происходит не всегда. Чтобы решить эту проблему, можно заменить NOW() на произвольное время, например SELECT 1 AS "time", или на любую другую допустимую метку времени UNIX.