Отчёт «DORA-метрики» измеряет поставку группы или проекта за выбранный период: как часто выполняются успешные развёртывания в production-окружения, сколько слитое изменение ждёт своего развёртывания, сколько инциденты остаются открытыми и сколько инцидентов приходится на одно развёртывание. Отчёт группы охватывает проекты группы и её подгрупп.

Доступность отчёта

Отчёт проекта доступен участникам с ролью «Наблюдатель» и выше, в том числе тем, кто получил роль в родительской группе. Участники с ролью «Гость» не видят пункт «DORA-метрики» в меню проекта, а прямой адрес отвечает кодом 404. Уровень видимости проекта этот доступ не расширяет: в публичном или внутреннем проекте пользователь, не состоящий в проекте, отчёт не видит. Выключение функции «Аналитика» проекта закрывает отчёт для всех: пункт меню пропадает, а прямой адрес отвечает кодом 404.

Отчёт группы доступен участникам с ролью «Наблюдатель» и выше, в том числе тем, кто получил роль в родительской группе, а также пользователям с типом «Аудитор». Участники с ролью «Гость» не видят пункт в меню группы, а прямой адрес отвечает кодом 404. Для отчёта проекта пользователю с типом «Аудитор» нужна роль «Наблюдатель» и выше в проекте или в его родительской группе.

Просмотр отчёта

Чтобы просмотреть отчёт группы:

  1. В верхней панели нажмите «Искать или перейти к…» и выберите группу.
  2. В меню группы перейдите в «Аналитика» → «DORA-метрики».

Чтобы просмотреть отчёт проекта:

  1. В верхней панели нажмите «Искать или перейти к…» и выберите проект.
  2. В меню проекта перейдите в «Аналитика» → «DORA-метрики».

Также отчёт можно открыть по прямому адресу:

ОтчётАдрес
Группаhttps://<HOST>/groups/<GROUP>/-/analytics/dashboards/dora_metrics
Проектhttps://<HOST>/<GROUP>/<PROJECT>/-/analytics/dashboards/dora_metrics

На странице расположены список периодов, ряд карточек со значением каждой метрики за период и по графику на каждую метрику со значениями по дням.

Метрики

МетрикаПодпись карточкиЗначение
«Частота деплоя»«Успешные деплои в день.»Число успешных развёртываний, завершённых в периоде, делённое на число дней периода
«Время проведения изменений»«Медианное время от слияния до деплоя.»Медианное время от слияния запроса на слияние до завершения успешного развёртывания, которое принесло его в окружение
«Время восстановления сервиса»«Медианное время, в течение которого инциденты остаются открытыми.»Медианное время от создания инцидента до его закрытия по инцидентам, закрытым в периоде
«Частота неуспешных изменений»«Инциденты, делённые на количество деплоев.»Число инцидентов, созданных в периоде, делённое на число успешных развёртываний, завершённых в нём

Отчёт учитывает развёртывания в окружения с уровнем развёртывания production. Развёртывание связывается с запросами на слияние, коммиты которых оно принесло в окружение после предыдущего успешного развёртывания в то же окружение; первое развёртывание в окружение связывается со всеми запросами на слияние, слитыми в развёрнутую ветку. Запрос на слияние, слияние которого зафиксировано после завершения развёртывания, во время проведения изменений не попадает.

Инциденты — задачи с типом «Инцидент». Инцидент относится к проекту в целом и учитывается как инцидент уровня production, поэтому «Время восстановления сервиса» и «Частота неуспешных изменений» имеют значения только в проекте с окружением этого уровня. Инцидент, помеченный как дубликат другой задачи, исключается из обеих метрик; переоткрытый инцидент перестаёт считаться закрытым.

Значения хранятся по окружениям и по дням; день начинается и заканчивается по часовому поясу сервера. День пересчитывается заново при событии этого дня: через 5 минут после успешного развёртывания, когда с ним связаны принесённые им запросы на слияние, и сразу при создании, закрытии, переоткрытии инцидента, пометке его как дубликата или смене его типа на «Инцидент» или с него. За период суммируются развёртывания и инциденты его дней, а время проведения изменений и время восстановления сервиса берутся как медианы дневных медиан. Период без успешных развёртываний значения «Частоты неуспешных изменений» не имеет.

Значения записываются в момент события. Развёртывания и инциденты, произошедшие до обновления, которое принесло отчёт, получают значения после загрузки истории администратором, как описано в разделе Загрузка истории; то же относится к дням, посчитанным до изменения списка веток из раздела Ветки, учитываемые во времени проведения изменений.

Карточки метрик

Ряд над графиками содержит по карточке на каждую метрику с её названием, подписью и значением за весь период:

  • «Частота деплоя» — развёртываний в день, с суффиксом /d;
  • «Время проведения изменений» и «Время восстановления сервиса» — в днях, с суффиксом d;
  • «Частота неуспешных изменений» — в процентах.

Метрика без значения в периоде показана прочерком. Если значения не удалось загрузить, карточка показывает «Не удалось загрузить DORA-метрики.»

Графики

Под карточками расположено по графику на каждую метрику с названием и подписью её карточки: линия с точкой на каждый день периода, вертикальная ось в единицах карточки, горизонтальная ось — «Дата». Пунктирная линия через весь график несёт значение карточки за весь период; на графиках «Время проведения изменений» и «Время восстановления сервиса» она называется «Медиана», на графиках «Частота деплоя» и «Частота неуспешных изменений» — «Среднее». При наведении на точку показываются дата и значение. День, в который у метрики нет значения, точки не имеет.

График без значения ни за один день периода показывает «Нет доступных данных» и «Создайте production-деплои и инциденты, чтобы заполнить этот график.» Если значения не удалось загрузить, график показывает «Не удалось загрузить DORA-метрики.»

Период

Список в правом верхнем углу страницы задаёт период: «Последние 7 дней», «Последние 30 дней», «Последние 90 дней», «Последние 180 дней» или «Произвольный диапазон», который открывает поля выбора даты «От» и «В». Отчёт открывается на «Последние 180 дней». Готовый период заканчивается текущим днём. Произвольный период применяется, когда выбраны обе даты; он заканчивается текущим днём или раньше и ограничен 180 днями. Значок рядом с полями показывает «Даты и время отображаются в часовом поясе UTC. Диапазон дат ограничен 180 днями.»

Когда ни у одной метрики нет значения ни за один день периода, вместо карточек и графиков страница показывает «DORA-метрики недоступны» и «Создайте production-деплои и инциденты, чтобы заполнить этот дашборд.»

Ветки, учитываемые во времени проведения изменений

По умолчанию время проведения изменений развёртывания учитывает все связанные с ним запросы на слияние. В проекте, который продвигает изменения через несколько веток — запрос на слияние в staging, затем запрос на слияние из staging в main и развёртывание main, — с развёртыванием связаны оба запроса, и одно изменение считается дважды. DORA-конфигурация проекта называет целевые ветки, запросы на слияние в которые учитываются: с одной веткой main слияния в staging во время проведения изменений не попадают.

Список действует на окружения уровня production; окружение другого уровня сохраняет все связанные запросы на слияние. Ветка или тег, из которых выполнено развёртывание, со списком не сравниваются, поэтому проект, развёртывающий теги, сохраняет своё время проведения изменений. Список должен быть непустым и без пустых или повторяющихся имён; у проекта одна конфигурация.

Конфигурация задаётся из Rails-консоли. Откройте консоль для используемого типа установки:

  • Пакет для ОС Linux
  • Omnibus Docker
  • Helm-чарт
  • Модуль Deckhouse Kubernetes Platform
sudo gitlab-rails console
docker exec -it code gitlab-rails console
d8 k -n code exec -it deploy/code-toolbox -- gitlab-rails console -e production
d8 k -n d8-code exec -it -c toolbox deploy/toolbox -- gitlab-rails console -e production

Затем создайте конфигурацию, указав полный путь проекта и имена веток:

project = Project.find_by_full_path('<GROUP>/<PROJECT>')
Dora::Configuration.create!(project: project, branches_for_lead_time_for_changes: %w[main])

Чтобы изменить список существующей конфигурации:

Dora::Configuration.find_by!(project: project).update!(branches_for_lead_time_for_changes: %w[main release])

Чтобы снова учитывать все связанные запросы на слияние, удалите конфигурацию командой Dora::Configuration.find_by!(project: project).destroy!.

Дни, посчитанные до создания или изменения конфигурации, сохраняют своё время проведения изменений. Чтобы пересчитать их, загрузите историю за затронутый период, как описано в разделе Загрузка истории.

REST API

Значения отчёта доступны через REST API, по одной метрике на запрос:

GET /api/v4/projects/:id/dora/metrics
GET /api/v4/groups/:id/dora/metrics

:id — идентификатор или URL-кодированный полный путь проекта или группы. Запрос аутентифицируется токеном доступа с областью api или read_api; пользователю токена нужен тот же доступ, что и к странице.

Параметры:

ПараметрОписание
metricОбязательный. Метрика: deployment_frequency, lead_time_for_changes, time_to_restore_service или change_failure_rate
start_dateПервый день периода в форме YYYY-MM-DD. По умолчанию — три месяца до текущего дня
end_dateПоследний день периода в форме YYYY-MM-DD. По умолчанию — текущий день
intervalИнтервал значений: daily (по умолчанию), monthly или all
environment_tiersУровни развёртывания окружений, массив: production, staging, testing, development, other. По умолчанию — production

Ответ — массив объектов с полями date и value. С daily и monthly массив содержит по объекту на каждый день или месяц периода: date — день или первый день месяца, value — null для дня или месяца без значений; с all — один объект с date, равным null. Частота развёртываний указана в развёртываниях в день, время проведения изменений и время восстановления сервиса — в секундах, частота неуспешных изменений — долей от 0 до 1. Для месяца, обрезанного периодом, частота развёртываний делится на дни месяца внутри периода.

Коды ответа:

  • 200 — значения;
  • 400 — start_date позже end_date, период длиннее 180 дней или значение вне перечисленных выше списков;
  • 401 — нет токена;
  • 403 — у пользователя токена нет доступа к отчёту;
  • 404 — проект или группа не найдены.

Пример:

curl --header "PRIVATE-TOKEN: <TOKEN>" \
  "https://<HOST>/api/v4/projects/<GROUP>%2F<PROJECT>/dora/metrics?metric=deployment_frequency&start_date=2026-03-09&end_date=2026-03-11"

Ответ для проекта с 2 успешными развёртываниями в окружение уровня production 2026-03-10:

[
  { "date": "2026-03-09", "value": null },
  { "date": "2026-03-10", "value": 2.0 },
  { "date": "2026-03-11", "value": null }
]

Загрузка истории

Значения записываются в момент развёртывания или инцидента. Чтобы учесть развёртывания и инциденты, произошедшие до обновления, которое принесло отчёт, или пересчитать дни после изменения списка веток, администратор запускает rake-задачу gitlab:dora:backfill с полным путём проекта и первым и последним днём периода в форме YYYY-MM-DD:

  • Пакет для ОС Linux
  • Omnibus Docker
  • Helm-чарт
  • Модуль Deckhouse Kubernetes Platform
sudo gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'
docker exec code gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'
d8 k -n code exec deploy/code-toolbox -- gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'
d8 k -n d8-code exec -it -c toolbox deploy/toolbox -- gitlab-rake 'gitlab:dora:backfill[<GROUP>/<PROJECT>,<START_DATE>,<END_DATE>]'

Задача принимает один проект; для отчёта группы запустите её для каждого проекта группы. Она ставит в очередь пересчёт каждого дня периода, в который завершилось успешное развёртывание, в окружении этого развёртывания, и каждого дня, в который был создан или закрыт инцидент. В проекте без окружения уровня production дни инцидентов в очередь не попадают. Задача выводит Enqueued N DORA day recounts. и завершается; пересчёты выполняются в фоне через Sidekiq, и отчёт заполняется по мере их завершения. День пересчитывается заново, поэтому повторный запуск за тот же период даёт те же значения.

Задача останавливается с ошибкой, если аргумент пропущен (project, start_date and end_date are required), проект не найден (Project not found: <PATH>), дата указана в другой форме (invalid date) или первый день позже последнего (start_date must not be after end_date).