Иногда в процессе работы с Jenkins возникает необходимость анализировать данные о проходящих билдах. Зачастую это стандартная статистика которую и так предоставляет Jenkins, иногда предоставляют дополнительные плагины, например global-build-stats. Но так же возникает необходимость сборки данных специфичных для проекта. Но кроме сбора данных так же хочется их визуализировать, например с помощью графиков.

К счастью у Jenkins есть отличный плагин plot. Плагин позволяет строить графики на основе, как единичных, так и множественных значений. Давайте рассмотрим простой и реальный пример: посчитать количество @ts-ignore в коде смигрированном на typescript.

Сперва определяемся как в принципе мы можем посчитать количество в исходниках. Думаю первой мыслью почти у всех был поиск при помощи утилиты grep.

~/project$ grep -R -o @ts-ignore ./src | wc -l
    8435
~/project$

И так мы хотим построить график, что бы по оси X откладывали билды, а по Y мы видели количество оставшихся @ts-ignore. Так мы сможем анализировать насколько быстро мы избавляемся от старого кода.

Плагин plot имеет 3 способа получения значений, все они основаны на чтении значений из файла:

  • Чтение из Properties файла
  • Чтение из CSV файла
  • Чтение из XML файла (при помощи XPath)

Так как в нашем случае на графике должно быть просто единичное значение, то самый подходящий способ конфигурации это Properties файл. Что бы им воспользоваться нам необходимо сформировать файл со следующим содержимым:

YVALUE=<your value>

А затем передать этот файл в propertiesSeries свойство плагина. Скрипт для пайплайна можно сконфигурировать с помощью Snippet Generator.

pipeline {
  agent any
  stages {
    // Your stages...
  }
  post {
    always {
      // Build properties file
      sh 'echo "YVALUE=$(grep -R -o @ts-ignore ./src | wc -l)" > tsignore.properties'

      // Draw chart
      plot csvFileName: 'plot-8e54e334-ab7b-4c9f-94f7-b9d8965723df.csv',
        propertiesSeries: [
          [file: 'tsignore.properties', label: '@ts-ignore']
        ],
        group: 'Source code metrics',
        title: 'Ts ignore count',
        style: 'line',
        exclZero: true,
        numBuilds: '100'
    }
  }
}

В данном скрипте:

  • plot-8e54e334-ab7b-4c9f-94f7-b9d8965723df.csv - Это имя файла, в котором будет храниться история сборок.
  • group: 'Source code metrics' - Группа графиков (обязательный параметр), необходима, что бы отображать графики из разных групп на разных страницах.
  • exclZero: true - Разрешить графику начинаться не с нуля. Это сделает график более наглядным, так как опустит то пространство где он не изменяется.
  • numBuilds: 100 - Количество отображаемых билдов по оси X.
  • Более подробно про остальные параметры можно знать здесь.

После запуска пайплайна в боковом меню ветки появился новый пункт Plots.

demo

Открыв его мы увидим наш график. Note: На фото график после проведения нескольких билдов.

Грфик количества ts ignore

Так же можно, использовать несколько графиков на одной координатной плоскости, просто добавив еще один файл.

propertiesSeries: [
  [file: 'tsignore.properties', label: '@ts-ignore'],
  [file: 'eslint-disable.properties', label: 'eslint-disable']
],

Грфик с несколькими зачениями

На этом графике видно как растет количество используемых eslint-disable и плавно падает количество @ts-ignore.

Более удобным способом конфигурации графиков с несколькими значениями будет использование csv файлов. Генерация его конечно ложиться на ваши плечи, но это дает наиболее гибкие возможности для визуализации любых данных. Например, можно строить график изменения размера всех чанков в проекте (речь идет о webpack сборке).

Первым шагом получим статистки от самого webpack в виде файла stats.json. Как это сделать можно узнать тут.

Далее напишем маленький скрипт, для того что бы преобразовать данные в csv формат.

const stats = require('./dist/stats.json');
const papaparse = require('papaparse');
const fs = require("fs");

fs.writeFileSync('stats.csv', papaparse.unparse([
  stats.chunks.map(chunk => chunk.id),
  stats.chunks.map(chunk => chunk.size / (1024 * 1024)),
]));

И в конце сконфигурируем новый график в качестве style укажем stackedArea, что бы можно было графически оценивать размер как каждого чанка, так и все вместе.

plot csvFileName: 'plot-6f220edc-412a-4f4f-b065-0015fdc38077.csv',
  csvSeries: [
    [displayTableFlag: false, file: 'stats.csv']
  ],
  exclZero: true,
  group: 'Source code metrics',
  numBuilds: '100',
  style: 'stackedArea',
  title: 'Chunks sizes'

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

Грфик с несколькими зачениями

Так же если посмотреть URL картинки на странице Plots, то можно заметить параметры переданные эндпоинту .../plot/getPlot?index=0&width=750&height=450. Параметры можно изменить и передать дополнительные title=Custom title и style=stackedbar3d это позволит изменить график на лету:

Демонстрация модификации графика через query params

Данные которые записывает плагин можно так же получить и проанализировать. Они хранятся в файле с именем переданным параметром csvFileName. А располагается этот файл в папке вашей джобы: $JENKINS_HOME/jobs/<jour job name>/plot-6f220edc-412a-4f4f-b065-0015fdc38077.csv.

jenkins@f3d79016545d:~$ cat /var/jenkins_home/jobs/frontend/plot-6f220edc-412a-4f4f-b065-0015fdc38077.csv
"Title","Chunks sizes"
"Value","Series Label","Build Number","Build Date","URL"
"3.7","common","20","1643543937619",""
"7.5","polyfills","20","1643543937619",""
"14.3","polyfills-es5","20","1643543937619",""
"43.2","runtime","20","1643543937619",""
"6.7","scripts","20","1643543937619",""
"13.7","styles","20","1643543937619",""
"10.1","vendor","20","1643543937619",""
"3.82","common","21","1643543979599",""
"7.34","polyfills","21","1643543979599",""
"14.34","polyfills-es5","21","1643543979599",""
"43.2","runtime","21","1643543979599",""
"6.71","scripts","21","1643543979599",""
"13.73","styles","21","1643543979599",""
...

Вывести таким образом можно любые данные из любого проекта, это были всего лишь пару примеров для front-end проекта. К сожалению данный плагин не имеет хорошей документации, надеюсь эта статья немного исправит это положение.

Ссылки на источники

  1. Plot plugin
  2. Pipeline Step Reference