FileLog позволяет:
- Подписываться на файлы журнала.
- Обрабатывать новые записи по мере их добавления в отслеживаемые файлы журнала.
Создание таблицы
path_to_logs– Путь к файлам журнала, которые нужно отслеживать. Это может быть путь к каталогу с файлами журнала или к одному файлу журнала. Относительный путь разрешается относительно каталогаuser_files_path, как и в табличной функции file; если же относительный путь уже указывает внутрьuser_files_pathотносительно рабочего каталога сервера (например,user_files/my_app/app.log, когда сервер запущен в своём каталоге данных, как в официальном Docker-образе), он сохраняет прежний смысл. Имя файла в пути может содержать глоб-шаблоны (*,?,{abc,def},{N..M}), чтобы читать только подходящие файлы каталога, см. Выбор файлов с помощью глоб-шаблонов. Обратите внимание, что ClickHouse допускает только пути внутри каталогаuser_files.format_name- Формат записей. Обратите внимание, что FileLog обрабатывает каждую строку в файле как отдельную запись, поэтому не все форматы данных для этого подходят.
poll_timeout_ms- Тайм-аут одного опроса файла журнала. Значение по умолчанию: stream_poll_timeout_ms.poll_max_batch_size— Максимальное количество записей, считываемых за один опрос. Значение по умолчанию: max_block_size.max_block_size— Максимальный размер батча (в записях) для одного опроса. Значение по умолчанию: max_insert_block_size.max_threads- Максимальное количество потоков для разбора файлов; по умолчанию это 0, что означает, что количество будет равно max(1, physical_cpu_cores / 4).poll_directory_watch_events_backoff_init- Начальное время ожидания для потока наблюдения за каталогом. Значение по умолчанию:500.poll_directory_watch_events_backoff_max- Максимальное время ожидания для потока наблюдения за каталогом. Значение по умолчанию:32000.poll_directory_watch_events_backoff_factor- Скорость увеличения задержки; по умолчанию используется экспоненциальный рост. Значение по умолчанию:2.handle_error_mode— Как обрабатывать ошибки в движке FileLog. Возможные значения: default (если запись не удаётся разобрать, прямойSELECTгенерирует исключение; когда таблица передаёт данные в materialized view, такая запись пропускается, а ошибка записывается в журнал сервера), stream (сообщение об исключении и исходная запись будут сохранены в виртуальных столбцах_errorи_raw_record).
Описание
Доставленные записи отслеживаются автоматически, поэтому каждая запись в файле журнала учитывается только один раз. Если при следующем чтении файл оказывается короче сохранённого для него смещения (например, послеlogrotate с copytruncate), он читается заново с начала. Усечение не обнаруживается, если к моменту следующего чтения файл снова дорастает как минимум до этого смещения. Файл, у которого в каталоге несколько имён (жёсткие ссылки), читается под одним из них.
Файл, который не удаётся открыть (символическая ссылка, цель которой была удалена, файл, недоступный серверу для чтения, или удалённый файл таблицы, состоящей из одного файла), пропускается с записью об ошибке в журнал сервера; пока таблица загружена, попытки открыть его повторяются до тех пор, пока это не удастся. Ранее отсутствовавший файл после этого читается с начала. Символическая ссылка читается, только если её цель существует в момент, когда таблица её обнаруживает.
SELECT не слишком полезен для чтения записей (кроме отладки), потому что каждую запись можно прочитать только один раз. Гораздо практичнее создавать потоки в реальном времени с помощью materialized views. Для этого:
- Используйте движок, чтобы создать таблицу FileLog, и рассматривайте её как поток данных.
- Создайте таблицу с нужной структурой.
- Создайте materialized view, которое преобразует данные из движка и помещает их в созданную ранее таблицу.
MATERIALIZED VIEW подключается к движку, оно начинает собирать данные в фоновом режиме. Это позволяет непрерывно получать записи из файлов журнала и преобразовывать их в нужный формат с помощью SELECT.
Одна таблица FileLog может иметь сколько угодно materialized views; они не читают данные из таблицы напрямую, а получают новые записи (блоками), поэтому вы можете записывать данные в несколько таблиц с разным уровнем детализации (с группировкой — агрегацией — и без неё).
Пример:
ALTER, рекомендуем отключить materialized view, чтобы избежать расхождений между целевой таблицей и данными представления.
Выбор файлов с помощью глоб-шаблонов
Если имя файла вpath_to_logs содержит глоб-шаблоны, таблица читает файлы этого каталога с подходящими именами, в том числе файлы, появившиеся позже. Глоб-шаблоны в части пути, указывающей на каталог, не поддерживаются.
Файл, который уже читается таблицей, продолжает читаться и после переименования в имя, не подходящее под шаблон, — до тех пор, пока он не будет удалён из каталога. Файл, который был создан и переименован в неподходящее имя, пока таблица была отсоединена или сервер был остановлен, не читается. В macOS, где отслеживание изменений в каталоге выполняется путём сравнения списков его содержимого, то же касается файла, который был создан и переименован в неподходящее имя до того, как таблица получила список содержимого каталога. Именно такое поведение необходимо для ротации журналов. Например, при использовании logrotate с параметрами compress и delaycompress каталог выглядит так:
FileLog('/var/lib/clickhouse/user_files/my_app/*.log', 'JSONEachRow') читает app.log; после ротации она продолжает читать app.log.1, поэтому строки, которые приложение успевает записать туда до того, как заново откроет свой журнал, не теряются, а сжатые файлы таблица не читает никогда. Убедитесь, что глоб-шаблон не охватывает имена сжатых файлов.
Виртуальные столбцы
_filename- Имя файла журнала. Тип данных:LowCardinality(String)._offset- Смещение в файле журнала. Тип данных:UInt64.
handle_error_mode='stream':
_raw_record- Исходная запись, которую не удалось успешно разобрать. Тип данных:Nullable(String)._error- Сообщение об исключении, возникшем при неудачном разборе. Тип данных:Nullable(String).
_raw_record и _error заполняются только в случае исключения при разборе; если сообщение было успешно разобрано, они всегда имеют значение NULL.
Долговечность данных
ДвижокFileLog записывает смещение, обработанное для фрагмента, ещё до того, как будет закоммичена вставка, к которой этот фрагмент относится, поэтому при аварийной остановке сервера записанное смещение может оказаться дальше, чем данные, реально попавшие в целевую таблицу. При перезапуске чтение каждого файла журнала возобновляется с того смещения, которое сохранено в его каталоге метаданных, так что эти строки уже никогда не будут прочитаны повторно: они теряются без каких-либо ошибок, а count() просто оказывается меньше. Чтобы это проявилось, достаточно обычного сбоя процесса — потеря питания не требуется, поскольку смещение сохраняется в файле метаданных, который переименовывается на своё место в тот момент, когда целевой парт ещё пишется.
Потеря кэша страниц ОС может дополнительно уничтожить данные, уже записанные в целевую таблицу; примеры — потеря питания на уровне устройства и некорректный сброс хоста или ядра. Сами файлы метаданных, хранящие смещения, записываются без fsync — ни самого файла, ни его каталога, — поэтому и они не дают никаких гарантий долговечности.
В отличие от движков для брокеров сообщений, FileLog нельзя защитить от этого, предварительно обеспечив долговечность целевой таблицы. Поскольку смещение записывается изнутри конвейера чтения, до завершения вставки, к которой оно относится, параметр fsync_after_insert = 1 на целевых таблицах MergeTree не гарантирует, что вставленный парт станет долговечным до того, как смещение продвинется. Относитесь к чтению через FileLog как к дочитыванию локальных файлов по принципу «насколько получится»: если потеря строк недопустима, сохраняйте исходные файлы журналов до тех пор, пока обработанные данные не будут проверены в целевой таблице, чтобы чтение можно было повторить. SYSTEM RESET FILELOG, а также удаление и повторное создание таблицы сбрасывают записанные смещения и приводят к повторному чтению файлов с начала.