diff --git a/prometheus_resty_counter.lua b/prometheus_resty_counter.lua index bbb0897..15e75db 100644 --- a/prometheus_resty_counter.lua +++ b/prometheus_resty_counter.lua @@ -97,10 +97,11 @@ function _M:incr(key, step, exptime) step = step or 1 local value = self.increments[key] if value then - step = step + value.v + value.v = step + value.v + value.t = exptime + else + self.increments[key] = {v = step, t = exptime} end - - self.increments[key] = {v = step, t = exptime} return true end diff --git a/prometheus_test.lua b/prometheus_test.lua index 5b63bd7..b080d2c 100644 --- a/prometheus_test.lua +++ b/prometheus_test.lua @@ -419,6 +419,65 @@ function TestPrometheus:testCounters() luaunit.assertEquals(self.dict:get('metric2{f2="v2",f1="v1"}'), 4) luaunit.assertEquals(ngx.logs, nil) end +function TestPrometheus:testBufferedCounterExpiry() + local counter = self.p._counter + counter:incr("pending_nil", 1, 60) + counter:incr("pending_nil", 2) + counter:incr("pending_zero", 1, 60) + counter:incr("pending_zero", 0, 0) + counter:incr("pending_ttl", 1, 60) + counter:incr("pending_ttl", nil, 120) + + local before = os.time() + luaunit.assertTrue(counter:sync()) + luaunit.assertEquals(self.dict:get("pending_nil"), 3) + luaunit.assertEquals(self.dict:ttl("pending_nil"), 0) + luaunit.assertEquals(self.dict:get("pending_zero"), 1) + luaunit.assertEquals(self.dict:ttl("pending_zero"), 0) + luaunit.assertEquals(self.dict:get("pending_ttl"), 2) + local expiry = self.dict.dict.pending_ttl.expired + luaunit.assertTrue(expiry >= before + 120 and expiry <= os.time() + 120) + + -- A nil expiry in the next batch leaves the shared dictionary's TTL intact. + counter:incr("pending_ttl", 0.5) + luaunit.assertTrue(counter:sync()) + luaunit.assertEquals(self.dict:get("pending_ttl"), 2.5) + luaunit.assertEquals(self.dict.dict.pending_ttl.expired, expiry) + + counter:incr("pending_ttl", 0, 0) + luaunit.assertTrue(counter:sync()) + luaunit.assertEquals(self.dict:get("pending_ttl"), 2.5) + luaunit.assertEquals(self.dict:ttl("pending_ttl"), 0) + luaunit.assertEquals(ngx.logs, nil) +end +function TestPrometheus:testBufferedMetricsAcrossSyncs() + self.counter1:inc() + self.counter1:inc(4) + self.hist1:observe(0.25) + self.hist1:observe(0.5) + self.hist1:observe(-0.125) + + luaunit.assertTrue(self.p._counter:sync()) + luaunit.assertTrue(self.p._counter:sync()) + luaunit.assertEquals(self.dict:get("metric1"), 5) + luaunit.assertEquals(self.dict:get("l1_count"), 3) + luaunit.assertEquals(self.dict:get("l1_sum"), 0.625) + luaunit.assertEquals(self.dict:get('l1_bucket{le="00.005"}'), 1) + luaunit.assertEquals(self.dict:get('l1_bucket{le="00.500"}'), 3) + luaunit.assertEquals(self.dict:get('l1_bucket{le="Inf"}'), 3) + + self.counter1:inc(0) + self.counter1:inc() + self.hist1:observe(0.125) + luaunit.assertTrue(self.p._counter:sync()) + luaunit.assertEquals(self.dict:get("metric1"), 6) + luaunit.assertEquals(self.dict:get("l1_count"), 4) + luaunit.assertEquals(self.dict:get("l1_sum"), 0.75) + luaunit.assertEquals(self.dict:get('l1_bucket{le="00.005"}'), 1) + luaunit.assertEquals(self.dict:get('l1_bucket{le="00.500"}'), 4) + luaunit.assertEquals(self.dict:get('l1_bucket{le="Inf"}'), 4) + luaunit.assertEquals(ngx.logs, nil) +end function TestPrometheus:testGaugeIncDec() self.gauge1:inc(-1) luaunit.assertEquals(self.dict:get("gauge1"), -1)