Software /
code /
prosody
Comparison
util/statistics.lua @ 6553:0e29c05c3503
util.statistics: New library for gathering various kinds of statistics
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Tue, 20 Jan 2015 12:31:32 +0000 |
child | 6555:7b2d16c14659 |
comparison
equal
deleted
inserted
replaced
6552:bcb834728ee5 | 6553:0e29c05c3503 |
---|---|
1 local t_sort = table.sort | |
2 local m_floor = math.floor; | |
3 local time = require "socket".gettime; | |
4 | |
5 local function nop_function() end | |
6 | |
7 local function percentile(arr, length, pc) | |
8 local n = pc/100 * (length + 1); | |
9 local k, d = m_floor(n), n%1; | |
10 if k == 0 then | |
11 return arr[1]; | |
12 elseif k >= length then | |
13 return arr[length]; | |
14 end | |
15 return arr[k] + d*(arr[k+1] - arr[k]); | |
16 end | |
17 | |
18 local function new_registry(config) | |
19 config = config or {}; | |
20 local duration_sample_interval = config.duration_sample_interval or 5; | |
21 local duration_max_samples = config.duration_max_stored_samples or 5000; | |
22 | |
23 local registry = {}; | |
24 local methods; | |
25 methods = { | |
26 amount = function (name, initial) | |
27 local v = initial or 0; | |
28 registry[name] = function () return "amount", v; end | |
29 return function (new_v) v = new_v; end | |
30 end; | |
31 counter = function (name, initial) | |
32 local v = initial or 0; | |
33 registry[name] = function () return "amount", v; end | |
34 return function (delta) | |
35 v = v + delta; | |
36 end; | |
37 end; | |
38 rate = function (name) | |
39 local since, n = time(), 0; | |
40 registry[name] = function () | |
41 local t = time(); | |
42 local stats = { | |
43 rate = n/(t-since); | |
44 count = n; | |
45 }; | |
46 since, n = t, 0; | |
47 return "rate", stats.rate, stats; | |
48 end; | |
49 return function () | |
50 n = n + 1; | |
51 end; | |
52 end; | |
53 duration = function (name) | |
54 local events, last_event = {}, 0; | |
55 local n_actual_events = 0; | |
56 local since = time(); | |
57 | |
58 registry[name] = function () | |
59 local n_stored_events = #events; | |
60 t_sort(events); | |
61 local sum = 0; | |
62 for i = 1, n_stored_events do | |
63 sum = sum + events[i]; | |
64 end | |
65 | |
66 local new_time = time(); | |
67 | |
68 local stats = { | |
69 samples = events; | |
70 sample_count = n_stored_events; | |
71 count = n_actual_events, | |
72 rate = n_actual_events/(new_time-since); | |
73 average = n_stored_events > 0 and sum/n_stored_events or 0, | |
74 min = events[1], | |
75 max = events[n_stored_events], | |
76 }; | |
77 | |
78 events, last_event = {}, 0; | |
79 n_actual_events = 0; | |
80 since = new_time; | |
81 | |
82 return "duration", stats.average, stats; | |
83 end; | |
84 | |
85 return function () | |
86 n_actual_events = n_actual_events + 1; | |
87 if n_actual_events%duration_sample_interval > 0 then | |
88 return nop_function; | |
89 end | |
90 | |
91 local start_time = time(); | |
92 return function () | |
93 local end_time = time(); | |
94 local duration = end_time - start_time; | |
95 last_event = (last_event%duration_max_samples) + 1; | |
96 events[last_event] = duration; | |
97 end | |
98 end; | |
99 end; | |
100 | |
101 get_stats = function () | |
102 return registry; | |
103 end; | |
104 }; | |
105 return methods; | |
106 end | |
107 | |
108 return { | |
109 new = new_registry; | |
110 get_histogram = function (duration, n_buckets) | |
111 n_buckets = n_buckets or 100; | |
112 local events, n_events = duration.samples, duration.sample_count; | |
113 if not (events and n_events) then | |
114 return nil, "not a valid duration stat"; | |
115 end | |
116 local histogram = {}; | |
117 | |
118 for i = 1, 100, 100/n_buckets do | |
119 histogram[i] = percentile(events, n_events, i); | |
120 end | |
121 return histogram; | |
122 end; | |
123 | |
124 get_percentile = function (duration, pc) | |
125 local events, n_events = duration.samples, duration.sample_count; | |
126 if not (events and n_events) then | |
127 return nil, "not a valid duration stat"; | |
128 end | |
129 return percentile(events, n_events, pc); | |
130 end; | |
131 } |