Skip to content
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

Changes required for json and multiserver testing support #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions scripts/json.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
-- example reporting script which demonstrates a custom
-- done() function that prints results as JSON

done = function(summary, latency, requests)
-- io.write("\nJSON Output:\n")
io.write("{\n")
io.write(string.format("\t\"requests\": %d,\n", summary.requests))
io.write(string.format("\t\"duration_in_microseconds\": %0.2f,\n", summary.duration))
io.write(string.format("\t\"bytes\": %d,\n", summary.bytes))
io.write(string.format("\t\"requests_per_sec\": %0.2f,\n", (summary.requests/summary.duration)*1e6))
io.write(string.format("\t\"bytes_transfer_per_sec\": %0.2f,\n", (summary.bytes/summary.duration)*1e6))
io.write(string.format("\t Min: %0.2f,\n", latency.min))
io.write(string.format("\t Avg: %0.2f,\n", latency.mean))
io.write(string.format("\t Max: %0.2f,\n", latency.max))
io.write(string.format("\t StdDev: %0.2f,\n", latency.stdev))


-- print(string.format("Total Requests: %d", summary.requests))
-- print(string.format("HTTP errors: %d", summary.errors.status))
-- print(string.format("Requests timed out: %d", summary.errors.timeout))
-- print(string.format("Bytes received: %d", summary.bytes))
-- print(string.format("Socket connect errors: %d", summary.errors.connect))
-- print(string.format("Socket read errors: %d", summary.errors.read))
-- print(string.format("Socket write errors: %d", summary.errors.write))

io.write("\t\"Percentiles\": [\n")
for _, p in pairs({ 50, 75, 90, 99, 99.9, 99.99, 99.999, 100 }) do
io.write("\t\t{\n")
--print(latency.total_count(50))
n = latency:percentile(p)
-- k = latency:total_count(p)
-- io.write(string.format("\t\t\t\"SAKOO\": %s,\n", latency:percentile(p)))

io.write(string.format("Percent: %g,\nValue: %f\n", p, n*0.001))
if p == 100 then
io.write("\t\t}\n")
else
io.write("\t\t},\n")
end
end
io.write("\t]\n}\n")
end
145 changes: 0 additions & 145 deletions scripts/multi-server.lua

This file was deleted.

184 changes: 184 additions & 0 deletions scripts/multiple-endpoints_in_json.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
-- This script extends wrk2 to handle multiple server addresses
-- as well as multiple paths (endpoints) per server

-----------------
-- main() context

-- main() globals
local threads = {}
local counter = 1

function setup(thread)
-- Fill global threads table with thread handles so done()
-- can process per-thread data
table.insert(threads, thread)
thread:set("id",counter)
counter = counter +1
math.randomseed(os.time())
end

-----------------
-- Thread context

function xtract(str, match, default, err_msg)
local ret, count = string.gsub(str, match, "%1", 1)
if count == 0 then
if not default then
-- print(string.format("Error parsing URL '%s': %s",str,err_msg))
os.exit(1)
end
ret = default
end
return ret
end

function init(args)
-- Thread globals used by done()
called_idxs = ""
urls = ""
-- Thread globals used by request(), response()
addrs = {}
idx = 0

-- table of lists; per entry:
-- proto, host, hostaddr, port, path + params
endpoints={}
-- tablre of prepared HTTP requests for endpoints above
reqs={}

-- parse command line URLs and prepare requests
for i=0, #args, 1 do
-- note that URL parsing does not support user/pass as
-- wrk2 does not support auth
local proto = xtract(args[i],
"^(http[s]?)://.*", nil, "missing or unsupported protocol")
local host = xtract(
args[i], "^http[s]?://([^/:]+)[:/]?.*", nil, "missing host")
local port = xtract(args[i], "^http[s]?://[^/:]+:(%d+).*", 80)
local path = xtract(args[i], "^http[s]?://[^/]+(/.*)","/")

-- get IP addr(s) from hostname, validate by connecting
local addr = nil
for k, v in ipairs(wrk.lookup(host, port)) do
if wrk.connect(v) then
addr = v
break
end
end
if not addr then
print(string.format(
"Error: Unable to connect to %s port %s.", host, port))
os.exit(2)
end

-- store the endpoint
endpoints[i] = {}
endpoints[i][0] = proto
endpoints[i][1] = host
endpoints[i][2] = addr
endpoints[i][3] = port
endpoints[i][4] = path
endpoints[i][5] = string.format(
"GET %s HTTP/1.1\r\nHost:%s:%s\r\n\r\n", path, host, port)
if urls == "" then
urls = args[i]
else
urls = string.format("%s,%s",urls,args[i])
end
end

urls = urls .. ","
-- initialize idx, assign req and addr
idx = math.random(0, #endpoints)
wrk.thread.addr = endpoints[idx][2]
end

function request()
local ret = endpoints[idx][5]
return ret
end


function response(status, headers, body)
-- add current index to string of endpointsi calle
local c = ","
if called_idxs == "" then c="" end
called_idxs = string.format("%s%s%s",called_idxs,c,idx)

-- Pick a new random endpoint for the next request
-- Also, update the thread's remote server addr if endpoint
-- is on a different server.
local prev_srv = endpoints[idx][2]
idx = math.random(0, #endpoints)
if prev_srv ~= endpoints[idx][2] then
-- Re-setting the thread's server address forces a reconnect
wrk.thread.addr = endpoints[idx][2]
end
end

-----------------
-- main() context

function done(summary, latency, requests)
-- print(string.format("Total Requests: %d", summary.requests))
-- print(string.format("HTTP errors: %d", summary.errors.status))
-- print(string.format("Requests timed out: %d", summary.errors.timeout))
-- print(string.format("Bytes received: %d", summary.bytes))
-- print(string.format("Socket connect errors: %d", summary.errors.connect))
-- print(string.format("Socket read errors: %d", summary.errors.read))
-- print(string.format("Socket write errors: %d", summary.errors.write))
-- generate table of URL strings from first thread's endpoints table
-- (all threads generate the same table in init())
io.write("{\n")
-- io.write(string.format("\"TotalRequests\": \"%d\",\n", summary.requests))
io.write(string.format("\"DurationInMicroseconds\": \"%0.2f\",\n", summary.duration))
io.write(string.format("\"Bytes\": \"%d\",\n", summary.bytes))
io.write(string.format("\"RequestsPerSec\": \"%0.2f\",\n", (summary.requests/summary.duration)*1e6))
io.write(string.format("\"BytesTransferPerSec\": \"%0.2f\",\n", (summary.bytes/summary.duration)*1e6))
io.write(string.format("\"MinLatency\": \"%0.2f\",\n", latency.min))
io.write(string.format("\"AvgLatency\": \"%0.2f\",\n", latency.mean))
io.write(string.format("\"MaxLatency\": \"%0.2f\",\n", latency.max))
io.write(string.format("\"StdDev\": \"%0.2f\",\n", latency.stdev))

local urls = {}
local counts = {}
local i = 0
t = unpack(threads,1,2)
t:get("urls"):gsub("([^,]+),",
function(u)
urls[i]=u
counts[i] = 0
i = i+1
end)

-- fetch url call counts of individual threads
local c = t:get("called_idxs")
c = c .. ","
for i, t in ipairs(threads) do
c:gsub("([0-9]+),", function(s)
i = tonumber(s)
counts[i] = counts[i] + 1
end)
end
for i=0, #urls, 1 do
print(string.format("\"Url_".. i+1 .."\": \"%s\",\n\"UrlRequestCount_".. i+1 .."\": %d,", urls[i], counts[i]))
end


io.write("\"Percentiles\": [\n")
for _, p in pairs({ 50, 75, 90, 99, 99.9, 99.99, 99.999, 100 }) do
io.write("\t\t{\n")
--print(latency.total_count(50))
n = latency:percentile(p)
-- k = latency:total_count(p)
-- io.write(string.format("\t\t\t\"SAKOO\": %s,\n", latency:percentile(p)))

io.write(string.format("\"Percent\": \"%g\",\n\"Value\": \"%f\"\n", p, n*0.001))
if p == 100 then
io.write("\t\t}\n")
else
io.write("\t\t},\n")
end
end
io.write("\t]\n}\n")
end
1 change: 1 addition & 0 deletions src/hdr_histogram.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ int64_t hdr_value_at_percentile(struct hdr_histogram* h, double percentile)
if (total >= count_at_percentile)
{
int64_t value_from_index = iter.value_from_index;
printf("\"Count\": \"%lld\",\n",count_at_percentile);
return highest_equivalent_value(h, value_from_index);
}
}
Expand Down
Loading