Skip to content

Commit 56b473f

Browse files
committed
Fix GH-195: Fix JSON reporter to produce valid JSON
sysbench.report_json() now generates well-formed JSON without comma after the last array element and with proper opening/closing brackets.
1 parent b316938 commit 56b473f

5 files changed

Lines changed: 109 additions & 78 deletions

File tree

src/lua/internal/sysbench.lua

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,27 +88,37 @@ function sysbench.report_csv(stat)
8888
))
8989
end
9090

91-
-- Report statistics in the CSV format. Add the following to your
91+
-- Report statistics in the JSON format. Add the following to your
9292
-- script to replace the default human-readable reports
9393
--
9494
-- sysbench.hooks.report_intermediate = sysbench.report_json
9595
function sysbench.report_json(stat)
96+
if not gobj then
97+
io.write('[\n')
98+
-- hack to print the closing bracket when the Lua state of the reporting
99+
-- thread is closed
100+
gobj = newproxy(true)
101+
getmetatable(gobj).__gc = function () io.write('\n]\n') end
102+
else
103+
io.write(',\n')
104+
end
105+
96106
local seconds = stat.time_interval
97-
print(string.format([[
98-
{
99-
"time": %4.0f,
100-
"threads": %u,
101-
"tps": %4.2f,
102-
"qps": {
103-
"total": %4.2f,
104-
"reads": %4.2f,
105-
"writes": %4.2f,
106-
"other": %4.2f
107-
},
108-
"latency": %4.2f,
109-
"errors": %4.2f,
110-
"reconnects": %4.2f
111-
},]],
107+
io.write(([[
108+
{
109+
"time": %4.0f,
110+
"threads": %u,
111+
"tps": %4.2f,
112+
"qps": {
113+
"total": %4.2f,
114+
"reads": %4.2f,
115+
"writes": %4.2f,
116+
"other": %4.2f
117+
},
118+
"latency": %4.2f,
119+
"errors": %4.2f,
120+
"reconnects": %4.2f
121+
}]]):format(
112122
stat.time_total,
113123
stat.threads_running,
114124
stat.events / seconds,

src/sb_lua.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,10 @@ int sb_lua_report_thread_init(void)
16351635
return 0;
16361636
}
16371637

1638-
void sb_lua_report_thread_done(void)
1638+
void sb_lua_report_thread_done(void *arg)
16391639
{
1640-
sb_lua_close_state(tls_lua_ctxt.L);
1640+
(void) arg; /* unused */
1641+
1642+
if (sb_lua_loaded())
1643+
sb_lua_close_state(tls_lua_ctxt.L);
16411644
}

src/sb_lua.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Copyright (C) 2006 MySQL AB
2-
Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
2+
Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com>
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -37,6 +37,6 @@ int sb_lua_call_custom_command(const char *name);
3737

3838
int sb_lua_report_thread_init(void);
3939

40-
void sb_lua_report_thread_done(void);
40+
void sb_lua_report_thread_done(void *);
4141

4242
bool sb_lua_loaded(void);

src/sysbench.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,7 @@ static void report_intermediate(void)
220220
silence intermediate reports at the end of the test
221221
*/
222222
if (ck_pr_load_uint(&sb_globals.report_interval) == 0)
223-
{
224223
return;
225-
}
226224

227225
sb_counters_agg_intermediate(cnt);
228226
report_get_common_stat(&stat, cnt);
@@ -914,9 +912,9 @@ static void *report_thread_proc(void *arg)
914912
sb_rand_thread_init();
915913

916914
if (sb_lua_loaded() && sb_lua_report_thread_init())
917-
{
918915
return NULL;
919-
}
916+
917+
pthread_cleanup_push(sb_lua_report_thread_done, NULL);
920918

921919
log_text(LOG_DEBUG, "Reporting thread started");
922920

@@ -944,6 +942,8 @@ static void *report_thread_proc(void *arg)
944942
pause_ns = next_ns - curr_ns;
945943
}
946944

945+
pthread_cleanup_pop(1);
946+
947947
return NULL;
948948
}
949949

@@ -963,9 +963,9 @@ static void *checkpoints_thread_proc(void *arg)
963963
sb_rand_thread_init();
964964

965965
if (sb_lua_loaded() && sb_lua_report_thread_init())
966-
{
967966
return NULL;
968-
}
967+
968+
pthread_cleanup_push(sb_lua_report_thread_done, NULL);
969969

970970
log_text(LOG_DEBUG, "Checkpoints report thread started");
971971

@@ -990,8 +990,7 @@ static void *checkpoints_thread_proc(void *arg)
990990
report_cumulative();
991991
}
992992

993-
if (sb_lua_loaded())
994-
sb_lua_report_thread_done();
993+
pthread_cleanup_pop(1);
995994

996995
return NULL;
997996
}
@@ -1149,26 +1148,6 @@ static int run_test(sb_test_t *test)
11491148
if (test->ops.cleanup != NULL && test->ops.cleanup() != 0)
11501149
return 1;
11511150

1152-
/* print test-specific stats */
1153-
if (!sb_globals.error)
1154-
{
1155-
if (sb_globals.histogram)
1156-
{
1157-
log_text(LOG_NOTICE, "Latency histogram (values are in milliseconds)");
1158-
sb_histogram_print(&sb_latency_histogram);
1159-
log_text(LOG_NOTICE, " ");
1160-
}
1161-
1162-
report_cumulative();
1163-
}
1164-
1165-
pthread_mutex_destroy(&sb_globals.exec_mutex);
1166-
1167-
/* finalize test */
1168-
if (test->ops.done != NULL)
1169-
(*(test->ops.done))();
1170-
1171-
/* Delay killing the reporting threads to avoid mutex lock leaks */
11721151
if (report_thread_created)
11731152
{
11741153
if (sb_thread_cancel(report_thread) || sb_thread_join(report_thread, NULL))
@@ -1189,6 +1168,25 @@ static int run_test(sb_test_t *test)
11891168
log_errno(LOG_FATAL, "Terminating the checkpoint thread failed.");
11901169
}
11911170

1171+
/* print test-specific stats */
1172+
if (!sb_globals.error)
1173+
{
1174+
if (sb_globals.histogram)
1175+
{
1176+
log_text(LOG_NOTICE, "Latency histogram (values are in milliseconds)");
1177+
sb_histogram_print(&sb_latency_histogram);
1178+
log_text(LOG_NOTICE, " ");
1179+
}
1180+
1181+
report_cumulative();
1182+
}
1183+
1184+
pthread_mutex_destroy(&sb_globals.exec_mutex);
1185+
1186+
/* finalize test */
1187+
if (test->ops.done != NULL)
1188+
(*(test->ops.done))();
1189+
11921190
return sb_globals.error != 0;
11931191
}
11941192

tests/t/api_reports.t

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Tests for custom report hooks
33
########################################################################
44

55
# Trigger one intermediate and one cumulative report
6-
$ SB_ARGS="api_reports.lua --time=3 --report-interval=2 --verbosity=1"
6+
$ SB_ARGS="api_reports.lua --time=5 --report-interval=2 --verbosity=1"
77

88
########################################################################
99
# Default human-readable format via a custom hook
@@ -22,7 +22,8 @@ Tests for custom report hooks
2222

2323
$ sysbench $SB_ARGS run
2424
\[ 2s \] thds: 1 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re)
25-
\[ 3s \] thds: 0 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re)
25+
\[ 4s \] thds: 1 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re)
26+
\[ 5s \] thds: 0 tps: [0-9]*\.[0-9]* qps: 0\.00 \(r\/w\/o: 0\.00\/0\.00\/0\.00\) lat \(ms,95%\): [1-9][0-9]*\.[0-9]* err\/s 0\.00 reconn\/s: 0\.00 (re)
2627

2728
########################################################################
2829
# CSV format via a custom hook
@@ -41,7 +42,8 @@ Tests for custom report hooks
4142

4243
$ sysbench $SB_ARGS run
4344
2,1,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re)
44-
3,0,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re)
45+
4,1,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re)
46+
5,0,[0-9]*\.[0-9]*,0\.00,0\.00,0\.00,0\.00,[1-9][0-9]*\.[0-9]*,0\.00,0\.00 (re)
4547

4648
########################################################################
4749
# JSON format via a custom hook
@@ -59,31 +61,49 @@ Tests for custom report hooks
5961
> EOF
6062

6163
$ sysbench $SB_ARGS run
62-
{
63-
"time": 2,
64-
"threads": 1,
65-
"tps": *.*, (glob)
66-
"qps": {
67-
"total": 0.00,
68-
"reads": 0.00,
69-
"writes": 0.00,
70-
"other": 0.00
64+
[
65+
{
66+
"time": 2,
67+
"threads": 1,
68+
"tps": *.*, (glob)
69+
"qps": {
70+
"total": 0.00,
71+
"reads": 0.00,
72+
"writes": 0.00,
73+
"other": 0.00
74+
},
75+
"latency": [1-9][0-9]*\.[0-9]*, (re)
76+
"errors": 0.00,
77+
"reconnects": 0.00
7178
},
72-
"latency": [1-9][0-9]*\.[0-9]*, (re)
73-
"errors": 0.00,
74-
"reconnects": 0.00
75-
},
76-
{
77-
"time": 3,
78-
"threads": 0,
79-
"tps": *.*, (glob)
80-
"qps": {
81-
"total": 0.00,
82-
"reads": 0.00,
83-
"writes": 0.00,
84-
"other": 0.00
85-
},
86-
"latency": [1-9][0-9]*\.[0-9]*, (re)
87-
"errors": 0.00,
88-
"reconnects": 0.00
89-
},
79+
{
80+
"time": 4,
81+
"threads": 1,
82+
"tps": *.*, (glob)
83+
"qps": {
84+
"total": 0.00,
85+
"reads": 0.00,
86+
"writes": 0.00,
87+
"other": 0.00
88+
},
89+
"latency": [1-9][0-9]*\.[0-9]*, (re)
90+
"errors": 0.00,
91+
"reconnects": 0.00
92+
}
93+
]
94+
[
95+
{
96+
"time": 5,
97+
"threads": 0,
98+
"tps": *.*, (glob)
99+
"qps": {
100+
"total": 0.00,
101+
"reads": 0.00,
102+
"writes": 0.00,
103+
"other": 0.00
104+
},
105+
"latency": [1-9][0-9]*\.[0-9]*, (re)
106+
"errors": 0.00,
107+
"reconnects": 0.00
108+
}
109+
]

0 commit comments

Comments
 (0)