Afilters: Difference between revisions
(Описание advanced filters) |
|||
| Line 113: | Line 113: | ||
= Описание языка предикатов = | = Описание языка предикатов = | ||
Для написания предикатов используется язык '''Expr'''. Детальное описание всех возможностей можно найти здесь: | Для написания предикатов используется язык '''Expr'''. Детальное описание всех возможностей можно найти здесь: https://github.com/expr-lang/expr | ||
Далее описываются конструкции, наиболее подходящие для написания правил фильтрации. | Далее описываются конструкции, наиболее подходящие для написания правил фильтрации. | ||
Revision as of 12:36, 27 November 2025
Advanced filters
Поле "Расширенный фильтр" в пользовательских фильтрах предназначено для фильтрации маркеров (предупреждений) по сложным предикатам.

Предикат может использовать:
- поля маркера, его трассы, разметки и комментариев
- информацию из контекста (имя проекта, ветки, снимка и т.п.)
- атрибуты снимка (включая пользовательские атрибуты, заданные при импорте)
- статусы разметки
- текст и атрибуты комментариев
Формат фильтра определяется следующим шаблоном:
filter(markers, <predicate expr> )
Выражение <predicate expr> определяет предикат. Объект markers содержит массив маркеров из контекста, функция filter фильтрует данный список по предикату. Таким образом, применение фильтра заключается в фильтрации списка маркеров по указанному предикату.
Список доступных полей
Поля маркера (предупреждения)
Comments- список комментариев маркера. Объект типа Comment (смотреть ниже)Details- информация, специфичная для анализатора. Ближайший аналог - fingerprint в SARIFFile- имя файлаFunction- имя функции, может быть managled для С++ID- UUID маркераInvariant- инвариант маркера. Используется для авто-переноса разметки между снимкамиLang- язык детектораLine- номер строки в файлеLocID- порядковый номер маркера относительно изначального отчета анализатораMTid- шаблон сообщенияMsg- текст сообщенияOrigFunc- 'человекочитаемое' имя функции. Может быть недоступноTags- список тэгов(меток) маркераTool- модуль анализатора, ответственного за данный детекторTraces- список трасс маркера. Объект типа Trace (смотреть ниже)WarnClass- название детектора/класса детекторов
Имена полей могут так же использоваться в формате, где первая буква в lower-case.
Помимо использования полей, пользователь может использовать вспомогательные функции для доступа к дополнительной информации:
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, описанные ниже.
Имена полей могут использоваться в виде как описано выше, либо в формате lower-case: 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
}
Имена полей могут использоваться в виде, где первая буква в lower case.
Объекты в поле 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