-
Notifications
You must be signed in to change notification settings - Fork 19
/
short_summary.clj
73 lines (65 loc) · 3.15 KB
/
short_summary.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
(ns trombi.reporters.short-summary
(:require [clojure.set :refer [rename-keys]]))
(def generator
(fn [_]
{:generate identity
:as-str (fn [{:keys [ok ko response-time]
:or {ko 0 ok 0}}]
(let [total (+ ok ko)]
(str "Total number of requests: " total
", successful: " ok
", failed: " ko
" with mean " (-> response-time :global :mean) " ms.")))}))
(defn- mean [data]
(Math/round (double (/ (reduce + data) (count data)))))
(defn- weighted-mean [value1 sample-size1 value2 sample-size2]
;Return weighted mean based on sample sizes
(Math/round (double (/ (+ (* value1 sample-size1) (* value2 sample-size2))
(+ sample-size1 sample-size2)))))
(defn- combine [data1 data2]
(let [sample-size1 (+ (:ok data1) (:ko data1))
sample-size2 (+ (:ok data2) (:ko data2))]
(-> data1
(update :ok + (:ok data2))
(update :ko + (:ko data2))
(update-in [:response-time :global :min] min (-> data2
:response-time
:global
:min))
(update-in [:response-time :global :max] max (-> data2
:response-time
:global
:max))
;To get accurate mean we should use all the data points for the calculation
;However, that would require either storing all the data points to memory
;or then writing intermediate results to disk
;short-summary tries to be fast and memory efficient.
;So we use weighted mean based on sample sizes which is accurate enough
(update-in [:response-time :global :mean] weighted-mean
sample-size1
(-> data2
:response-time
:global
:mean)
sample-size2))))
(defn- collect [_ {:keys [batch]}]
(let [request-results (mapcat #(map :result (:requests %)) batch)
request-times (mapcat #(map (fn [{:keys [start end]}]
(- end start)) (:requests %)) batch)
freqs (frequencies request-results)
;;TODO Simulation should not return nil (it should return false instead)
req-counts (merge-with + (rename-keys freqs {true :ok
false :ko
nil :ko})
{:ok 0 :ko 0})]
(assoc req-counts :response-time {:global {:min (apply min request-times)
:max (apply max request-times)
:mean (mean request-times)}})))
(def collector
(fn [_]
{:collect collect
:combine combine}))
(def reporter
{:reporter-key :short
:collector 'trombi.reporters.short-summary/collector
:generator 'trombi.reporters.short-summary/generator})