order api results by descending totalExecTime (with option of adding a query parameter)

This commit is contained in:
gmega 2023-11-03 14:51:00 -03:00
parent f99a516203
commit 19d90191d8
No known key found for this signature in database
GPG Key ID: FFD8DAF00660270F
3 changed files with 48 additions and 7 deletions

View File

@ -195,8 +195,13 @@ proc initDataApi(node: CodexNodeRef, router: var RestRouter) =
router.api(
MethodGet,
"/api/codex/v1/debug/performance") do () -> RestApiResponse:
RestApiResponse.response(
$(%(getFutureSummaryMetrics())), contentType="application/json")
# Returns profiling information, highest totalExecTime first
without metrics =? sortBy(%(getFutureSummaryMetrics()),
"totalExecTime").catch, error:
return RestApiResponse.error(Http500, error.msg)
RestApiResponse.response($(metrics), contentType="application/json")
proc initSalesApi(node: CodexNodeRef, router: var RestRouter) =
router.api(

View File

@ -1,5 +1,5 @@
## Utilities for serializing profiler metrics.
import std/algorithm
import std/json
import asyncprofiler
@ -10,7 +10,7 @@ proc `%`*(o: Duration): JsonNode =
proc `%`*(o: cstring): JsonNode =
%($(o))
proc `%`*(o: MetricsSummary): JsonNode =
proc toJson*(o: MetricsSummary): JsonNode =
var rows = newJArray()
for (location, metric) in o.pairs:
var row = %(metric)
@ -18,3 +18,11 @@ proc `%`*(o: MetricsSummary): JsonNode =
rows.add(row)
rows
proc `%`*(o: MetricsSummary): JsonNode = o.toJson()
proc sortBy*(jArray: JsonNode, metric: string): JsonNode {.raises: [ref KeyError].} =
%(jArray.getElems.sorted(
proc (a, b: JsonNode): int {.raises: [ref KeyError].} =
cmp(a[metric].getInt, b[metric].getInt),
order=SortOrder.Descending))

View File

@ -1,3 +1,4 @@
import std/sequtils
import std/tables
import std/unittest
import std/json
@ -14,7 +15,7 @@ checksuite "asyncprofiler utils":
line: 1
)
let metric = OverallMetrics(
let fooMetric = OverallMetrics(
totalExecTime: 2.seconds,
totalRunTime: 2.seconds,
totalWallTime: 2.seconds,
@ -24,7 +25,7 @@ checksuite "asyncprofiler utils":
)
test "should serialize OverallMetrics":
check %metric == %*{
check %fooMetric == %*{
"totalExecTime": 2000000000,
"totalRunTime": 2000000000,
"totalWallTime": 2000000000,
@ -42,7 +43,7 @@ checksuite "asyncprofiler utils":
test "should serialize MetricsSummary":
var summary: MetricsSummary = {
(addr fooLoc): metric
(addr fooLoc): fooMetric
}.toTable
check %summary == %*[%*{
@ -58,3 +59,30 @@ checksuite "asyncprofiler utils":
"maxSingleTime": 1500000000,
"count": 10
}]
test "should sort MetricsSummary by the required key":
var barLoc = SrcLoc(
procedure: "bar",
file: "bar.nim",
line: 1
)
var barMetrics = OverallMetrics(
totalExecTime: 3.seconds,
totalRunTime: 1.seconds,
totalWallTime: 1.seconds,
minSingleTime: 100.nanoseconds,
maxSingleTime: 1500.milliseconds,
count: 5
)
var summary: MetricsSummary = {
(addr fooLoc): fooMetric,
(addr barLoc): barMetrics
}.toTable
check (%summary).sortBy("totalExecTime").getElems.map(
proc (x: JsonNode): string = x["location"]["procedure"].getStr) == @["bar", "foo"]
check (%summary).sortBy("count").getElems.map(
proc (x: JsonNode): string = x["location"]["procedure"].getStr) == @["foo", "bar"]