Введение
Наверняка каждый, кто пользовался стандартными листенерами в JMeter, сталкивался со следующими ограничениями:
- стандартные листенеры не позволяют получить подробную информацию по всем запросам, прописанным в тест плане;
- стандартные листенеры выводят информацию в XML — формате, что осложняет дальнейший анализ логов средствами Excel и IPython.
Чтобы обойти данные ограничения, было принято решение переработать формирование лог-файлов с помощью нового плагина CsvLogWriter.
Поставленные задачи
Необходимо было разработать плагин для JMeter, который обладал бы следующими функциональными возможностями:
- вывод полного текста ошибки в строковом формате;
- фиксация данных по дочерним подзапросам.
В стандартных листенерах для JMeter фиксация полного содержания ошибки возможна в XML-формате, что доставляет неудобства для анализа. Возникла потребность сохранять текст ошибки в строковом формате с последующей записью, например, в CSV-формат для обеспечения возможности построения графиков в Excel и IPython. Обычно получаемые лог-файлы не отображают данные по дочерним подзапросам. Что крайне неудобно при использовании сложной структуры тест-плана. Пример структуры продемонстрирован на рисунке 1.

Рисунок 1. Структура тест-плана
При использовании стандартных листенеров мы сможем получить данные только по Transaction Controller1. Исходя из этого было решено добавить фиксацию данных по дочерним подзапросам, таким образом получить результаты мы сможем по Transaction Controller1, Transaction Controller 2 и вложенным в него семплерам.
Описание функционала плагина pflb@CsvLogWriter
В ходе работы был написан плагин pflb@CsvLogWriter для JMeter. К ключевым особенностям данного плагина можно отнести то, что он может фиксировать результаты работы дочерних подзапросов и записывать полный текст ошибки, при ее возникновении, в виде обычного текста, а не в XML-формате.
Формат лога
Данные, фиксируемые в лог-файле, представлены в таблице 1.
Таблица 1. Формат лога
№
Имя
Тип
Описание
Примеры значений для колонки лога
Единица измерения
1
timeStamp
long
Время начала или конца запроса
мс
2
elapsed
long
Длительность обработки запроса: endTime — startTime — idleTime
49, 434
мс
3
label
String
Наименование компонента JMeter
4
responseCode
String
Код ответа на запрос
«200», «Non HTTP response code: java.net.UnknownHostException»
5
responseMessage
String
Расшифровка кода ответа
«OK», «Internal Server Error»
6
threadName
String
Имя потока
«Thread Group 1-1»
7
dataType
String
Тип данных в ответе, на практике принимает два значения — «bin» или «text»
«bin», «text»
8
success
boolean
Статус успешности выполнения запроса
true или false
9
failureMessage
String
Сообщение об ошибке,
в случае срабатывания Assertion-компонента,
добавленного к Sampler-у.
В CsvLogWriter в поле записываются сообщения
ото всех Assertion-компонентов,
выполнение которых сгенерировало ошибку.
В базовом логере записывается только первое сообщение.
10
bytes
int
Размер ответа.
Значение и алгоритм расчёта зависят от настроек
sampler-а. На значение могут влиять responseData.length,
headersSize, bodySize.
Байт
11
grpThreads
int
Количество активных потоков в текущей группе
12
allThreads
int
Количество активных виртуальных пользователей всех групп
13
URL
String
Ссылка
14
Filename
String
Наименования файла, в который записываются ответы.
Поле заполняется при использовании Save Response to File Listener.
Этот Listener редко используется, обычно значение колонки
— пустая строка
15
Latency
int
Время до получения первого ответа сервера.
Эта временная задержка включает в себя время,
потраченное на соединение с сервером,
задержки, обусловленные установкой защищённого соединения,
и внутренними задержками JMeter на получение
первых байт ответа сервера. Если по какой-то причине
работа Sampler-а была приостановлена, а потом возобновлена,
то значение Latency будет скорректировано
на длительность приостановки Sampler-а.
мс
16
Encoding
String
Кодировка. Возвращается кодировка ответа,
если кодировка ответа не задана,
то возвращается значение кодировки по умолчанию.
Значение кодировки по умолчанию задано в
«sampleresult.default.encoding».
Для HTTP Request значение по умолчанию «ISO-8859-1».
«ISO-8859-1», «UTF-8»
17
SampleCount
int
Количество семплов.
Для HTTP Request значение равно 1.
Для JMS Sampler, выполняющего подписку на события
и чтение нескольких сообщений за раз,
значение равно количеству циклов опроса
или количеству прочитанных сообщений.
Значение всегда больше или равно одному.
1, 2
шт
18
ErrorCount
int
Количество ошибок.
Для HTTP Request значение равно 0 если success
и равно 1 если запрос не успешный.
Для других sampler-ов выполняющих обработку
нескольких сообщений за раз,
значение может быть больше 1.
0, 1
шт
19
Hostname
String
Наименование машины
20
IdleTime
int
Время простоя
мс
21
Connect
int
Время, затраченное на установку соединения
мс
22
headersSize
int
Размер заголовков
Байт
23
bodySize
int
Размера тела
Байт
24
contentType
String
Тип содержимого из заголовка ответа
25
endTime
long
Время конца запроса
мс
26
isMonitor
boolean
Признак поставлена ли галочка Use as Monitor
true, false
27
threadName_label
String
Наименование треда и компонента JMeter
28
parent_threadName_label
String
Наименование треда и компонента JMeter родителя
29
startTime
long
Время начала запроса
мс
30
stopTest
boolean
Признак остановлен ли тест — кнопка Stop.
Также в настройках Thread Group есть опция
«Stop Test» при ошибке. Если в колонке «stopTest»
стоит true, значит произошла именно такая ситуация.
Сценарий прервался на текущем запросе.
true, false
31
stopTestNow
boolean
Признак остановлен ли тест резко — кнопка Shutdown.
Также в настройках Thread Group есть опция
«Stop Test Now» при ошибке. Если в колонке «stopTestNow»
стоит true, значит произошла именно такая ситуация.
Сценарий прервался на текущем запросе.
true, false
32
stopThread
boolean
Признак остановлен ли текущий поток.
В настройках Thread Group есть опция «Stop Thread»
при ошибке. Если в колонке «stopThread» стоит true,
значит произошла именно такая ситуация.
Сценарий прервался на текущем запросе.
true, false
33
startNextThreadLoop
boolean
Стартует ли повтор.
В настройках Thread Group есть опция «Start Next Thread Loop»
при ошибке. Если в колонке «startNextThreadLoop» стоит true,
значит произошла именно такая ситуация.
Сценарий прервался на текущем запросе.
true, false
34
isTransactionSampleEvent
boolean
Признак того, что текущее событие является транзакцией (TransactionController). То есть, это лишь группирующий элемент.
true, false
35
transactionLevel
int
Уровень вложенности запроса.
Если используется иерархия Transaction Controller
или у подзапросов есть подзапросы,
то в данной колонке будет уровень вложенности.
0 для корневого запроса или корневого Transaction Controller.
1 для подзапроса, родитель которого является корневым.
36
responseDataAsString
String
Полное содержание ошибки в формате строки
в случае ее возникновения, если success == false,
то в responseData будет содержаться полное тело ответа
37
requestHeaders
String
Заголовки запроса
38
responseData
String
Полное содержание ошибки в случае ее возникновения,
если success == false, то в responseData будет содержаться
полное тело ответа, перекодированное в base64
39
responseHeaders
String
Заголовки ответа
40
<Имя переменной>
String
Переменные JMeter
Структура лога расширяет базовый формат CSV лога. С базовым набором параметров можно ознакомиться по ссылке jmeter.apache.org/usermanual/listeners.html#csvlogformat
Полученный CSV-лог можно загрузить любым базовым Listener-ом JMeter, поддерживающим загрузку CSV-лога.
Также в логе появились дополнительные колонки, которые могут пригодится при анализе (стр. 22-35 таблицы Формат лога).
Тела и заголовки ответов и запросов записываются только при ошибках (стр. 36-39 таблицы Формат лога).
Также в лог запишутся колонки для переменных: jmeter.apache.org/usermanual/listeners.html#sample_variables — описание возможности логировать значения переменных.
Интерфейс
Для запуска плагина необходимо заполнить поле Filename. Поле Filename содержит путь к файлу, в котором будет вестись фиксация результатов работы. Можно прописать директорию вручную, или выбрать файл используя кнопку Browse. Если указанный файл существует, то создается новый файл. Наименование нового лог-файла формируется добавлением постфикса с номером лог-файла к оригинальному наименованию.
Так же на форме расположены флажки. С помощью флажков можно манипулировать данными, фиксируемыми в логе. Флажок Additional parameters отвечает за фиксацию дополнительных параметров (22-35 строки в таблице Формат лога), Response data отвечает за фиксацию текста ошибок (36-39 строки в таблице Формат лога), User variables отвечает за фиксацию пользовательских переменных.
Интерфейс плагина представлен на рисунке 2.

Рисунок 2. Интерфейс плагина CSVLogWriter
Сравнение плагина CSVLogWriter и Simple Data Writer
В данном разделе попробуем провести сравнение плагина CsvLogWriter и стандартного листенера Simple Data Writer.
Состав логируемых данных
Листенер Simple Data Writer дает пользователю возможность настроить список фиксируемых данных. На рисунке 3 показано окно настроек выводимых данных.

Рисунок 3. Окно настроек фиксируемых данных листенера Simple Data Writer
Плагин CsvLogWriter всегда выводит базовый перечень параметров (аналогичный Simple Data Writer) и позволяет настроить вывод списка дополнительных данных с помощью 3 флажков на форме:
- Additional parameters — дополнительные параметры (22-35 строки в таблице Формат лога);
- Response data — тексты ошибок (36-39 строки в таблице Формат лога);
- User variables — пользовательские переменные (для вывода необходимо запускать JMeter с ключом -Jsample_variables).
Детальный перечень фиксируемых данных жестко прописан в коде. Но, как видно на рисунке 3, Simple Data Writer не может выводить текст ошибки в строковом формате. Полный текст ошибки фиксируется только в XML формате. По этой причине в случае, когда нам необходим текст ошибок приходится вести 2 лога — 1 в CSV-формате (если необходима дальнейшая обработка лога с построением графиков в Excel или iPython) и 1 в XML-формате.
Логирование подзапросов
Так же, листенер Simple Data Writer не фиксирует результаты работы дочерних подзапросов, соответственно, такой лог-файл нельзя назвать исчерпывающим. Для наглядного сравнения объема выводимых данных запустим тест, соответствующий тест-плану на рисунке 1, и посмотрим на лог-файлы. Лог-файл SimpleDataWriter представлен на рисунке 4.

Рисунок 4. Лог-файл Simple Data Writer
Как видно на рисунке 4, SimpleDataWriter выводит информацию только по Transaction Controller1. В свою очередь, плагин CsvLogWriter за счет обработки дочерних подзапросов выводит гораздо больше информации. Содержание лог-файла плагина CsvLogWriter представлено на рисунке 5.

Рисунок 5. Лог-файл CsvLogWriter
Сравнение быстродействия
Так же проводился анализ быстродействия метода SimpleOccured, отвечающего за обработку событий. Профилирование велось в Java VisualVM. В тест плане не использовались подзапросы. Для SimpleDataWriter тестирование запускалось с записью в 1 CSV-файл и с записью в 2 файла — CSV и XML. Количество виртуальных пользователей составляло 10, количество повторение 100. Итоги сравнения приведены в таблице 2.
Таблица 2. Сравнение быстродействия SimpleDataWriter и плагина CsvLogWriter
CsvLogWriter
SimpleDataWriter (CSV+XML)
SimpleDataWriter (CSV)
Длительность (мс), количество вызовов
Длительность (мс), количество вызовов
Длительность (мс), количество вызовов
215, 2000
23076, 4000
101, 2000
Выводы:
- CsvLogWriter в 10 раз быстрее SimpleDataWriter (XML с максимальной детализацией);
- CsvLogWriter в 2 раза медленнее SimpleDataWriter (CSV с максимальной детализацией);
- SimpleDataWriter (XML с максимальной детализацией) в 20 раз медленнее SimpleDataWriter (CSV с максимальной детализацией).
Ссылка на плагин
github.com/pflb/Jmeter.Plugin.CsvLogWriter
Свежие комментарии