Привет, Хабр. Меня зовут Никита Лепёхин. Я DevOps-инженер в СберЗдоровье — MedTech-компании №1 в России.

Многие компании пользуются GitLab в качестве инструмента CI/CD. Но при использовании бесплатной Community-версии он не даёт достаточную наблюдаемость всех запускаемых пайплайнов. Поэтому актуальной задачей становится поиск инструмента для анализа GitLab CI/CD. Наш выбор для её решения — Apache DevLake.

В этой статье я расскажу, что такое Apache DevLake, как он организован, и каким образом мы смогли его применить под свои задачи.

Что такое Apache DevLake

Apache DevLake — это платформа с открытым исходным кодом для сбора и анализа данных из различных DevOps-инструментов. Она помогает командам разработки систематизировать и измерять эффективность своей работы, улучшая процессы на основе объективных данных.

Платформа объединяет данные из множества datasource, то есть инструментов, задействованных в процессе разработки, например, GitLab, GitHub, Jira, Jenkins, в одно хранилище. Далее на основе этой информации с помощью SQL-запросов можно строить метрики и визуализировать их, например, в Grafana.

В Apache DevLake данные из datasource хранятся на нескольких уровнях (layers):

  • Raw Layer — слой необработанных данных. Здесь хранятся необработанные, оригинальные данные, извлечённые через API непосредственно из инструментов и сервисов, например, GitLab. Эти данные служат основой для дальнейшей очистки и нормализации.

    Так, когда DevLake ходит в GitLab API, полученные данные он складывает в БД в виде JSON в таблицах _raw_.+, например: _raw_gitlab_api_job, _raw_gitlab_api_pipeline. Такой подход позволяет быстро собрать нужные данные, а дальше уже заниматься их трансформацией.

  • Tool Layer — слой конкретных инструментов. На данном уровне происходит преобразование сырых JSON-данных из Raw Layer в реляционную форму, но пока в разрезе инструментов. Это промежуточный эт��п, где данные адаптируются под единый стандарт. На выходе получаются таблицы с названием в формате _tool_.+, например: _tool_gitlab_jobs, _tool_gitlab_pipelines.

  • Domain Layer — слой предметной области. Это финальный слой, содержащий чистые, нормализованные и готовые к анализу данные. Здесь все интеграции сведены в единую схему, где представлены абстрагированные понятия, соответствующие бизнес-задачам организации, такие как репозитории, разработчики, пайплайны, задачи и прочие. Именно этот уровень используется для создания отчётов и анализа. Пример таблиц в Domain Layer: cicd_pipelines, cicd_tasks.

    Примечание: Подробнее изучить все таблицы Domain Layer можно здесь. Узнать больше о том, какие данные умеет собирать DevLake из каждого источника можно здесь.

    А почитать про опыт нашей команды — в ТГ-канале SberHealth IT ;)

Компоненты

DevLake включает различные компоненты:

  • API Server. Сервер, предоставляющий программный интерфейс для пользователей и компонентов Apache DevLake.

  • Runner. Выполняет работу по обработке данных. Получает задания от API сервера, подключается к внешним источникам данных (datasources), собирает необходимую информацию и загружает её в БД. Отвечает за основной рабочий поток обработки данных.

  • Plugins. Набор модулей расширения, предназначенных для поддержки интеграции с различными системами, например, GitLab, Jira, Jenkins.

    Примечание: API Server, Runner и Plugins запускаются в одном поде и контейнере в k8s. Эти компоненты не поддерживают горизонтальное масштабирование, то есть работают в одной реплике (один под).

  • Config UI — Web-интерфейс администрирования и настройки DevLake. Запускается отдельным подом в k8s при деплое.

  • Database — реляционная База данных, в которую поступают собранные и обработанные данные.

    Примечание: полноценная поддержка имеется только для MySQL, к тому же дефолтные дашборды заточены под него. На момент релиза 1.0.1 поддержка PostgreSQL была неполной. Возможно, в более новых релизах это поправят.

Расписание сбора данных

Apache DevLake выполняет синхронизацию данных из добавленных в него проектов в соответствии с заданным расписанием.

Для каждого проекта можно назначить своё расписание. При этом я рекомендую запускать задачи ночью, потому что в процессе обработки новых данных метрики временно нарушаются, что будет выражаться искаженными данными на дашбордах.

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

Доступный функционал из коробки

Сразу после запуска DevLake предлагает готовые дашборды для:

  • DORA метрик,

  • GitLab,

  • других инструментов, например, GitHub, Jira, Jenkins.

Для меня наибольший интерес представлял дашборд GitLab. Из коробки он позволяет отслеживать:

  • статистику по MR и contributors;

  • CI/CD Metrics: количество успешных пайплайнов, success rate пайплайнов, среднее время выполнения пайплайнов.

Все данные на панелях с временной шкалой по умолчанию агрегируются по недельным и месячным интервалам. Это не совсем удобно, поскольку не позволяет анализировать данные в разрезе дней или часов.

Помимо этого, мне в DevLake изначально не хватало некоторых функций. Например:

  • метрик не только pipelines, но и jobs, таких как success rate, какие джобы ретраят и как много, какие джобы падают и как много;

  • агрегации по дням и часам в дополнение к неделям и месяцам;

  • деления по окружениям: prod/dev/stage, отдельно выделить Merge Request'ы.

Примечательно, что все нужные мне данные есть в БД DevLake'а, поэтому в теории их можно вытянуть в дашборды с помощью SQL-запросов. Приступим.

Кейс адаптации DevLake под задачи СберЗдоровья: получение метрик, которых нет «из коробки»

Сразу оговорюсь, что каждый строит CI/CD по-своему, поэтому универсального, подходящего всем решения поставленных задач у меня нет. Но вы можете разработать свое решение, следуя тем советам, которые я опишу.

Метрики jobs

В дополнение к дефолтным метрикам пайплайнов нужны метрики jobs.

Так как у джоб есть имя, можно дополнительно выделять информацию:

  • какие джобы чаще всего падают, например, билд образов или автотесты;

  • какие джобы чаще всего ретраят.

Чтобы выводить эти данные на дашборды, я задействовал информацию из двух таблиц БД — cicd_pipelines, cicd_tasks. В результате я смог получить реализацию, которая позволяет отслеживать через дашбо��ды DevLake детальную статистику jobs.

Метрики Jobs. Часть 1
Метрики Jobs. Часть 1
Метрики Jobs. Часть 2
Метрики Jobs. Часть 2

Деление на окружения

Также нам нужно было делить все jobs, pipelines на окружения: dev, prod, stage. Кроме того, мы хотели выделить Merge Request'ы.

Для этого можно применить несколько подходов.

  • Окружение может быть указано в столбце environment таблицы _tool_gitlab_deployments, если вы используете ключевое слово environment. Подробнее об этом можно почитать здесь

  • В таблицу pipelines можно добавить столбец x_source, который содержит в себе признак source, указывающий на тип события, которое стригерило запуск пайплайна.

    На основе сочетания этих данных можно определять окружение.

Как добавить в таблицу pipelines столбец x_source

GitLab API возвращает поле source — оно имеется в данных Raw Layer. Проблема в том, что в Tool Layer и Domain Layer этот признак при обработке теряется.

Но его можно добавить с помощью плагина customize.

Алгоритм добавления столбца x_source в таблицу pipelines следующий:

  1. Создаем столбец x_source в таблице cicd_pipelines

    curl -X POST -H "Authorization: Bearer ..." -d '{"columnName": "x_source","dataType": "varchar(255)","description": "pipelines source","displayName": "source"}' https://devlake.example.com/api/rest/plugins/customize/cicd_pipelines/fields
  2. Пишем правило, как из сырых JSON данных вытащить признак source и поместить его в созданный столбец. 

    Здесь есть несколько нюансов. Так, все изменения вносятся в Blueprint — задачу, которая описывает, какие данные нужно собирать, из каких источников данных, как проводить трансформацию данных и другие аспекты. Любые дополнительные столбцы, правила извлечения данных или фильтры добавляются через редактирование Blueprint, после чего DevLake пересобирает данные по этим правилам. При этом, на мой взгляд неочевидно, как писать правила — чтобы разобраться в этом, можно изучить исходники плагина.

    В rawDataTable прописываем таблицу, указанную в столбце _raw_data_table таблицы cicd_pipelines. В rawDataParams прописываем содержимое столбца params таблицы, указанной в rawDataTable. Далее эти таблицы «под капотом» связываются через "LEFT JOIN" по полям cicd_pipelines._raw_data_id = _raw_gitlab_api_pipeline_details.id

    В нашем случае получилось правило следующего вида:

    [
      {
        "plugin": "customize",
        "subtasks": null,
        "options": {
          "transformationRules": [
            {
              "mapping": {
                "x_source": "source"
              },
              "rawDataParams": {
                "ConnectionId": 1,
                "ProjectId": 56
              },
              "rawDataTable": "_raw_gitlab_api_pipeline_details",
              "table": "cicd_pipelines"
            }
          ]
        }
      }
    ]
  3. Получившийся JSON добавляем в Blueprint проекта.

  4. Пересобираем данные проекта кнопкой "Re-transform Data".

  5. Наблюдаем появившийся столбец x_source в таблице cicd_pipelines.

  6. Дописываем запросы в дашборде, чтобы фильтровать данные по x_source и environment. Например, через конструкцию вида

    WHERE
       CASE
         WHEN ('${env}' = 'production') THEN environment = 'production'
         WHEN ('${env}' = 'mr') THEN x_source = 'merge_request_event'
         WHEN ('${env}' = 'dev') THEN x_source REGEXP '^(api|web)$'
      END

    На дашборде в Grafana можно добавить переменную env, определяя которую, мы будем получать метрики только нужного окружения:

Выбор окружения
Выбор окружения

Что в итоге

DevLake — удобный инструмент, с помощью которого можно организовать аналитику всех процессов GitLab CI/CD. Хотя его функционал «из коробки» был недостаточным для задач нашего проекта, это полностью компенсировалось гибкостью настройки. Применение DevLake позволило получить прозрачную картину CI/CD, выявить джобы, которые становились точками отказа, и устранить проблемы в пайплайнах.

А вы применяли DevLake в своих проектах? Делитесь опытом — будет полезно.