Фильтры LogsQL

Полный справочник фильтров языка запросов LogsQL для поиска лог-записей.

Фильтры

LogsQL поддерживает различные фильтры для поиска лог-сообщений (см. ниже). Их можно комбинировать в произвольно сложные запросы с помощью логических фильтров.

По умолчанию фильтры применяются к полю _msg. Если фильтр должен применяться к другому полю лога, то перед фильтром нужно указать имя поля с двоеточием. Например, если фильтр по слову error должен применяться к полю log.level, используйте запрос log.level:error.

Имена полей и аргументы фильтров можно заключать в кавычки, если они содержат специальные символы, которые могут конфликтовать с синтаксисом LogsQL. LogsQL поддерживает кавычки через двойные кавычки ", одинарные кавычки ' и обратные кавычки:

"some 'field':123":i('some("value")') AND `other"value'`

Если есть сомнения, рекомендуется заключать имена полей и аргументы фильтров в кавычки.

Список фильтров LogsQL


Фильтр по времени

Хранилище логов сканирует все логи для запроса, если он не содержит фильтр по полю _time. Платформа использует различные оптимизации для ускорения запросов без фильтра _time, но такие запросы могут быть медленными, если хранилище содержит большое количество логов за длительный период. Самый простой способ оптимизировать запросы – сузить поиск с помощью фильтра по полю _time.

Например, следующий запрос возвращает логи с _time за последний час, содержащие слово error в поле _msg:

_time:1h AND error

Поддерживаются следующие форматы для фильтра _time:

  • _time:duration – соответствует логам с временными метками в диапазоне (now-duration, now], где duration может принимать значения длительности (например, 5m, 1h, 2d, 1y). Примеры:
    • _time:5m – возвращает логи за последние 5 минут
    • _time:2.5d15m42.345s – возвращает логи за последние 2,5 дня, 15 минут и 42,345 секунды
    • _time:1y – возвращает логи за последний год
  • _time:>duration – соответствует логам с временными метками старше now-duration.
  • _time:<duration – соответствует логам с временными метками новее now-duration. Эквивалентно _time:duration.
  • _time:YYYY-MM-DDZ – соответствует всем логам за определённый день по UTC. Например, _time:2023-04-25Z – логи за 25 апреля 2023 по UTC.
  • _time:YYYY-MMZ – соответствует всем логам за определённый месяц по UTC. Например, _time:2023-02Z – логи за февраль 2023 по UTC.
  • _time:YYYYZ – соответствует всем логам за определённый год по UTC. Например, _time:2023Z – логи за 2023 год по UTC.
  • _time:YYYY-MM-DDTHHZ – соответствует всем логам за определённый час по UTC. Например, _time:2023-04-25T22Z – логи за 25 апреля 2023 в 22:00 по UTC.
  • _time:YYYY-MM-DDTHH:MMZ – соответствует всем логам за определённую минуту по UTC. Например, _time:2023-04-25T22:45Z – логи за 25 апреля 2023 в 22:45 по UTC.
  • _time:YYYY-MM-DDTHH:MM:SSZ – соответствует всем логам за определённую секунду по UTC. Например, _time:2023-04-25T22:45:59Z – логи за 25 апреля 2023 в 22:45:59 по UTC.
  • _time:>min_time – соответствует логам с временными метками больше min_time.
  • _time:>=min_time – соответствует логам с временными метками больше или равными min_time.
  • _time:<max_time – соответствует логам с временными метками меньше max_time.
  • _time:<=max_time – соответствует логам с временными метками меньше или равными max_time.
  • _time:[min_time, max_time] – соответствует логам в диапазоне [min_time, max_time], включая обе границы. Например, _time:[2023-04-01Z, 2023-04-30Z] – логи за весь апрель 2023 по UTC, что эквивалентно _time:2023-04Z.
  • _time:[min_time, max_time) – соответствует логам в диапазоне [min_time, max_time), не включая max_time. Например, _time:[2023-02-01Z, 2023-03-01Z) – логи за весь февраль 2023 по UTC, что эквивалентно _time:2023-02Z.

Для всех абсолютных форматов времени можно указать смещение часового пояса, добавив суффикс +hh:mm или -hh:mm. Например, _time:2023-04-25+05:30 – все логи за 25 апреля 2023 по индийскому часовому поясу, а _time:2023-02-07:00 – все логи за февраль 2023 по калифорнийскому часовому поясу.

Если информация о часовом поясе отсутствует, используется локальный часовой пояс хоста, на котором работает хранилище логов. Например, _time:2023-10-20 – все логи за день 2023-10-20 по локальному часовому поясу сервера.

Можно указать общее смещение для выбранного временного диапазона, добавив offset после фильтра _time. Примеры:

  • _time:offset 1h – логи до now-1h.
  • _time:5m offset 1h – логи в диапазоне (now-1h5m, now-1h].
  • _time:2023-07Z offset 5h30m – логи за июль 2023 по UTC со смещением 5ч30мин.
  • _time:[2023-02-01Z, 2023-03-01Z) offset 1w – логи за неделю до диапазона [2023-02-01Z, 2023-03-01Z) по UTC.

Советы по производительности:

  • Рекомендуется указывать наименьший возможный временной диапазон при поиске, так как это уменьшает количество лог-записей, которые нужно просканировать. Например, _time:1h обычно быстрее, чем _time:5h.
  • Хотя LogsQL поддерживает произвольное количество фильтров _time:... на любом уровне логических фильтров, рекомендуется указывать один фильтр _time на верхнем уровне запроса.

См. также:


Фильтр дневного диапазона

Фильтр _time:day_range[start, end] позволяет возвращать логи за определённый временной интервал start ... end для каждого дня, где start и end имеют формат hh:mm. Например, следующий запрос соответствует логам между 08:00 и 18:00 каждый день по локальному часовому поясу сервера:

_time:day_range[08:00, 18:00)

Этот запрос включает 08:00, но исключает 18:00, т.е. последнее совпадающее время – 17:59:59.999999999. Замените [ на ( для исключения начального времени. Замените ) на ] для включения конечного времени. Например, следующий запрос соответствует логам между 08:00 и 18:00, исключая 08:00:00.000000000 и включая 18:00:

_time:day_range(08:00, 18:00]

Если временной диапазон должен применяться к часовому поясу, отличному от локального, добавьте offset <duration>. Например, следующий запрос выбирает логи между 08:00 и 18:00 в часовом поясе +0200:

_time:day_range[08:00, 18:00) offset 2h

Используйте offset 0h для фильтрации логов по заданному диапазону в UTC:

_time:day_range[08:00, 18:00) offset 0h

Если нужно выбрать логи вне заданного дневного диапазона, поставьте NOT или - перед фильтром day_range. Например, следующий запрос выбирает логи вне рабочих часов [08:00 - 17:00]:

-_time:day_range[08:00, 17:00]

Совет по производительности: рекомендуется дополнительно указывать обычный фильтр по времени вместе с day_range. Например, следующий запрос выбирает логи между 08:00 и 18:00 каждый день за последнюю неделю:

_time:1w _time:day_range[08:00, 18:00)

См. также:


Фильтр недельного диапазона

Фильтр _time:week_range[start, end] позволяет возвращать логи за определённые дни недели start ... end по локальному часовому поясу сервера.

Поддерживаются следующие значения для start и end:

  • Sun или Sunday
  • Mon или Monday
  • Tue или Tuesday
  • Wed или Wednesday
  • Thu или Thursday
  • Fri или Friday
  • Sat или Saturday

Например, следующий запрос соответствует логам с понедельника по пятницу по локальному часовому поясу сервера:

_time:week_range[Mon, Fri]

Этот запрос включает понедельник и пятницу. Замените [ на ( для исключения начального дня. Замените ] на ) для исключения конечного дня. Например, следующий запрос соответствует логам между воскресеньем и субботой, исключая оба дня (т.е. эквивалентен предыдущему запросу):

_time:week_range(Sun, Sat)

Если недельный диапазон должен применяться к часовому поясу, отличному от локального, добавьте offset <duration>. Например, следующий запрос выбирает логи с понедельника по пятницу в часовом поясе +0200:

_time:week_range[Mon, Fri] offset 2h

Для выбора логов по заданным дням недели в UTC используйте offset 0h:

_time:week_range[Mon, Fri] offset 0h

Фильтр week_range можно комбинировать с фильтром дневного диапазона через логические фильтры. Например, следующий запрос выбирает логи между 08:00 и 18:00 каждый рабочий день:

_time:week_range[Mon, Fri] _time:day_range[08:00, 18:00)

Если нужно выбрать логи вне заданного недельного диапазона, поставьте NOT или - перед week_range. Например, следующий запрос выбирает логи за выходные (субботу и воскресенье):

-_time:week_range[Mon, Fri]

Совет по производительности: рекомендуется дополнительно указывать обычный фильтр по времени вместе с week_range. Например, следующий запрос выбирает логи с понедельника по пятницу за последние 4 недели:

_time:4w _time:week_range[Mon, Fri]

См. также:


Фильтр потока

Proto Observability Platform предоставляет оптимизированный способ выбора логов, принадлежащих определённым потокам логов. Это можно сделать с помощью фильтра {...}, который может содержать произвольный Prometheus-совместимый селектор меток по полям, связанным с потоками логов. Предположим, что поле app является полем потока; следующий запрос выбирает лог-записи с полем app, равным nginx:

{app="nginx"}

Этот запрос эквивалентен следующему запросу с фильтром точного совпадения, но обычно работает значительно быстрее:

app:="nginx"

Фильтр потока поддерживает синтаксис {label in (v1,...,vN)} и {label not_in (v1,...,vN)}. Они эквивалентны {label=~"v1|...|vN"} и {label!~"v1|...|vN"} соответственно. Значения v1, …, vN корректно экранируются внутри регулярного выражения. Например, {app in ("nginx", "foo.bar")} эквивалентно {app=~"nginx|foo\\.bar"} – обратите внимание, что символ . корректно экранирован.

Допускается добавление префикса _stream: перед фильтром {...} для явного указания, что фильтрация выполняется по полю _stream. Следующий фильтр эквивалентен {app="nginx"}:

_stream:{app="nginx"}

Советы по производительности:

  • Рекомендуется использовать наиболее специфичный фильтр {...}, соответствующий наименьшему количеству потоков логов, которые необходимо просканировать остальными фильтрами в запросе.
  • Хотя LogsQL поддерживает произвольное количество фильтров {...} на любом уровне логических фильтров, рекомендуется указывать один фильтр {...} на верхнем уровне запроса.

См. также:


Фильтр _stream_id

Каждый поток логов в платформе уникально идентифицируется полем _stream_id. Фильтр _stream_id:... позволяет быстро выбрать все логи, принадлежащие определённому потоку.

Например, следующий запрос выбирает все логи потока с _stream_id, равным 0000007b000001c850d9950ea6196b1a4812081265faa1c7:

_stream_id:0000007b000001c850d9950ea6196b1a4812081265faa1c7

Если поток содержит слишком много логов, рекомендуется ограничить количество возвращаемых логов фильтром по времени. Например, следующий запрос выбирает логи заданного потока за последний час:

_time:1h _stream_id:0000007b000001c850d9950ea6196b1a4812081265faa1c7

Фильтр _stream_id поддерживает указание нескольких значений через синтаксис _stream_id:in(...). Например:

_stream_id:in(0000007b000001c850d9950ea6196b1a4812081265faa1c7, 1230007b456701c850d9950ea6196b1a4812081265fff2a9)

Также можно указать подзапрос внутри in(...) (подзапрос должен заканчиваться на fields _stream_id или uniq by (_stream_id)), который выбирает нужные значения _stream_id. Например, следующий запрос возвращает логи потоков, содержащих слово error в поле _msg за последние 5 минут:

_stream_id:in(_time:5m error | fields _stream_id)

См. также:


Фильтр по слову

Простейший запрос LogsQL состоит из одного слова для поиска в лог-сообщениях. Например, следующий запрос соответствует лог-сообщениям, содержащим слово error:

error

Этот запрос соответствует следующим лог-сообщениям:

  • error
  • an error happened
  • error: cannot open file

Этот запрос не соответствует следующим лог-сообщениям:

По умолчанию заданное слово ищется в поле _msg. Укажите имя поля перед словом с двоеточием, если поиск должен выполняться в другом поле. Например, следующий запрос возвращает лог-записи, содержащие слово error в поле log.level:

log.level:error

Как имя поля, так и слово в запросе могут содержать буквы и цифры в кодировке UTF-8. Например:

სფერო:τιμή

Заключите имя поля и/или слово в кавычки, если они содержат другие символы (например, :), которые могут конфликтовать с синтаксисом запроса. Например, следующий запрос ищет IP 1.2.3.45 в поле ip:remote:

"ip:remote":"1.2.3.45"

См. также:


Фильтр по фразе

Если нужно искать лог-сообщения с определённой фразой, просто заключите фразу в кавычки. Фраза может содержать любые символы, включая пробелы, знаки пунктуации, скобки и т.д. – все они учитываются при поиске. Например, следующий запрос соответствует лог-сообщениям, содержащим фразу ssh: login fail:

"ssh: login fail"

Этот запрос соответствует следующим лог-сообщениям:

  • ERROR: ssh: login fail for user "foobar"
  • ssh: login fail!

Этот запрос не соответствует следующим лог-сообщениям:

  • ssh login fail, так как в сообщении отсутствует символ : после ssh. Используйте запрос seq("ssh", "login", "fail"), если нужно найти сообщения с последовательностью этих слов. См. фильтр последовательности.
  • login fail: ssh error, так как сообщение не содержит полную запрошенную фразу. Если нужно найти сообщение со всеми перечисленными словами, используйте ssh AND login AND fail. См. логический фильтр.
  • ssh: login failed, так как сообщение заканчивается словом failed вместо fail. Используйте запрос "ssh: login fail"* в этом случае. См. фильтр по префиксу.
  • SSH: login fail, так как слово SSH написано заглавными буквами. Используйте i("ssh: login fail") для регистронезависимого поиска. См. регистронезависимый фильтр.

Если фраза содержит двойные кавычки, поставьте \ перед двойными кавычками или заключите фразу в одинарные кавычки. Например, следующий фильтр ищет логи с фразой "foo":"bar":

'"foo":"bar"'

По умолчанию фраза ищется в поле _msg. Укажите имя поля перед фразой с двоеточием, если поиск должен выполняться в другом поле. Например, следующий запрос возвращает лог-записи, содержащие фразу cannot open file в поле event.original:

event.original:"cannot open file"

Как имя поля, так и фраза могут содержать произвольные символы в кодировке UTF-8. Например:

შეტყობინება:"Το αρχείο δεν μπορεί να ανοίξει"

Имя поля можно заключить в кавычки, если оно содержит специальные символы. Например, следующий запрос ищет фразу cannot open file в поле some:message:

"some:message":"cannot open file"

См. также:


Фильтр по префиксу

Если нужно искать лог-сообщения со словами или фразами, содержащими определённый префикс, добавьте символ * в конце слова или фразы. Например, следующий запрос возвращает лог-сообщения, содержащие слова с префиксом err:

err*

Этот запрос соответствует следующим лог-сообщениям:

  • err: foobar
  • cannot open file: error occurred

Этот запрос не соответствует следующим лог-сообщениям:

Фильтр по префиксу можно применять к фразам, заключённым в кавычки. Например, следующий запрос соответствует лог-сообщениям, содержащим фразы с префиксом unexpected fail:

"unexpected fail"*

Этот запрос соответствует следующим лог-сообщениям:

  • unexpected fail: IO error
  • error:unexpected failure

Этот запрос не соответствует следующим лог-сообщениям:

  • unexpectedly failed, так как unexpectedly не совпадает со словом unexpected. Используйте unexpected* AND fail* в этом случае. См. логический фильтр.
  • failed to open file: unexpected EOF, так как слово failed стоит перед словом unexpected. Используйте unexpected AND fail* в этом случае. См. логический фильтр.

Если префикс содержит двойные кавычки, поставьте \ перед ними или заключите префикс в одинарные кавычки. Например, следующий фильтр ищет логи с префиксом "foo":"bar:

'"foo":"bar'*

По умолчанию фильтр по префиксу применяется к полю _msg. Укажите имя поля перед фильтром для применения к другому полю. Например, следующий запрос соответствует полю log.level, содержащему слово с префиксом err:

log.level:err*

Если имя поля содержит специальные символы, его можно заключить в кавычки. Например, следующий запрос соответствует полю log:level, содержащему слово с префиксом err:

"log:level":err*

Советы по производительности:

См. также:


Фильтр по паттерну

Платформа поддерживает фильтрацию логов по паттернам с помощью следующих фильтров:

  • pattern_match("pattern") – соответствует заданному паттерну в любой части поля _msg
  • pattern_match_full("pattern") – соответствует заданному паттерну для всего значения поля _msg
  • pattern_match_prefix("pattern") – соответствует заданному паттерну в начале поля _msg
  • pattern_match_suffix("pattern") – соответствует заданному паттерну в конце поля _msg

Эти фильтры можно применять к любому полю лога с синтаксисом log_field:pattern_match("pattern").

Паттерн ("pattern") должен содержать текст для сопоставления, а также произвольное количество следующих плейсхолдеров:

  • <N> – соответствует целому числу. Также соответствует шестнадцатеричным числам длиной от 4 символов с чётной длиной. Например, соответствует 123 и 12abcdEF. Для сопоставления числа с плавающей точкой целиком (например, 123.456) используйте паттерн <N>.<N>.
  • <UUID> – соответствует любому UUID, например 2edfed59-3e98-4073-bbb2-28d321ca71a7.
  • <IP4> – соответствует IPv4-адресу, например 123.45.67.89. Используйте <IP4>/<N> для сопоставления IPv4-масок.
  • <TIME> – соответствует строкам времени, например 10:20:30. Также захватывает дробные секунды: 10:20:30.123 и 10:20:30,123.
  • <DATE> – соответствует строкам даты, например 2025-10-20 и 2025/10/20.
  • <DATETIME> – соответствует строкам даты и времени, например 2025-10-20T08:09:11 и 2025-10-20 08:09:11. Также захватывает дробные секунды и часовые пояса.
  • <W> – соответствует любому слову или любой строке в кавычках (одинарных, двойных или обратных).

Например, следующий фильтр соответствует полю _msg с содержимым вида <произвольный_префикс>user_id=123, ip=45.67.89.12, time=2025-10-20T23:32:12Z<произвольный_суффикс>:

pattern_match("user_id=<N>, ip=<IP4>, time=<DATETIME>")

См. также:


Фильтр по подстроке

Если нужно найти логи с определённой подстрокой, можно использовать фильтр *подстрока*. Подстроку можно заключить в кавычки при необходимости. Например, следующий запрос соответствует лог-записям, содержащим текст ampl в поле _msg:

*ampl*

Соответствует следующим сообщениям:

  • Example message
  • This is a sample

Не соответствует EXAMPLE message, так как подстрока AMPL написана в верхнем регистре. Используйте фильтр регулярных выражений ~"(?i)ampl" в этом случае. Обратите внимание, что регистронезависимый фильтр может быть значительно медленнее.

Совет по производительности: предпочитайте фильтр по слову и фильтр по фразе, так как фильтр по подстроке может быть довольно медленным.

См. также:


Фильтр сравнения диапазона

LogsQL поддерживает фильтры field:>X, field:>=X, field:<X и field:<=X, где field – имя поля лога, а X – числовое значение, IPv4-адрес или строка. Например, следующий запрос возвращает логи с числовыми значениями поля response_size, превышающими 10*1024:

response_size:>10KiB

Следующий запрос возвращает логи с полем username, содержащим строковые значения меньше John:

username:<"John"

См. также:


Фильтр пустого значения

Иногда нужно найти лог-записи без определённого поля. Это можно сделать с помощью синтаксиса log_field:"". Например, следующий запрос соответствует лог-записям без поля host.hostname (платформа рассматривает пустые значения как несуществующие):

host.hostname:""

См. также:


Фильтр любого значения

Иногда нужно найти лог-записи с любым непустым значением заданного поля. Это можно сделать с помощью синтаксиса log_field:*. Например, следующий запрос соответствует лог-записям с непустым полем host.hostname:

host.hostname:*

См. также:


No-op фильтр

Иногда нужно применить фильтр-заглушку к заданному полю лога, который ничего не делает, т.е. соответствует всем логам, даже если они не содержат данное поле.

Поддерживаются следующие варианты no-op фильтра:

См. также:


Фильтр точного совпадения

Фильтр по слову и фильтр по фразе возвращают лог-сообщения, которые содержат заданное слово или фразу внутри себя. Сообщение может содержать дополнительный текст помимо запрошенного слова или фразы. Если нужно искать лог-сообщения или поля с точным значением, используйте фильтр exact (синтаксис =). Например, следующий запрос возвращает лог-сообщения с точным значением fatal error: cannot find /foo/bar:

="fatal error: cannot find /foo/bar"

Запрос не соответствует следующим лог-сообщениям:

  • fatal error: cannot find /foo/bar/baz или some-text fatal error: cannot find /foo/bar, так как они содержат дополнительный текст. Используйте запрос "fatal error: cannot find /foo/bar" в этом случае. См. фильтр по фразе.
  • FATAL ERROR: cannot find /foo/bar, так как фильтр точного совпадения регистрозависим. Используйте i("fatal error: cannot find /foo/bar") в этом случае. См. регистронезависимый фильтр.

По умолчанию фильтр точного совпадения применяется к полю _msg. Укажите имя поля перед фильтром с двоеточием для применения к другому полю. Например, следующий запрос возвращает лог-записи с точным значением error в поле log.level:

log.level:="error"

Как имя поля, так и фраза могут содержать произвольные символы UTF-8. Например:

log.დონე:="შეცდომა"

Имя поля можно заключить в кавычки, если оно содержит специальные символы. Например, следующий запрос соответствует значению error в поле log:level:

"log:level":="error"

См. также:


Фильтр точного префикса

Иногда нужно найти лог-сообщения, начинающиеся с определённого префикса. Это можно сделать с помощью фильтра ="prefix"*. Например, следующий запрос соответствует лог-сообщениям, начинающимся с префикса Processing request:

="Processing request"*

Этот фильтр соответствует следующим лог-сообщениям:

  • Processing request foobar
  • Processing requests from ...

Не соответствует следующим лог-сообщениям:

  • processing request foobar, так как сообщение начинается со строчной буквы p. Используйте ="processing request"* OR ="Processing request"* в этом случае. См. логический фильтр.
  • start: Processing request, так как сообщение не начинается с Processing request. Используйте "Processing request" в этом случае. См. фильтр по фразе.

По умолчанию фильтр точного префикса применяется к полю _msg. Укажите имя поля перед фильтром для применения к другому полю. Например, следующий запрос возвращает лог-записи с полем log.level, начинающимся с префикса err:

log.level:="err"*

Как имя поля, так и фраза могут содержать произвольные символы UTF-8. Например:

log.დონე:="შეცდომა"*

Имя поля можно заключить в кавычки, если оно содержит специальные символы. Например, следующий запрос соответствует значениям log:level, начинающимся с префикса err:

"log:level":="err"*

См. также:


Мульти-фильтр точного совпадения

Иногда нужно найти лог-сообщения, в которых поле содержит одно из заданных значений. Это можно сделать с помощью нескольких фильтров точного совпадения, объединённых в один логический фильтр. Например, следующий запрос соответствует лог-сообщениям с полем log.level, содержащим точные значения error или fatal:

log.level:(="error" OR ="fatal")

Хотя это решение работает нормально, LogsQL предоставляет более простое и быстрое решение – фильтр in():

log.level:in("error", "fatal")

Он работает очень быстро для длинных списков, переданных в in().

Существует специальный случай – in(*) – этот фильтр соответствует всем логам. См. no-op фильтр.

Также можно передать произвольный запрос внутри фильтра in(...) для сопоставления с результатами этого запроса. См. фильтр подзапроса.

См. также:


Фильтр contains_all

Если нужно найти логи, содержащие все заданные слова или фразы, можно использовать логический фильтр v1 AND v2 ... AND vN. Платформа предоставляет альтернативный подход с фильтром contains_all(v1, v2, ..., vN). Например, следующий запрос соответствует логам, содержащим как слово foo, так и фразу "bar baz" в поле _msg:

contains_all(foo, "bar baz")

Это эквивалентно следующему запросу:

foo AND "bar baz"

Существует специальный случай – contains_all(*) – этот фильтр соответствует всем логам. См. no-op фильтр.

Также можно передать произвольный запрос внутри contains_all(...) для сопоставления с результатами этого запроса. См. фильтр подзапроса.

См. также:


Фильтр contains_any

Иногда нужно найти логи, содержащие хотя бы одно слово или фразу из многих. Это можно сделать с помощью логического фильтра v1 OR v2 OR ... OR vN. Платформа предоставляет альтернативный подход с фильтром contains_any(v1, v2, ..., vN). Например, следующий запрос соответствует логам, содержащим слово foo или фразу "bar baz" в поле _msg:

contains_any(foo, "bar baz")

Это эквивалентно следующему запросу:

foo OR "bar baz"

Существует специальный случай – contains_any(*) – этот фильтр соответствует всем логам. См. no-op фильтр.

Также можно передать произвольный запрос внутри contains_any(...) для сопоставления с результатами этого запроса. См. фильтр подзапроса.

См. также:


Фильтр подзапроса

Иногда нужно выбрать логи с полями, значения которых совпадают со значениями, выбранными другим запросом (подзапросом). LogsQL предоставляет такую возможность с помощью следующих фильтров:

  • field:in(<подзапрос>) – возвращает логи со значениями field, совпадающими с уникальными значениями, возвращёнными подзапросом. Например, следующий запрос выбирает все логи за последние 5 минут для пользователей, которые посещали страницы со словом admin в поле path за последний день:

    _time:5m AND user_id:in(_time:1d AND path:admin | fields user_id)
    
  • field:contains_all(<подзапрос>) – возвращает логи со значениями field, содержащими все слова и фразы, возвращённые подзапросом (дубликаты игнорируются). Например, следующий запрос выбирает все логи за последние 5 минут, содержащие все значения user_id из логов администраторов за последний день в поле _msg:

    _time:5m _msg:contains_all(_time:1d is_admin:true | fields user_id)
    
  • field:contains_any(<подзапрос>) – возвращает логи со значениями field, содержащими хотя бы одно слово или фразу, возвращённые подзапросом (дубликаты игнорируются). Например, следующий запрос выбирает все логи за последние 5 минут, содержащие хотя бы одно значение user_id из логов администраторов за последний день в поле _msg:

    _time:5m _msg:contains_any(_time:1d is_admin:true | fields user_id)
    

Подзапрос должен заканчиваться пайпом fields или пайпом uniq, содержащим одно имя поля, чтобы платформа могла использовать значения этого поля для сопоставления.

См. также:


Регистронезависимый фильтр

Регистронезависимый фильтр можно применить к любому слову, фразе или префиксу, обернув соответствующий фильтр по слову, фильтр по фразе или фильтр по префиксу в i(). Например, следующий запрос возвращает лог-сообщения со словом error в любом регистре:

i(error)

Запрос соответствует следующим лог-сообщениям:

  • unknown error happened
  • ERROR: cannot read file
  • Error: unknown arg
  • An ErRoR occurred

Запрос не соответствует следующим лог-сообщениям:

  • FooError, так как слово FooError имеет лишний префикс Foo. Используйте ~"(?i)error" в этом случае. См. фильтр регулярных выражений.
  • too many Errors, так как слово Errors имеет лишний суффикс s. Используйте i(error*) в этом случае.

По умолчанию фильтр i() применяется к полю _msg. Укажите имя поля перед фильтром для применения к другому полю. Например, следующий запрос соответствует полю log.level, содержащему слово error в любом регистре:

log.level:i(error)

Если имя поля содержит специальные символы, его можно заключить в кавычки. Например, следующий запрос соответствует полю log:level, содержащему слово error в любом регистре:

"log:level":i("error")

Советы по производительности:

См. также:


Фильтр equals_common_case

Фильтр field_name:equals_common_case(phrase1, ..., phraseN) ищет логи, в которых поле field_name равно следующим фразам и словам:

  • заданным фразам – phrase1, …, phraseN
  • фразам в верхнем и нижнем регистре
  • отдельным фразам, в которых каждая заглавная буква независимо заменена соответствующей строчной буквой

Например, _msg:equals_common_case("ServiceName") находит логи, в которых поле _msg равно одному из следующих слов:

  • ServiceName
  • SERVICENAME
  • servicename
  • Servicename
  • serviceName

Фильтр equals_common_case(...) обычно работает значительно быстрее, чем i(...).

Если нужно найти логи с полями, содержащими слова/фразы в типичных вариациях регистра, используйте фильтр contains_common_case.

См. также:


Фильтр contains_common_case

Фильтр field_name:contains_common_case(phrase1, ..., phraseN) ищет логи, в которых поле field_name содержит следующие фразы и слова:

  • заданные фразы – phrase1, …, phraseN
  • фразы в верхнем и нижнем регистре
  • отдельные фразы, в которых каждая заглавная буква независимо заменена соответствующей строчной буквой

Например, _msg:contains_common_case("ServiceName") находит логи, в которых поле _msg содержит хотя бы одно из следующих слов:

  • ServiceName
  • SERVICENAME
  • servicename
  • Servicename
  • serviceName

Фильтр contains_common_case(...) обычно работает значительно быстрее, чем i(...).

Если нужно найти логи с полями, равными словам/фразам в типичных вариациях регистра, используйте фильтр equals_common_case.

См. также:


Фильтр последовательности

Иногда нужно найти лог-сообщения со словами или фразами в определённом порядке. Например, если нужно найти лог-сообщения со словом error, за которым следует фраза open file, можно использовать следующий запрос LogsQL (каждое слово/фразу можно заключить в кавычки):

seq("error", "open file")

Этот запрос соответствует сообщению some error: cannot open file /foo/bar, так как фраза open file стоит после слова error. Запрос не соответствует сообщению cannot open file: error, так как фраза open file расположена перед словом error. Если нужно найти лог-сообщения, содержащие как слово error, так и фразу open file, используйте error AND "open file". См. логический фильтр.

По умолчанию фильтр seq() применяется к полю _msg. Укажите имя поля перед фильтром для применения к другому полю. Например, следующий запрос соответствует полю event.original, содержащему последовательность (error, "open file"):

event.original:seq(error, "open file")

Если имя поля содержит специальные символы, его можно заключить в кавычки. Например, следующий запрос соответствует полю event:original, содержащему последовательность (error, "open file"):

"event:original":seq(error, "open file")

См. также:


Фильтр регулярных выражений

LogsQL поддерживает фильтр регулярных выражений с синтаксисом RE2 через синтаксис ~"regex". Регулярное выражение можно заключить в любые поддерживаемые кавычки. Например, следующий запрос возвращает все лог-сообщения, содержащие подстроки err или warn:

~"err|warn"

Запрос соответствует следующим лог-сообщениям, содержащим подстроки err или warn:

  • error: cannot read data
  • 2 warnings have been raised
  • data transferring finished

Запрос не соответствует следующим лог-сообщениям:

  • ERROR: cannot open file, так как слово ERROR написано заглавными буквами. Используйте ~"(?i)(err|warn)" для регистронезависимого поиска по регулярному выражению. См. также регистронезависимый фильтр.
  • it is warmer than usual, так как сообщение не содержит подстрок err или warn.

Если регулярное выражение содержит двойные кавычки, поставьте \ перед ними или заключите выражение в одинарные кавычки. Например, следующее регулярное выражение ищет логи, соответствующие "foo":"(bar|baz)":

~'"foo":"(bar|baz)"'

Если регулярное выражение заключено в двойные или одинарные кавычки, символ \ внутри должен быть записан как \\. Например, следующий запрос ищет логи с подстрокой a.b:

~"a\\.b"

Для поиска подстроки рекомендуется использовать фильтр по подстроке.

По умолчанию фильтр регулярных выражений применяется к полю _msg. Укажите имя поля перед фильтром для применения к другому полю. Например, следующий запрос соответствует полю event.original, содержащему подстроки err или warn:

event.original:~"err|warn"

Если имя поля содержит специальные символы, его можно заключить в кавычки. Например, следующий запрос соответствует полю event:original, содержащему подстроки err или warn:

"event:original":~"err|warn"

Советы по производительности:

  • Предпочитайте комбинирование простых фильтров по слову с логическим фильтром вместо использования фильтра регулярных выражений. Например, запрос ~"error|warning" можно заменить на error OR warning, который обычно работает значительно быстрее. Обратите внимание, что ~"error|warning" соответствует также словам errors и warnings, тогда как error OR warning соответствует только указанным словам. См. также мульти-фильтр точного совпадения.
  • Предпочитайте перемещение фильтра регулярных выражений в конец логического фильтра, чтобы более лёгкие фильтры выполнялись первыми.
  • Предпочитайте ="some prefix"* вместо ~"^some prefix", так как фильтр точного префикса работает значительно быстрее, чем фильтр регулярных выражений.

См. также:


Фильтр числового диапазона

Если нужно фильтровать лог-сообщения по полю, содержащему только числовые значения, можно использовать фильтр range(). Например, если поле request.duration содержит длительность запроса в секундах, следующий запрос LogsQL можно использовать для поиска лог-записей с длительностью запроса, превышающей 4,2 секунды:

request.duration:range(4.2, Inf)

Этот запрос можно сократить с помощью фильтра сравнения диапазона:

request.duration:>4.2

Нижняя и верхняя границы range(lower, upper) по умолчанию исключаются. Если их нужно включить, замените соответствующие круглые скобки квадратными. Например:

  • range[1, 10) – включает 1 в диапазон сопоставления
  • range(1, 10] – включает 10 в диапазон сопоставления
  • range[1, 10] – включает 1 и 10 в диапазон сопоставления

Обратите внимание, что фильтр range() не соответствует значениям, содержащим нечисловые символы. Например, range(1, 10) не соответствует лог-сообщению the request took 4.2 seconds, так как число 4.2 окружено другим текстом. Извлеките числовое значение из сообщения с помощью пайпа extract и затем примените фильтр range() к извлечённому полю.

Советы по производительности:

  • Лучше выполнять запросы к чисто числовым полям, а не извлекать числовые значения из текстовых полей во время запроса.

См. также:


Фильтр IPv4 диапазона

Если нужно фильтровать лог-сообщения по полю, содержащему только IPv4-адреса (например, 1.2.3.4), можно использовать фильтр ipv4_range(). Например, следующий запрос соответствует лог-записям с адресом user.ip в диапазоне [127.0.0.0 - 127.255.255.255]:

user.ip:ipv4_range('127.0.0.0', '127.255.255.255')

Фильтр ipv4_range() также принимает IPv4-подсети в нотации CIDR. Например, следующий запрос эквивалентен предыдущему:

user.ip:ipv4_range("127.0.0.0/8")

Для сопоставления одного IPv4-адреса просто укажите его внутри ipv4_range(). Например, следующий запрос соответствует IP-адресу 1.2.3.4 в поле user.ip:

user.ip:ipv4_range("1.2.3.4")

Обратите внимание, что ipv4_range() не соответствует строке с IPv4-адресом, если строка содержит другой текст. Например, ipv4_range("127.0.0.0/24") не соответствует лог-сообщению request from 127.0.0.1: done, так как IP-адрес 127.0.0.1 окружён другим текстом. Извлеките IP из сообщения с помощью пайпа extract и затем примените ipv4_range() к извлечённому полю.

Подсказки:

  • Если нужно искать лог-сообщения, содержащие заданный IPv4-адрес X.Y.Z.Q, можно использовать запрос "X.Y.Z.Q". См. фильтр по фразе.
  • Если нужно искать лог-сообщения, содержащие хотя бы один IPv4-адрес из заданного списка, можно использовать запрос "ip1" OR "ip2" ... OR "ipN". См. логический фильтр.
  • Если нужно найти лог-записи с полем ip в нескольких диапазонах, используйте ip:(ipv4_range(range1) OR ipv4_range(range2) ... OR ipv4_range(rangeN)). См. логический фильтр.

Советы по производительности:

  • Лучше выполнять запросы к чисто IPv4-полям, а не извлекать IPv4 из текстовых полей во время запроса.

См. также:


Фильтр IPv6 диапазона

Фильтр ipv6_range() работает аналогично фильтру ipv4_range(), но для IPv6-адресов.

Например, следующий запрос соответствует лог-записям с адресом user.ipv6 в диапазоне [2001:db8:: - 2001:db8::ffff]:

user.ipv6:ipv6_range('2001:db8::', '2001:db8::ffff')

Фильтр ipv6_range() также принимает IPv6-подсети в нотации CIDR. Например, следующий запрос эквивалентен предыдущему:

user.ipv6:ipv6_range("2001:db8::/112")

Для сопоставления одного IPv6-адреса просто укажите его внутри ipv6_range(). Например, следующий запрос соответствует адресу 2001:db8::1 в поле user.ipv6:

user.ipv6:ipv6_range("2001:db8::1")

Как и в случае с ipv4_range(), фильтр ipv6_range() не соответствует IPv6-адресу, встроенному в более длинную строку (например, с портом или окружающим текстом). В таких случаях сначала извлеките IPv6-адрес в отдельное поле (например, с помощью пайпа extract) и затем примените ipv6_range() к этому полю.

Подсказки:

  • Если нужно искать лог-сообщения, содержащие заданный IPv6-адрес в тексте, используйте фильтр по фразе, например "2001:db8::1".
  • Если нужно искать лог-сообщения, содержащие хотя бы один IPv6-адрес из заданного списка, используйте "ip1" OR "ip2" ... OR "ipN".
  • Если нужно найти лог-записи с полем ip в нескольких IPv6-диапазонах, используйте ip:(ipv6_range(range1) OR ipv6_range(range2) ... OR ipv6_range(rangeN)).

Советы по производительности:

  • Предпочитайте записывать IPv6-адреса в отдельное поле (например, user.ipv6), а не встраивать их в произвольный текст.

Фильтр строкового диапазона

Если нужно фильтровать лог-сообщения по полю со строковыми значениями в определённом диапазоне, можно использовать фильтр string_range(). Например, следующий запрос LogsQL соответствует лог-записям с полем user.name, начинающимся на буквы A и B:

user.name:string_range(A, C)

Фильтр string_range() включает нижнюю границу и исключает верхнюю. Это упрощает запросы для отдельных наборов логов. Например, user.name:string_range(C, E) будет соответствовать полям user.name, начинающимся на буквы C и D.

См. также:


Фильтр диапазона длины

Если нужно фильтровать лог-сообщения по их длине, можно использовать фильтр len_range(). Например, следующий запрос LogsQL соответствует лог-сообщениям с длиной в диапазоне [5, 10] символов:

len_range(5, 10)

Этот запрос соответствует следующим лог-сообщениям, так как их длина находится в запрошенном диапазоне:

  • foobar
  • foo bar

Этот запрос не соответствует следующим лог-сообщениям:

  • foo, так как оно слишком короткое
  • foo bar baz abc, так как оно слишком длинное

Можно использовать inf в качестве верхней границы. Например, следующий запрос соответствует лог-сообщениям с длиной 5 символов и более:

len_range(5, inf)

Границы диапазона можно выражать в следующих формах:

  • Шестнадцатеричная форма. Например, len_range(0xff, 0xABCD).
  • Двоичная форма. Например, len_range(0b100110, 0b11111101).
  • Целочисленная форма с разделителями _ для удобства чтения. Например, len_range(1_000, 2_345_678).

По умолчанию len_range() применяется к полю _msg. Укажите имя поля перед len_range() для применения фильтра к нужному полю. Например, следующий запрос соответствует лог-записям с полем foo длиной в диапазоне [10, 20] символов:

foo:len_range(10, 20)

См. также:


Фильтр типа значения

Хранилище логов автоматически определяет типы для принимаемых полей логов и сохраняет значения полей в соответствии с обнаруженным типом (например, dict, string, uint64, int64, float64, ipv4, iso8601 и др.).

Иногда нужно выбрать логи с полями определённого типа значения. В этом случае можно использовать фильтр value_type(type). Например, следующий фильтр выбирает логи, в которых значения поля user_id хранятся как тип uint64:

user_id:value_type(uint64)

См. также:


Фильтр равенства полей

Иногда нужно найти логи, содержащие одинаковые значения в заданных полях. Это можно сделать с помощью фильтра field1:eq_field(field2).

Например, следующий запрос соответствует логам с одинаковыми значениями в полях user_id и customer_id:

user_id:eq_field(customer_id)

Быстрая подсказка: используйте NOT user_id:eq_field(customer_id) для поиска логов, где user_id не равен customer_id. Используется оператор NOT логического фильтра.

См. также:


Фильтр le_field

Иногда нужно найти логи, в которых значение одного поля не превышает значение другого поля. Это можно сделать с помощью фильтра field1:le_field(field2).

Например, следующий запрос соответствует логам, в которых поле duration не превышает поле max_duration:

duration:le_field(max_duration)

Быстрая подсказка: используйте NOT duration:le_field(max_duration) для поиска логов, где duration превышает max_duration.

См. также:


Фильтр lt_field

Иногда нужно найти логи, в которых значение одного поля строго меньше значения другого поля. Это можно сделать с помощью фильтра field1:lt_field(field2).

Например, следующий запрос соответствует логам, в которых поле duration меньше поля max_duration:

duration:lt_field(max_duration)

Быстрая подсказка: используйте NOT duration:lt_field(max_duration) для поиска логов, где duration больше или равно max_duration.

См. также:


Логический фильтр

Базовые фильтры LogsQL можно комбинировать в более сложные фильтры с помощью следующих логических операций:

  • q1 AND q2 – соответствует лог-записям, которые возвращаются обоими фильтрами q1 и q2. Произвольное количество фильтров можно объединять операцией AND. Например, error AND file AND app соответствует лог-сообщениям, одновременно содержащим слова error, file и app. Операция AND часто используется в запросах LogsQL, поэтому допускается опускать слово AND. Например, error file app эквивалентно error AND file AND app. См. также фильтр contains_all.

  • q1 OR q2 – объединяет лог-записи, возвращаемые обоими фильтрами q1 и q2. Произвольное количество фильтров можно объединять операцией OR. Например, error OR warning OR info соответствует лог-сообщениям, содержащим хотя бы одно из слов error, warning или info. См. также фильтр contains_any.

  • NOT q – возвращает все лог-записи, кроме тех, которые соответствуют q. Например, NOT info возвращает все лог-сообщения, не содержащие слово info. Операция NOT часто используется в запросах LogsQL, поэтому допускается замена NOT на - и !. Например, -info и !info эквивалентны NOT info. Символ ! следует использовать вместо - перед фильтрами = и ~, например != и !~.

Приоритет операций:

Операция NOT имеет наивысший приоритет, AND – средний, а OR – наименьший. Порядок приоритета можно изменить с помощью скобок. Например, NOT info OR debug интерпретируется как (NOT info) OR debug, т.е. соответствует лог-сообщениям, не содержащим слово info, а также сообщениям со словом debug (которые могут содержать слово info). Это не то, чего ожидает большинство пользователей. В этом случае запрос можно переписать как NOT (info OR debug), который корректно возвращает лог-сообщения без слов info и debug.

LogsQL поддерживает произвольно сложные логические запросы с произвольным сочетанием операций AND, OR и NOT и скобок.

По умолчанию логические фильтры применяются к полю _msg, если внутренние фильтры явно не указывают нужное поле через синтаксис field_name:filter. Например, (error OR warn) AND host.hostname:host123 интерпретируется как (_msg:error OR _msg:warn) AND host.hostname:host123.

Можно указать одно поле для нескольких фильтров с помощью следующего синтаксиса:

field_name:(q1 OR q2 OR ... OR qN)

Например, log.level:error OR log.level:warning OR log.level:info можно заменить более коротким запросом: log.level:(error OR warning OR info).

Советы по производительности:

  • Платформа выполняет логические операции слева направо, поэтому рекомендуется размещать наиболее специфичные и быстрые фильтры (такие как фильтр по слову и фильтр по фразе) слева, а менее специфичные и медленные фильтры (такие как фильтр регулярных выражений и регистронезависимый фильтр) справа. Например, если нужно найти лог-сообщения со словом error, соответствующие регулярному выражению /foo/(bar|baz), с точки зрения производительности лучше использовать запрос error ~"/foo/(bar|baz)" вместо ~"/foo/(bar|baz)" error.

    Наиболее специфичный фильтр – тот, который соответствует наименьшему количеству лог-записей по сравнению с другими фильтрами.


Навигация