Afilters
Advanced filters
Поле "Расширенный фильтр" в пользовательских фильтрах предназначено для фильтрации маркеров (предупреждений) по сложным предикатам.

Предикат может использовать:
- поля маркера, его трассы, разметки и комментариев
- информацию из контекста: имя проекта, ветки, снимка и т. п.
- атрибуты снимка, включая пользовательские атрибуты, заданные при импорте
- статусы разметки
- текст и атрибуты комментариев
Формат фильтра определяется следующим шаблоном:
filter(markers, <predicate expr>)
Выражение <predicate expr> определяет предикат. Объект markers содержит массив маркеров из контекста, функция filter фильтрует данный список по предикату. Таким образом, применение фильтра заключается в фильтрации списка маркеров по указанному предикату.
Список доступных полей
Поля маркера (предупреждения)
Comments— список комментариев маркера. Объект типа Comment (смотрите ниже)Details— информация, специфичная для анализатора. Ближайший аналог — fingerprint в SARIFFile— имя файлаFunction— имя функции, может быть mangled для С++ID— UUID маркераInvariant— инвариант маркера. Используется для автопереноса разметки между снимкамиLang— язык детектораLine— номер строки в файлеLocID— порядковый номер маркера относительно изначального отчета анализатораMTid— шаблон сообщенияMsg— текст сообщенияOrigFunc— 'человекочитаемое' имя функции. Может быть недоступноTags— список тегов (меток) маркераTool— модуль анализатора, ответственного за данный детекторTraces— список трасс маркера. Объект типа Trace (смотрите ниже)WarnClass— название детектора/класса детекторов
Имена полей также могут использоваться в формате, где первая буква в lowercase.
Помимо использования полей, можно использовать вспомогательные функции для доступа к дополнительной информации:
severity(item) string— серьезность детектора (чекера)
Пример:
filter(markers, severity(#) == "Critical")
Внимание: использование в предикатах поля Trace может сказаться на скорости применения фильтра, т. к. загрузка большого числа трасс может занять время.
Данные о разметке
Поддерживаются следующие функции для получения информации о разметке:
status(item) string— статус разметки текущего маркера. Пример:filter(markers, status(#) == "Confirmed")action(item) string— статус поля action текущего маркера. Пример:filter(markers, action(#) == "Ignore")mseverity(item) string— статус поля severity текущего маркера (не путать с severity детектора). Пример:filter(markers, mseverity(#) == "Critical")triaged(item) bool— возвращает true, если маркер имеет не дефолтную разметку. Пример:filter(markers, triaged(#))get_triaged_by(item) UserInfo— возвращает структуру с информацией о пользователе, кто произвел разметку
Поля структуры UserInfo:
login: string— логин пользователяcreate_ts: Time (UTC)— время разметки в UTC формате (RFC3339)
Комментарии
Объекты типа Comment содержатся в поле Comments маркера. Объект имеет следующие поля:
ID— UUID комментарияText— текст комментарияCreatedBy— имя пользователя, кто создал комментарийCreateTs— время создания комментария (объект типаtime.Time)UpdateTs— время обновления комментария (объект типаtime.Time), может быть пустымUpdatedBy— имя пользователя, кто обновил комментарий
Трассы
Маркер может содержать трассу маркера в поле Traces. Трасса описывается следующими структурами:
type Trace struct {
Role string
Locations []TraceEntry
}
type TraceEntry struct {
File string
Line uint32
Col uint32
Info string
}
Доступ к полям объекта Trace может выполняться, используя правила языка go-expr, описанные ниже.
Имена полей могут использоваться в виде как описано выше, либо в формате lowercase: role, locations, file, line, col, info
Пример:
filter(markers, any(.Comments, .Text == "Test") && any(.Traces, any(.Locations, .Info == "Boolean expression has constant value")) )
Поля снимка
Для доступа к полям снимка можно использовать переменную snapshot. Переменная имеет тип структуры со следующими полями
struct {
ID string
Name string
SerialID uint32
BuildObject string
ResultsObject string
ImportTime time.Time
CreatedBy string
CreatedByID string
Details map[string]any
CreateTime time.Time
SourcesAvailable bool
}
Имена полей могут использоваться в виде, где первая буква в lowercase.
Объекты в поле Details можно просмотреть, нажав на кнопку View JSON в WebUI в поле Snapshot Information.
Пример:
filter(markers, snapshot.buildObject == "5b634b75422bd554a8569cc10bfadc3aea77b73e" && .warnClass matches "DEREF" )
Описание языка предикатов
Для написания предикатов используется язык Expr. Детальное описание всех возможностей можно найти здесь: https://github.com/expr-lang/expr
Далее описываются конструкции, наиболее подходящие для написания правил фильтрации.
Литералы
Comment /* */ or //
Boolean true, false
Integer 42, 0x2A, 0o52, 0b101010
Float 0.5, .5
String "foo", 'bar'
Array [1, 2, 3]
Map {a: 1, b: 2, c: 3}
Nil nil
Строки
Строки могут быть в одинарных и двойных кавычках. Для эскейпа используйте обратный слэш.
Пример однострочного текста:
"Hello\nWorld"
Пример многострочного текста:
`Hello World`
В многострочном тексте escape-последовательности не поддерживаются.
Операторы
Arithmetic: +, -, *, /, % (modulus), ^ or ** (exponent)
Comparison: ==, !=, <, >, <=, >=
Logical: not or !, and or &&, or or ||
Conditional: ?: (ternary), ?? (nil coalescing), if {} else {} (multiline)
Membership: [], ., ?., in
String: + (concatenation), contains, startsWith, endsWith
Regex: matches
Range: ..
Slice: [:]
Pipe: |
Операторы доступа к полю объекта
Можно использовать оператор . и оператор []:
user.Name user["Name"]
Оператор in
Оператор in для проверки наличия объекта в массиве или мэпе:
"John" in ["John", "Jane"]
"name" in {"name": "John", "age": 30}
Optional chaining
Оператор ?. может использоваться для доступа к полю структуры или элементу отображения (map) без необходимости проверки, является ли структура или отображение равными nil. Если структура или отображение имеют значение nil, результатом выражения будет nil.
Пример вида:
author.User?.Name
значит то же самое, что:
author.User != nil ? author.User.Name : nil
Nil coalescing
Оператор ?? может использоваться для возврата левого операнда, если он не равен nil, в противном случае возвращается правый операнд.
Пример вида:
author.User?.Name ?? "Anonymous"
значит то же самое, что:
author.User != nil ? author.User.Name : "Anonymous"
Оператор конвейера
Оператор конвейера | может использоваться для передачи результата выражения левого операнда в качестве первого аргумента выражения правого операнда.
Пример вида:
user.Name | lower() | split(" ")
значит то же самое, что:
split(lower(user.Name), " ")
Предикаты
Предикат — это выражение. Предикаты можно использовать в функциях, таких как filter, all, any, one, none и других.
filter(0..9, {# % 2 == 0})
filter(tweets, {len(.Content) > 240})
Скобки { } можно опускать:
filter(tweets, len(.Content) > 240)
Операции над строками
trim(str[, chars]) trimPrefix(str, prefix) trimSuffix(str, suffix) upper(str) lower(str) indexOf(str, substring) lastIndexOf(str, substring) hasPrefix(str, prefix) hasSuffix(str, suffix)
Также есть оператор matches для поиска регулярного выражения в строке:
str matches "regular expression"
Для сопоставления целой строки с регулярным выражением следует использовать вариант:
str matches "^regex$"
Функции времени
Поддерживаются Go типы для времени и интервалов: time.Time, time.Duration из time package.
Можно использовать операции сложения и вычитания над объектами с типом time.Time.
createdAt - now()
createdAt + duration("1h")
createdAt > now() - duration("1h")
date("2023-08-14")
date("15:04:05")
date("2023-08-14T00:00:00Z")
date("2023-08-14 00:00:00", "2006-01-02 15:04:05", "Europe/Zurich")
Функции над массивами
all(array, predicate)— все объекты должны удовлетворять предикатуany(array, predicate)— должен быть по крайней мере один объект, который удовлетворяет предикатуone(array, predicate)— должен быть только один объект, который удовлетворяет предикатуnone(array, predicate)— ни один объект не должен удовлетворять предикатуfind(array, predicate)— возвращает первый объект, который удовлетворяет предикатуfindLast(array, predicate)— возвращает последний объект, который удовлетворяет предикатуcount(array[, predicate])— возвращает число объектов, удовлетворяющих предикатуfirst(array)— первый объект из массиваlast(array)— последний объект из массива
Примеры:
all(tweets, {.Size < 280})
any(tweets, {.Size > 280})
none(tweets, {.Size > 280})
find([1, 2, 3, 4], # > 2) == 3
findLast([1, 2, 3, 4], # > 2) == 4
count(users, .Age > 18)
first([1, 2, 3]) == 1
last([1, 2, 3]) == 3