В предыдущих частях я разобрал, когда гонять нагрузку, как поставить k6 и как собирать сценарии. Теперь — про то, куда складывать результаты, чтобы они не терялись в терминале, и как смотреть на них так, чтобы видеть картину, а не цифры.
Мои первые прогоны заканчивались тем, что я копировал вывод k6 из терминала в заметки. Потом хотел сравнить с прогоном недельной давности — а где тот вывод? Потерялся. Потом стал писать в CSV, но открывать их в Excel и строить графики руками — тоска. Так я пришёл к связке InfluxDB + Grafana.
Здесь расскажу, как я это настраиваю минимально — без Kubernetes, без Helm, просто Docker Compose на машине рядом с генератором.
Зачем вообще что-то кроме терминала
Терминал показывает итоговые цифры: среднее, p95, количество запросов. Но он не показывает:
- Как менялась latency во время прогона — была ли пила, был ли рост к концу.
- Как коррелирует рост VU с ростом ошибок.
- Что происходило в конкретную секунду, когда всё упало.
- Как сравнить два прогона друг с другом.
Графики отвечают на эти вопросы. Но чтобы они появились, метрики нужно куда-то складывать.
Почему не PostgreSQL с TimescaleDB
До InfluxDB я пробовал связку PostgreSQL + TimescaleDB — расширение, превращающее Postgres в базу временных рядов (кстати, компания Timescale в июне 2025 переименовалась в TigerData, но само расширение по-прежнему называется TimescaleDB). Сама по себе она хороша: hypertables, continuous aggregates, привычный SQL, не надо учить новый язык запросов.
Но с k6 всё уперлось в схему записи. Встроенного вывода в Postgres у k6 нет, работаешь через расширение xk6-output-postgres, а оно складывает сэмплы строками, где теги метрики лежат в JSONB-поле. На коротких прогонах терпимо. На 12-часовом soak-тесте с миллионами точек любая агрегация превращается в разбор JSONB по миллионам строк — база начинает подлагивать, дашборды отваливаются по таймауту, и вместо анализа результатов я чинил хранилище результатов.
InfluxDB под модель k6 заточен из коробки: каждая метрика складывается в свой measurement с отдельными полями и тегами, а схема расширяется сама, когда появляются новые метрики — ничего проектировать не надо.
Честности ради: проблема была не в TimescaleDB как таковой. Спроектируй я собственную схему — отдельные колонки вместо JSONB, hypertable, continuous aggregates — она бы справилась. Но это уже работа уровня «спроектировать и поддерживать схему БД», а мне нужно было «записал → открыл графики». Для этого сценария InfluxDB оказался проще.
InfluxDB: база для метрик
InfluxDB — хранилище временных рядов. Оно заточено под данные, где каждая точка привязана к времени: CPU в 14:03:15, latency в 14:03:16. k6 умеет писать в InfluxDB из коробки, но с нюансом.
Встроенный вывод
--out influxdbработает только с InfluxDB 1.x. Для 2.x и 3.x придётся собирать k6 с расширениемxk6-output-influxdb.
Мне для домашнего стенда это было избыточно, поэтому ниже ставлю 1.8: для наших задач она ничем не хуже, а связка с k6 и Grafana работает без единого лишнего шага.
Запуск через Docker Compose
Я использую простой compose-файл:
version: '3.8'
services:
influxdb:
image: influxdb:1.8
ports:
- "8086:8086"
environment:
- INFLUXDB_DB=k6
volumes:
- influxdb-data:/var/lib/influxdb
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=grafanapass
volumes:
- grafana-data:/var/lib/grafana
volumes:
influxdb-data:
grafana-data:Запускаю:
docker-compose up -dЧерез пару минут InfluxDB доступна на порту 8086, Grafana — на 3000.
База k6 создаётся автоматически из переменной INFLUXDB_DB — отдельно настраивать ничего не надо. По умолчанию 1.8 работает без авторизации, что для стенда в закрытой сети приемлемо. Если InfluxDB доступна снаружи — включите INFLUXDB_HTTP_AUTH_ENABLED и заведите пользователя.
Запуск k6 с записью в InfluxDB
k6 умеет отправлять метрики через флаг --out influxdb:
k6 run --out influxdb=http://localhost:8086/k6 script.js
Формат адреса: http://хост:порт/имя_базы. Больше ничего настраивать не нужно — k6 сам разложит метрики по measurements.
Важно: если InfluxDB на другой машине, указывайте реальный IP, а не localhost. И проверьте, что порт 8086 открыт в firewall.
Grafana: дашборды, которые я использую
После первого прогона я захожу в Grafana (admin / grafanapass), добавляю InfluxDB как datasource (тип InfluxDB, язык запросов InfluxQL, база k6) и импортирую готовый дашборд для k6. Есть официальный дашборд от Grafana Labs — ищите по ID 2587 в разделе Import.
Ключевые панели
Я обычно настраиваю такие панели:
- RPS (requests per second) — сколько запросов в секунду обрабатывает приложение. Смотрю на плато и на провалы.
- Response time (p50, p95, p99) — три графика одним стеком. Видно, как растёт «хвост».
- VU (virtual users) — сколько пользователей сейчас активно. Должно совпадать с тем, что задано в скрипте.
- HTTP errors — количество и типы ошибок по статус-кодам.
- Data transfer — сколько данных передаётся. Полезно, если тестируете API с тяжёлыми ответами.
Свои панели для бизнес-метрик
Помимо стандартных метрик k6, я иногда добавляю кастомные метрики прямо в скрипте:
import { Trend } from 'k6/metrics';
const checkoutDuration = new Trend('checkout_duration');
export default function () {
const start = Date.now();
// ... сценарий оформления заказа ...
checkoutDuration.add(Date.now() - start);
}Эта метрика появится в InfluxDB и её можно визуализировать отдельно — например, «время оформления заказа» вместо общего response time.
Сравнение прогонов
Чтобы сравнить два прогона, я помечаю их системным тегом testid при запуске (именно --tag, а не --env: env-переменная видна только внутри скрипта, а тег приклеивается к каждой метрике):
k6 run --out influxdb=http://localhost:8086/k6 --tag testid=before-optimization script.js
k6 run --out influxdb=http://localhost:8086/k6 --tag testid=after-optimization script.jsВ Grafana фильтрую по этому тегу и накладываю графики друг на друга. Сразу видно, помогла оптимизация или нет.
Что часто ломается
InfluxDB не принимает данные
Проверяю: правильный ли токен, правильная ли организация и бакет, доступен ли порт. Частая ошибка — указать localhost, когда InfluxDB в Docker, а k6 на хосте. В Docker localhost — это контейнер, а не машина.
Grafana не видит datasource
Проверяю URL InfluxDB в настройках datasource. Если Grafana тоже в Docker, использую http://influxdb:8086 (имя сервиса из docker-compose).
Слишком много данных
При больших прогонах k6 генерирует миллионы точек. InfluxDB может начать тормозить. Я ограничиваю частоту записи через переменную окружения K6_INFLUXDB_PUSH_INTERVAL=5s — k6 будет скидывать метрики пачками раз в пять секунд вместо непрерывного потока.
Минимальный рабочий набор
Чтобы получить работающую визуализацию:
- InfluxDB и Grafana в Docker Compose.
- Бакет
k6и токен записи. - Grafana datasource на InfluxDB.
- Импортированный дашборд k6 (ID 2587).
- Запуск k6 с
--out influxdb. - Проверка, что графики появились после первого прогона.
К следующей части
Метрики собираются и визуализируются. Осталось самое сложное — научиться их читать. В следующей части я расскажу, как отличать реальную проблему от шума, на что смотреть в первую очередь и какие ложные выводы я делал сам.
Обсуждение
Комментариев пока нет — начните тему.