Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Интеграция Vector с ClickHouse

Партнерская интеграция

Возможность анализировать журналы в реальном времени критически важна для приложений в продакшне. ClickHouse отлично подходит для хранения и анализа данных журналов благодаря превосходному сжатию (до 170x для журналов) и способности быстро агрегировать большие объёмы данных.

В этом руководстве показано, как использовать популярный конвейер данных Vector для отслеживания файла журнала Nginx и отправки данных в ClickHouse. Приведённые ниже шаги аналогичны для отслеживания любого файла журнала.

Предварительные требования:

  • У вас уже есть работающий ClickHouse
  • У вас установлен Vector

Создайте базу данных и таблицу

Создайте таблицу для хранения событий журнала:

  1. Начните с создания новой базы данных nginxdb:
CREATE DATABASE IF NOT EXISTS nginxdb
  1. Вставьте всё событие лога как одну строку. Очевидно, это не лучший формат для анализа логов, но ниже мы решим эту проблему с помощью materialized views.
CREATE TABLE IF NOT EXISTS  nginxdb.access_logs (
  message String
)
ENGINE = MergeTree()
ORDER BY tuple()

Настройка Nginx

На этом шаге показано, как настроить ведение журналов в Nginx.

  1. Следующее свойство access_log направляет журнал в /var/log/nginx/my_access.log в формате combined. Это значение нужно указать в разделе http файла nginx.conf:
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  access_log  /var/log/nginx/my_access.log combined;
  sendfile        on;
  keepalive_timeout  65;
  include /etc/nginx/conf.d/*.conf;
}
  1. Обязательно перезапустите Nginx, если вам пришлось изменить nginx.conf.

  2. Откройте страницы на вашем веб-сервере, чтобы сгенерировать несколько событий в журнале доступа. Записи журнала в формате combined выглядят следующим образом:

192.168.208.1 - - [12/Oct/2021:03:31:44 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
192.168.208.1 - - [12/Oct/2021:03:31:44 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"
192.168.208.1 - - [12/Oct/2021:03:31:49 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"

Настройка Vector

Vector собирает, преобразует и маршрутизирует журналы, метрики и трассировки (так называемые источники) в различные системы назначения (так называемые приемники), включая встроенную совместимость с ClickHouse. Источники и приемники задаются в файле конфигурации vector.toml.

  1. Следующий файл vector.toml определяет источник типа file, который читает новые записи с конца файла my_access.log, а также приемник — таблицу access_logs, определенную выше:
[sources.nginx_logs]
type = "file"
include = [ "/var/log/nginx/my_access.log" ]
read_from = "end"

[sinks.clickhouse]
type = "clickhouse"
inputs = ["nginx_logs"]
endpoint = "http://clickhouse-server:8123"
database = "nginxdb"
table = "access_logs"
skip_unknown_fields = true
  1. Запустите Vector, используя приведённую выше конфигурацию. Подробнее о настройке источников и приёмников см. в документации Vector.

  2. Убедитесь, что журналы доступа записываются в ClickHouse, выполнив следующий запрос. В таблице должны появиться журналы доступа:

SELECT * FROM nginxdb.access_logs
Просмотр журналов ClickHouse в табличном формате

Разбор журналов

Хранить журналы в ClickHouse удобно, однако запись каждого события в виде одной строки существенно ограничивает возможности анализа данных. Далее рассмотрим, как разобрать события журнала с помощью materialized view.

Materialized view работает аналогично триггеру вставки в SQL. Когда строки данных вставляются в исходную таблицу, materialized view выполняет некоторое преобразование этих строк и вставляет результаты в целевую таблицу. Materialized view можно настроить для получения разобранного представления событий журнала в access_logs. Пример одного такого события журнала приведён ниже:

192.168.208.1 - - [12/Oct/2021:15:32:43 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"

В ClickHouse есть различные функции для разбора приведённой выше строки. Функция splitByWhitespace разбивает строку по пробельным символам и возвращает каждый токен в виде массива. Для демонстрации выполните следующую команду:

Querysql
SELECT splitByWhitespace('192.168.208.1 - - [12/Oct/2021:15:32:43 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"')
Responsetext
["192.168.208.1","-","-","[12/Oct/2021:15:32:43","+0000]","\"GET","/","HTTP/1.1\"","304","0","\"-\"","\"Mozilla/5.0","(Macintosh;","Intel","Mac","OS","X","10_15_7)","AppleWebKit/537.36","(KHTML,","like","Gecko)","Chrome/93.0.4577.63","Safari/537.36\""]

В некоторых строках есть лишние символы, а user agent (сведения о браузере) не нуждался в разборе, однако результирующий массив близок к тому, что требуется.

Аналогично splitByWhitespace, функция splitByRegexp разбивает строку на массив по регулярному выражению. Выполните следующую команду, которая возвращает две строки.

SELECT splitByRegexp('\S \d+ "([^"]*)"', '192.168.208.1 - - [12/Oct/2021:15:32:43 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"')

Обратите внимание, что вторая возвращённая строка — это user agent, успешно извлечённый из лога:

["192.168.208.1 - - [12/Oct/2021:15:32:43 +0000] \"GET / HTTP/1.1\" 30"," \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36\""]

Прежде чем рассмотреть финальную команду CREATE MATERIALIZED VIEW, ознакомимся ещё с несколькими функциями для очистки данных. Например, значение RequestMethod равно "GET и содержит лишнюю двойную кавычку. Для её удаления можно воспользоваться функцией trimBoth (alias trim):

SELECT trim(LEADING '"' FROM '"GET')

Строка времени начинается с символа [ и не имеет формата, который ClickHouse может разобрать как дату. Однако если изменить разделитель с двоеточия (:) на запятую (,), разбор выполняется корректно:

SELECT parseDateTimeBestEffort(replaceOne(trim(LEADING '[' FROM '[12/Oct/2021:15:32:43'), ':', ' '))

Теперь можно определить materialized view. Приведённое ниже определение включает POPULATE, что означает: существующие строки в access_logs будут обработаны и вставлены немедленно. Выполните следующий SQL-оператор:

CREATE MATERIALIZED VIEW nginxdb.access_logs_view
(
  RemoteAddr String,
  Client String,
  RemoteUser String,
  TimeLocal DateTime,
  RequestMethod String,
  Request String,
  HttpVersion String,
  Status Int32,
  BytesSent Int64,
  UserAgent String
)
ENGINE = MergeTree()
ORDER BY RemoteAddr
POPULATE AS
WITH
  splitByWhitespace(message) as split,
  splitByRegexp('\S \d+ "([^"]*)"', message) as referer
SELECT
  split[1] AS RemoteAddr,
  split[2] AS Client,
  split[3] AS RemoteUser,
  parseDateTimeBestEffort(replaceOne(trim(LEADING '[' FROM split[4]), ':', ' ')) AS TimeLocal,
  trim(LEADING '"' FROM split[6]) AS RequestMethod,
  split[7] AS Request,
  trim(TRAILING '"' FROM split[8]) AS HttpVersion,
  split[9] AS Status,
  split[10] AS BytesSent,
  trim(BOTH '"' from referer[2]) AS UserAgent
FROM
  (SELECT message FROM nginxdb.access_logs)

Теперь убедитесь, что всё работает. Журналы доступа должны быть аккуратно разобраны по столбцам:

SELECT * FROM nginxdb.access_logs_view
Просмотр разобранных журналов ClickHouse в табличном формате

С помощью Vector, для которого нужны лишь простая установка и быстрая настройка, вы можете отправлять журналы с сервера Nginx в таблицу ClickHouse. С помощью materialized view можно разобрать эти журналы на столбцы для более удобной аналитики.

Navigation