-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added output as JSON #375
base: master
Are you sure you want to change the base?
Added output as JSON #375
Conversation
d9c71b5
to
704a824
Compare
This need to be merged! I need it! |
Why has not that been done yet? |
@wg Any news ? |
} | ||
printf(" \"runtime\": %"PRIu64",\n", runtime_us); | ||
printf(" \"bytes\": %"PRIu64",\n", bytes); | ||
printf(" \"bytes_per_sec\": %Lf,\n", bytes_per_s); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSON is for machine. Why bytes_per_sec
is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Several reason, because:
- It is declared in the original text output
- it is internally calculated and without documentation, no one is expected to know how you get it
- If the value could be given by the output instead of code the calculation elsewhere, it's better
- There's no cost to give it to user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- It is declared in the original text output
I don't think JSON output should be same to original text output. Text is mainly for human. But JSON is more for machine.
Too detailed information for human eye are omitted in text output, but it can be included in JSON.
On the other hand, values easily calculated by other values can be omitted in JSON.
People expect backward compatibility about JSON format.
Adding items later is easy. Removing or changing items later is difficult.
So you should be careful about choosing which value is included, and how to format it.
it is internally calculated and without documentation, no one is expected to know how you get it
If the value could be given by the output instead of code the calculation elsewhere, it's better
There's no cost to give it to user
All of these reasons seems not enough for inclusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@methane You don't say why it shouldn't be included.
Otherwise, even you know the runtime and wrk knows the number of transfered bytes. The throughput is still a value researched by a lot of people.
printf(" \"latency_percentile_90\": %.2Lf,\n", lat_perc_90); | ||
printf(" \"latency_percentile_90\": %.2Lf,\n", lat_perc_90); | ||
printf(" \"latency_percentile_95\": %.2Lf,\n", lat_perc_95); | ||
printf(" \"latency_percentile_99\": %.2Lf,\n", lat_perc_99); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really beautiful? How about
"latency_percentile": {
"50": ...
"75": ...
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful or not, I think it in several aspects:
- It gives exactly what a user could need.
- I kept code simple and readable
I'm not against a new format, but let @wg decide about it.
This is duplicate of #72 and there are no describe about why report.lua is not enough. Addtionally, I expect more detailed information for JSON. I don't expect "for human" information (like avg) in JSON. For example, someone may want histogram instead of percentile. If wrk has |
long double lat_perc_95 = stats_percentile(statistics.latency, 95.0) / 1000000.0; | ||
long double lat_perc_99 = stats_percentile(statistics.latency, 99.0) / 1000000.0; | ||
printf("{\n"); | ||
printf(" \"url\": \"%s\",\n", url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems not be escaped here. Is this %s
secure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by secure ?
If you think about code injection, this is just JSON. And a parser would expect only 1 object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If someone do this.
#!/bin/sh
RESULT=$(wrk -j ...)
my-dommand $RESULT
With url
is "} || sudo rm /etc/passwd #
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will give:
my-dommand {"url": ""} || sudo rm /etc/passwd", "script": null}
So the ending quote is missing
Feel free to propose an enhancement 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look my code #
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which code are you talking about ?
If you're pointing me the ending #
, the problem is still not here as the closing quote "
is not here. In interactive terminal, it will wait for you to close quotes. And in non-interactive, it will raise a syntax error.
Hello @methane
Here's an example of output:
Your link is pointing to an issue, not a pull request, but yes, there were several (closed) contributions about JSON output:
This is a first contribution of JSON output and it actually gives more than the existing text one with more accuracy. Your example of histogram is a totally other feature/PR. Otherwise it could be enabled with the
It's not hard if you warn users. People could expect changement if they change major or minor version.
Solutions aren't mutually exclusive, the ability to use LuA isn't erased by the JSON option |
"report.lua" is just an example. You can propose adding "reportjson.lua" example. |
...
...
I meant you should describe these reasoning before sending PR with only "Hello I added JSON output option", and pinging. Especially for features already rejected in the past. |
@methane thank you for taking the time to review and comment on this PR! @ZuluPro as methane points out it should be possible to generate a JSON report using the Lua scripting API. This is preferable to hard-coding reports in wrk itself because everyone will have different requirements for format, content, etc. My recommendation would be to develop JSON reporting as a Lua script and publish it as a blog post or to your own GitHub repo. I've left this repo's wiki open and it'd be a great contribution if you wanted to curate a page about available scripts and including yours. |
Hello @wg Except the latency details, the output gives almost everything, so no one could ask more data. If someone has issue with format it would be JSON's keys or unit of measurement: nothing hard as JSON is typed and machine readable. I would like to point the project's audience : Benchmarkers. You are asking for LuA programming just to be able to have machine-readable output. For a sysadmin, your project stay a handy tool, but just for human eyes. |
As said, people who aren't programmers won't use scripts. Seeing reaction on top of this PR, I think a lot of people are agreed.
I saw the other PR after did mine, seeing the popularity of this project I didn't think this feature could be already rejected. About reason, nowadays, it's obvious that a machine-readable output is a base requirements for a benchmark command. |
I tried to implement sample implementation of JSON output. https://gist.github.com/methane/8bb4fedf27e4d13db80078302f8954da As you can see, it's difficult to combine with tools like jq by pipe. |
Yes this is why my Does the lua environment allow to disable the default output ? |
I'd suggest writing JSON output to a file whose path is specified via a script arg. Most likely someone who wants machine-readable output is also invoking wrk with a script. Easy enough to record the command line parameters in that script, generate a temp file name, pass that to wrk and read the results if wrk completes successfully. |
@wg But with your suggestion we lose the ability to just pipe to another command, i.e. a JSON parser. As what I coded is an option, it doesn't change the default behavior, but the new output should be also be given in usual conditions. |
If so, why didn't describe it from first?
Using pipe is not a strict requirement for me. |
@wg How can I use script args from |
@methane good question, it's a little tricky since I'd use some Lua JSON library like https://github.com/rxi/json.lua to avoid a lot of ugly manual JSON building and then a script like: json = require "json"
function setup(thread)
thread0 = thread0 or thread
end
function init(args)
file = args[1] or "/dev/null"
end
function done(summary, latency, requests)
file = io.open(thread0:get("file"), "w")
percentiles = {}
for _, p in pairs({ 50, 90, 99, 99.999 }) do
k = string.format("%g%%", p)
v = latency:percentile(p)
percentiles[k] = v
end
file:write(json.encode({
duration = summary.duration,
requests = summary.requests,
bytes = summary.bytes,
errors = summary.errors,
latency = {
min = latency.min,
max = latency.max,
mean = latency.mean,
stdev = latency.stdev,
percentiles = percentiles,
},
}))
file:close()
end Run as |
Wow, good example! |
I also need this option. Lua script is highly customisable, but it not helps. It just makes everything more complicated ( Why messing with additional files, when you could add just a small parameter to command? It would be so much easier... |
Hey folks, any updates on this one? |
Hello I added JSON output option with -j / --json-output.
Other outputs are disabled if JSON is enabled ande vice-versa.