Обзор
DashPDF — сервис для экспорта дашбордов Grafana и отдельных панелей в PDF и PNG. Он превращает рабочий дашборд в документ, который можно скачать, сохранить или регулярно отправлять получателям по электронной почте.
DashPDF работает через app-плагин в Grafana. Плагин выполняет запросы панелей внутри инфраструктуры пользователя, собирает JSON дашборда и подготовленные data frames, затем исходящим запросом передаёт снапшот для рендеринга. Доступ к Grafana и учётные данные источников данных остаются на стороне пользователя.
Продукт работает с Grafana 12 и 13. Обе версии входят в матрицу автоматизированного тестирования.
Возможности продукта
DashPDF предоставляет:
- Экспорт всего дашборда или отдельной панели
- Форматы PDF и PNG
- Размер страницы A4 или Letter
- Книжную и альбомную ориентацию
- Постраничную раскладку или одну длинную страницу
- Сохранение панелей целиком при постраничной разбивке
- Передачу выбранного диапазона времени и значений переменных
- Работу с повторяющимися панелями и строками, mixed data sources, ad hoc-фильтрами и library panels
- Расписания с cron-выражением, часовым поясом и относительным временным окном
- Доставку готового отчёта получателям по электронной почте
- Портал со списком отчётов, подключённых экземпляров Grafana и их расписаний
Получатели задаются непосредственно в расписании. После запуска PDF приходит во вложении, а для крупного файла письмо содержит ссылку на отчёт в портале. Повторяющиеся ошибки приостанавливают расписание и делают проблему видимой вместо молчаливого пропуска доставки.
Сейчас DashPDF доступен бесплатно в режиме preview, пока команда изучает реальные сценарии экспорта и доставки отчётов.
Архитектура
DashPDF построен как monorepo и включает:
- Веб-портал на Next.js
- API на Go с контрактом OpenAPI
- App-плагин для Grafana на TypeScript и Go
- Внутренний datasource-плагин для передачи сохранённых data frames в среду рендеринга
- PostgreSQL для учётных записей, подключённых экземпляров, токенов, снапшотов, задач рендера и расписаний
- Redis для координации составной загрузки снапшотов между репликами API
- Mailoo как headless CMS для блога
Вход в портал отделён от доступа плагина к API: браузер работает со своей сессией, а каждый подключённый экземпляр Grafana получает отдельный токен.
Для рендера API запускает изолированную Grafana той же мажорной версии, что и исходный экземпляр, и добавляет нужные публичные panel-плагины. Источники данных в копии дашборда заменяются внутренним datasource, который отдаёт уже собранные frames. PDF и PNG формируются через headless Chrome.
Среды рендеринга переиспользуются для одинаковых сочетаний версии Grafana и набора плагинов, а после периода бездействия останавливаются. Это сокращает время повторных экспортов и одновременно ограничивает число постоянно работающих экземпляров.
Инфраструктура и SRE
Для проекта настроены:
- GitLab CI с проверками кода, тестами и анализом качества
- Сборка контейнеров через Kaniko
- Отдельные образы веб-портала, API и мигратора
- GitOps-деплой через Argo CD
- Отдельная задача миграции базы данных перед обновлением API
- Health checks для портала и API
- Playwright E2E-тесты на Grafana 12 и Grafana 13
- Ограниченный пул сред рендеринга
- Автоматическое удаление содержимого снапшотов по сроку хранения
- Ограничения на размер и количество незавершённых загрузок
Кадры снапшота доступны только среде рендеринга внутри сервисного контура. Публичный API принимает подготовленные плагином данные и управляет задачей, а внутренний канал обслуживает временную Grafana.
Инженерные задачи
Главная инженерная задача DashPDF — получить воспроизводимый отчёт из живого дашборда, сохранив границу доверия вокруг Grafana пользователя.
Плагин выполняет запросы там, где уже настроены доступ к источникам и права пользователя. В сервис передаётся материал конкретного экспорта, а рендер выполняется в отдельной Grafana совместимой версии. Такой подход позволяет воспроизводить панели без передачи сервису доступов к инфраструктуре мониторинга.
Для крупных дашбордов реализована составная загрузка снапшота. Её состояние хранится централизованно, поэтому части одной загрузки может принимать API с несколькими репликами.
Расписание исполняется плагином внутри Grafana. При сохранении он записывает план запросов, а затем повторяет его для нужного временного окна. Если дашборд изменился после записи плана, запуск помечается предупреждением до следующей записи плана.
Постраничный PDF требует отдельной раскладки: панели группируются по строкам и переносятся целиком, чтобы график или таблица не оказались разрезаны границей страницы.
В результате DashPDF дополняет существующую Grafana экспортом и регулярной доставкой отчётов, сохраняя запросы к источникам данных и контроль доступа внутри инфраструктуры пользователя.