Всем привет! Меня зовут Дмитрий Шкилёв, я тимлид команды Teachers Platform. Мы занимаемся личным кабинетом преподавателя и внутренними ресурсами, которые необходимы для обеспечения работы преподавателей.
Сегодня хотелось бы поговорить про такую не очень популярную историю, как измерение показателей команды разработки. За рамками статьи хочу оставить, почему необходимо измерять что-либо в работе команды — это тема для отдельного рассказа. Также тут вы не найдёте готовых рецептов для построения бордов в Grafana, но зато получите всё необходимое, чтобы начать их делать самостоятельно. Цель статьи — поделиться, как с минимумом инструментов измерять интересующие тимлида показатели.
Под катом несколько кейсов. Они актуальны для конкретной команды с ее укладом, поэтому прежде всего погружу вас в наши процессы. Но при этом прошу помнить, что статья — не агитация за определённый процесс работы, а описание способа построения дашбордов на примере отдельно взятой команды. Вы вправе сами решить, делать ли вам Code Review, логировать ли время, оценивать с помощью идеальных часов или стори поинтов, использовать ли сабтаски или связанные таски, как связывать баги с задачами и каким образом разделять задачи по эпикам. И я надеюсь, что после прочтения статьи вы сможете создать актуальный для вас борд.
Немного контекста о процессах в команде
Работаем по Agile c двухнедельными спринтами.
Команда делится на две части: Discovery и Delivery. Discovery — это продакт, аналитики, дизайнеры и ресёрчер. Delivery — тимлид, разработчики и QA. Задача Discovery — изучать потребности клиента, формировать требования и выбор проектов, которые принесут компании наибольший результат. Задача Delivery — качественно реализовать проект в ожидаемые сроки.
Раз в спринт я, как тимлид, провожу 1:1 c разработчиками и QA, а еще ретро со всей командой. Раз в квартал проходят квартальные ретро.
Есть процесс квартального планирования, в результате которого собираются проекты и скорятся на соответствие целям компании и приносимому результату. По каждому проекту создаётся техрешение вместе с оценкой. Те проекты, которые мы берём в квартал, проходят ресурсное планирование, в рамках которого строится диаграмма Ганта по конкретным задачам, причём задачи предварительно закрепляются за конкретными разработчиками.
Планирование спринта проводится дважды — сначала предварительное на встрече руководителей команды, а затем финальное со всей командой.
Раз в полгода разработчики и QA проходят грейдирование. По результатам грейдирования принимается решение о повышении оплаты.
Разработчики логируют рабочее время в JIRA. QA не логируют ничего.
Каждая задача разработки обязана пройти Code Review и ручное тестирование (автоматизаторов у нас в команде пока нет).
Один из принципов Skyeng — это открытость, поэтому каждый должен иметь открытый доступ не только к своим результатам, но и чужим.
Ещё один принцип — это честность, поэтому мы не боимся открыто говорить о проблемах и принимать ошибки.
Перед тем, как начать
Мы работаем с JIRA. Теоретически, можно сделать отдельный JIRA report, но у нас практически нет Java-разработчиков, да и это займет время. Но зато есть Grafana и доступ к реплике БД JIRA. Поэтому мой выбор пал на связку Grafana + Jira. Нужно было лишь разобраться во внутреннем устройстве БД JIRA. Особо рекомендую обратить внимание на историю изменений и кастомные поля.
Некоторые лайфхаки можно найти на просторах сети. Например, для определения задач, которые входят в спринт, можно воспользоваться этим советом. Дополнительно потребуется заджойнить имя спринта и добавить по нему условие. Также для виджетов по закрытым/созданным в рамках спринта задачам рекомендую добавить условие соответственно на resolutiondate/created, иначе запросы могут вернуть не те данные. Еще стоит учесть, что задачи могут переходить из одного спринта в другой и менять свои Original Estimate. Для отображения корректного Original Estimate в рамках прошедшего спринта потребуется сделать подзапрос к истории изменений и взять последнее значение до даты старта спринта.
Скорее всего вы уже используете какой-то плагин для логирования времени. В нашем случае — это Work Time Calendar. Следует изучить структуру таблиц плагина, чтобы иметь возможность как минимум достать ворклоги. Для учёта времени, которое проводит задача в определенном статусе, у нас используется плагин Time to SLA. Этот плагин особенно будет полезен для тех команд, которые не практикуют логирование времени.
Теперь давайте перейдём к разбору кейсов, в которых дашборды в Grafana могут помочь.
Sprint Report
Тимлиду важно понимать, что в целом происходит во время спринта, а также видеть ситуацию по каждому человеку из команды. Если общие отчёты в JIRA есть, то вот по людям собрать инфу уже проблематично. Кроме того, полезно бывает посмотреть производительность человека в динамике, ведь никто не в состоянии постоянно показывать топовые результаты.
Для того, чтобы это стало возможным, я вынес на отдельный дашборд интересующие меня показатели. При построении дашборда вы можете определить, какие показатели интересны именно вам, ведь у каждой команды и компании своя специфика.
Все виджеты я условно разбил на следующие группы:
Общие ключевые показатели команды — первые два ряда виджетов на скрине выше, плюс цели спринта, чтобы о них всегда помнить.
Показатели разработчиков.
Показатели QA.
Детализированные таблицы с данными по конкретным задачам.
По этим таблицам можно «отдебажить» что пошло не так в конкретном случае.
Одновременно на дашборде отображаются результаты только одного спринта. Дополнительно можно отфильтровать по людям.
Расскажу подробнее о виджетах, на которые чаще всего обращаю внимание.
Время по статусам
В этом виджете показывается время, которое задачи провели в конкретном статусе. Особенно полезен этот виджет будет для команд, которые не практикуют логирование времени в задачах. По нему можно понять, в каком месте процесса есть проблемы. Я, например, у себя заметил проблемы с зависанием задач на стадии Code Review. Поэтому создал отдельные виджеты для отслеживания задач на этой стадии и работы с командой для ускорения процесса Code Review.
Следует отметить отдельный статус NEED INFO FROM BUSINESS. В него мы переводим задачу, когда ждём информацию от бизнеса для ее решения. В идеале это число должно равняться нулю, так как к началу спринта все вопросы уже должны быть решены. Если в этом статусе задачи проводят много времени, то это означает, что задачи были плохо проработаны.
Для реализации этого виджета необходимо настроить SLA по каждому статусу с помощью плагина Time to SLA. После этого останется лишь просуммировать данные по всем задачам в спринте.
Top sprint performance developers
В этом виджете выводится информация о том, сколько идеальных часов (Original Estimate) закрыл разработчик. Исторические данные виджета помогают понять среднюю производительность человека и лучше планировать его нагрузку на следующие спринты. Кроме того, открытые данные по производительности дают дополнительный бонус — ребята немного включают соревновательный режим в производительности и с каждым разом закрывают всё больше задач :) Для этого полезно хотя бы иногда начинать дейли с показа текущего значения виджета.
Sprint performance rating
Формула проста: количество завершённых часов делится на количество взятых изначально в спринт. При этом, если разработчику добавили новые задачи и он их сделал, из-за чего он не успел сделать взятые перед началом спринта, то у него всё равно будут хорошие показатели.
Code Review
Для решения ситуации с Code Review я сделал несколько виджетов, чтобы отобразить количество задач с превышением и количество часов, на которое превысили SLA. Кроме того, сгруппировал результаты по исполнителям и по ревьюерам.
Наиболее интересен последний виджет, который показывает, на сколько часов в каждом конкретном случае был превышен ревьюером SLA по времени проведения Code Review. Не всегда в проблеме виноват ответственный за Code Review человек. Возможно, ему одновременно упало большое количество задач на ревью или задачи были очень объемными. Виджет только подсвечивает такие моменты, но разбираться в причинах нужно самостоятельно.
Logged time in sprint
Виджет помогает поддерживать актуальными данные по логированию времени. Видеть ситуацию на дашборде значительно удобнее, чем делать выгрузку ворклогов за определённый период и смотреть там часы по каждому человеку.
Для реализации необходимо использовать данные вашего плагина для логов, у нас это Work Time Calendar.
Dev production bugs и QA production bugs
Количество багов, которые дошли на production по разработчикам и QA.
Для хранения информации о багах на production мы выбрали кастомное поле, которое вручную обновляется в случае обнаружения бага по задаче на production. Возможно, у вас принят другой способ отслеживания багов — например, создание issues с определённым типом и их связи с изначальной задачей. В таком случае потребуется написать более сложный запрос, но это тоже возможно.
Количество задач, отправленных на доработку по разработчикам и QA
Здесь смотрим, насколько качественно разработчики выполняют задачи и как много дефектов находят QA.
Sprint issues not completed
Пожалуй, это самый интересный виджет в группе виджетов с детализированными таблицами по задачам. По нему на 1:1 можно посмотреть, какие конкретно задачи человеку не удалось выполнить, до какой стадии в рамках спринта он успел их довести и сколько времени на них уже потратил, а также сравнить с запланированным временем.
Бывает полезно посматривать на этот виджет во время спринта, чтобы понимать ситуацию по каждой задаче и иметь возможность оперативно подключиться, если становится понятно, что задачу можно и не успеть сделать за спринт. Если вдруг у вас перестанет работать JIRA, но реплика БД будет работать, то по этому виджету вполне можно провести дейли (у меня такой случай один раз был).
Issues with excess
В виджете отображаются задачи с превышением фактически потраченного времени над запланированным. Я показываю только задачи с превышением более 15%, чтобы не обращать на мелочи внимания. Лучше вывести конкретные часы (плановые и фактические), чтобы понимать превышение — это всего час или десять часов. Этот виджет тоже бывает полезно посмотреть на 1:1 и проговорить, что по отдельным задачам пошло не так.
Задачи с превышением времени по Code Review SLA
Если есть проблемы с Code Review, то по этому виджету становится видно, на каких конкретно задачах возникли проблемы и какое превышение времени было. Что даёт возможность детально разобрать проблему на 1:1
Дашборд Sprint Report позволил мне сэкономить несколько часов в спринт на составление ручных отчётов в экселе для юнит-лида и облегчил подготовку к 1:1 и ретро.
JIRA — statistics by services
Если:
к вам когда-нибудь приходили с вопросом «А сколько времени ушло на разработку этого сервиса?»
вам интересно узнать, сколько вы тратите времени на разработку своих и не только своих сервисов;
вы хотите понять насколько уложились в оценки по разработке новых сервисов;
…то вам может быть полезен отдельный дашборд в Grafana c количеством потраченного времени по сервисам.
Я смотрю на три показателя, которые мы используем в команде:
Initial Estimate — изначальная оценка. Ставится один раз после проведения техревью и не меняется. Если по задаче произошёл scope change, то лучше завести отдельную задачу.
Original Estimate — у нас это оценка задачи на момент перед стартом спринта (мы перед каждым спринтом проставляем Original Estimate и Remaining Estimate равными цифрами).
Logged Time — количество часов, которое залогировали по задаче.
Разница между Initial Estimate и Logged Time показывает, насколько мы ошибаемся в оценке. Original Estimate позволяет контролировать объем задач в спринте.
Как это работает
Спасибо команде инфры: после деплоя каждой задачи у неё проставляется лейбл deployed-<название сервиса>. По этим лейблам я определяю сервис, в рамках которого шла работа по задаче. Ну а дальше остаётся только просуммировать задачи с группировкой по сервису, в которые были зарезолвлены в обозначенное время. Вы можете у себя организовать такой же процесс, проставлять лейблы вручную или придумать другой способ разделения по сервисам.
На что стоит обратить внимание
Необходимо следить за лейблами. Замечал случаи, когда новые задачи заводились путём клонирования и лейблы клонировались от исходной задачи. В итоге у задачи было несколько деплойных лейблов, что приводило к задвоению/затроению оценок.
Анализируя полученные цифры, можно найти для себя ряд сюрпризов. Я, например, обнаружил, что в рамках квартала у нас ушло значительно больше времени на доработку сервиса соседней команды, чем мы рассчитывали.
Если приходится регулярно фиксить баги в каком-то сервисе, то с помощью такого отчёта легко показать бизнесу, сколько времени уходит на поддержку работоспособности сервиса, а это даёт рычаг для обоснования необходимости устранения технического долга.
По количеству сервисов, на которые тратится основной объём времени, тоже можно сделать выводы. Если у вас больше 3 сервисов, на каждый из которых уходит более 5% времени, то это говорит о расфокусировке команды. В этом случае стоит проговорить зоны ответственности и понять, действительно ли вам стоит отвечать за все эти сервисы или есть более подходящая команда. Возможно, пришла пора разделять команду на части.
Грейдирование
Раз в полгода у нас проходит грейдирование разработчиков. Ребята оценивают сами себя, друг друга и получают оценку от руководителей. Необходимо ответить на вопросы о производительности разработчика и количестве задач, которые вернули после тестирования. Чтобы определить грейд, необходимо знать точные цифры по каждому разработчику:
% задач, которые были возвращены QA после тестирования на доработку.
% задач, в которых разработчик уложился в оценку.
% задач, которые были сделаны быстрее, чем их оценивали.
Естественно, эти цифры не зависят от респондента, но долгое время каждый отвечал «по личным ощущениям», и они не всегда совпадали с правдой. Так как же считать эти показатели?
С % задач, которые были возвращены QA после тестирования, мне повезло. У нас уже было кастомное поле WasInTesting, которое автоматически увеличивалось на 1 каждый раз, когда задача из разработки отправлялась в тестирование. Осталось только посчитать % задач, у которых этот показатель был >1.
Что касается сравнения фактических результатов и планируемых, то количество залогированных часов в JIRA есть (поле jiraissue.timespent). Плановые часы мы также сохраняем в отдельном кастомное поле Initial estimate (Original estimate не можем использовать для этого, так как мы его меняем каждый раз перед началом спринта). Остается сравнить количество потраченных часов на задачу и плановых.
У нас есть задачи на исследования, которые мы заранее не оцениваем. Для формирования корректной выборки необходимо исключить их. Это легко можно сделать, если помечать их отдельным лейблом (мы выбрали лейбл research).
Как известно, аппетит приходит во время еды. Поэтому кроме необходимых показателей для ответов на вопросы грейдирования я вывел и ряд других, которые позволяют понять, как человек поработал в этом квартале, увидеть конкретные задачи, на которые ушло много времени. Дашборд доступен для всей команды. Каждый видит свои результаты и результаты коллег. Всё прозрачно и непредвзято. Это повышает доверие команды к результатам грейдирования и компании в целом, а также мотивирует ребят на улучшение своих показателей.
Вот что из всего этого получилось:
Заключение
На первый взгляд получившиеся отчёты кажутся громоздкими и трудно представить, как своими руками создать нечто подобное. Но на самом деле это не так уж и сложно, главное — начать.
У меня в самом начале был всего один график. Периодически я дорабатывал первый борд и создал остальные, когда в них возникла необходимость. До сих пор продолжаю усовершенствовать борды и с каждой итерацией они становятся полезнее и точнее.
В качестве результата вы получаете инструмент, с помощью которого можно достаточно просто мониторить производительность сотрудников и процессы в команде, обнаруживать аномалии и оперативно их устранять.