commit 04d982393b89e9663c5254fb3c0b3bd33d26f8c4 from: Sergey Bronnikov date: Wed Jul 17 11:10:45 2024 UTC perf/lua: add context section to test output Google Benchmark output format contains a section "context" that describes useful information about test environment. Google Benchmark output format has been supported in Lua microbenchmarks in commit 3110ef9a9498 ("perf: introduce benchmark.lua helper module"). However, produced output contains test results only and section "context" is missed. The patch add a section "context" with the following fields: date, load average, hostname, tarantool's version, build flags and a name of build target. ``` $ tarantool uri_escape_unescape.lua --output=res.json --output_format=json $ jq ".context" res.json { "build_target": "Linux-x86_64-RelWithDebInfo", "host_name": "pony", "date": "2024-07-04 19:09:11", "tarantool_version": "3.2.0-entrypoint-114-g9e5dca29ad", "build_flags": " -fexceptions -funwind-tables -fasynchronous-unwind-tables -fno-common -msse2 -Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIC -fmacro-prefix-map=/home/sergeyb/sources/MRG/tarantool=. -std=c11 -Wall -Wextra -Wno-gnu-alignof-expression -Wno-cast-function-type -O2 -g -DNDEBUG -ggdb -O2 ", "load_avg": [ "0.76", "0.74", "0.63" ] } ``` NO_CHANGELOG=perf NO_DOC=perf NO_TEST=perf commit - 25f860db29201fdf2da287eaf46bc19d7039330b commit + 04d982393b89e9663c5254fb3c0b3bd33d26f8c4 blob - a4c73127125270195457b164b327d2595ec5e28e blob + e76d7bdb6a1fa7d2ba2b29c755d5641d06ee9569 --- perf/lua/benchmark.lua +++ perf/lua/benchmark.lua @@ -34,6 +34,8 @@ local json = require('json') local fio = require('fio') local argparse = require('internal.argparse') +local tarantool = require('tarantool') +local datetime = require('datetime') local M = {} @@ -45,7 +47,10 @@ local function format_report(bench) -- The output should have the same format as the Google -- Benchmark JSON output format: -- https://github.com/google/benchmark/blob/main/docs/user_guide.md - report = json.encode({benchmarks = results}) + report = json.encode({ + benchmarks = results, + context = bench.context, + }) else assert(output_format == 'console', 'unknown output format') for _, res in ipairs(results) do @@ -119,6 +124,40 @@ function M.argparse(arg, argtable, custom_help) return params end +local function load_average() + local path = '/proc/loadavg' + local fh = assert(fio.open(path, {'O_RDONLY'})) + local loadavg_buf = fh:read(1024) + fh:close() + -- Format is '0.89 0.66 0.80 2/1576 1203510'. + local loadavg_re = '(%d+.%d+) (%d+.%d+) (%d+.%d+)' + + return { string.match(loadavg_buf, loadavg_re) } +end + +-- Google Benchmark reports contains a date in ISO 8061 format, +-- example: 2013-07-01T17:55:13-07:00. +-- See an implementation of `LocalDateTimeString()` in +-- Google Benchmark library source code [1]. +-- The function return a ISO 8061 formatted timestamp. +-- +-- 1. https://github.com/google/benchmark/blob/65668db27365d29ca4890cb2102e81acb6585b43/src/timers.cc#L209 +-- @return e.g. 2024-07-17T12:46:31+03:00 +local function iso_8061_timestamp() + return datetime.new(os.date('*t')):format('%FT%T.%f%z') +end + +local function perf_context() + return { + build_flags = tarantool.build.flags, + build_target = tarantool.build.target, + date = iso_8061_timestamp(), + host_name = io.popen('hostname'):read(), + load_avg = load_average(), + tarantool_version = tarantool.version, + } +end + function M.new(opts) assert(type(opts) == 'table', 'given argument should be a table') local output_format = opts.output_format or 'console' @@ -126,6 +165,7 @@ function M.new(opts) output = opts.output, output_format = output_format:lower(), results = {}, + context = perf_context(), }, {__index = { add_result = add_result, dump_results = dump_results,