-
Notifications
You must be signed in to change notification settings - Fork 231
/
prometheus_resty_counter.lua
118 lines (98 loc) · 2.43 KB
/
prometheus_resty_counter.lua
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
local ngx_shared = ngx.shared
local pairs = pairs
local ngx = ngx
local error = error
local setmetatable = setmetatable
local tonumber = tonumber
local clear_tab
do
local ok
ok, clear_tab = pcall(require, "table.clear")
if not ok then
clear_tab = function(tab)
for k in pairs(tab) do
tab[k] = nil
end
end
end
end
local _M = {
_VERSION = '0.2.1'
}
local mt = { __index = _M }
-- local cache of counters increments
local increments = {}
-- boolean flags of per worker sync timers
local timer_started = {}
local id
local function sync(_, self)
local err, _, forcible
local ok = true
for k, v in pairs(self.increments) do
_, err, forcible = self.dict:incr(k, v, 0)
if forcible then
ngx.log(ngx.ERR, "increasing counter in shdict: lru eviction: key=", k)
ok = false
end
if err then
ngx.log(ngx.ERR, "error increasing counter in shdict key: ", k, ", err: ", err)
ok = false
end
end
clear_tab(self.increments)
if ok == false then
self.dict:incr(self.error_metric_name, 1, 0)
end
return ok
end
function _M.new(shdict_name, sync_interval, error_metric_name)
id = ngx.worker.id()
if not ngx_shared[shdict_name] then
error("shared dict \"" .. (shdict_name or "nil") .. "\" not defined", 2)
end
if not increments[shdict_name] then
increments[shdict_name] = {}
end
local self = setmetatable({
dict = ngx_shared[shdict_name],
increments = increments[shdict_name],
error_metric_name = error_metric_name,
}, mt)
if sync_interval then
sync_interval = tonumber(sync_interval)
if not sync_interval or sync_interval < 0 then
error("expect sync_interval to be a positive number", 2)
end
if not timer_started[shdict_name] then
ngx.log(ngx.DEBUG, "start timer for shdict ", shdict_name, " on worker ", id)
ngx.timer.every(sync_interval, sync, self)
timer_started[shdict_name] = true
end
end
return self
end
function _M:sync()
return sync(false, self)
end
function _M:incr(key, step)
step = step or 1
local v = self.increments[key]
if v then
step = step + v
end
self.increments[key] = step
return true
end
function _M:reset(key, number)
if not number then
return nil, "expect a number at #2"
end
return self.dict:incr(key, -number, number)
end
function _M:get(key)
return self.dict:get(key)
end
function _M:get_keys(max_count)
return self.dict:get_keys(max_count)
end
return _M