@@ -10,6 +10,7 @@ local checks = require("checks")
10
10
local fun = require (" fun" )
11
11
local log = require (" log" )
12
12
local fiber = require (" fiber" )
13
+ local is_metrics_package , metrics = pcall (require , " metrics" )
13
14
14
15
-- get fiber id function
15
16
local function get_fiber_id (fiber )
@@ -21,6 +22,7 @@ local function get_fiber_id(fiber)
21
22
end
22
23
23
24
local task_list = {}
25
+ local cfg = {metrics = false }
24
26
25
27
local constants = {
26
28
-- default value of number of tuples that will be checked by one iteration
@@ -49,6 +51,74 @@ local constants = {
49
51
atomic_iteration = false ,
50
52
}
51
53
54
+ local metrics_callback = nil
55
+ local metrics_collectors = nil
56
+
57
+ local function metrics_enable ()
58
+ if metrics_callback then
59
+ return
60
+ end
61
+
62
+ local supported_v0_11 = false
63
+ if is_metrics_package and metrics .unregister_callback then
64
+ local counter = require (' metrics.collectors.counter' )
65
+ supported_v0_11 = counter .remove and true or false
66
+ end
67
+ if not supported_v0_11 then
68
+ error (" metrics >= 0.11.0 is required" , 3 )
69
+ end
70
+
71
+ local create_collector = function (name , description )
72
+ return {
73
+ collector = metrics .counter (name , description ),
74
+ task_value = {},
75
+ }
76
+ end
77
+
78
+ metrics_collectors = {
79
+ [" checked_count" ] = create_collector (
80
+ " expirationd_checked_count" ,
81
+ " expirationd task's a number of checked tuples"
82
+ ),
83
+ [" expired_count" ] = create_collector (
84
+ " expirationd_expired_count" ,
85
+ " expirationd task's a number of expired tuples"
86
+ ),
87
+ [" restarts" ] = create_collector (
88
+ " expirationd_restarts" ,
89
+ " expirationd task's a number of restarts"
90
+ ),
91
+ [" working_time" ] = create_collector (
92
+ " expirationd_working_time" ,
93
+ " expirationd task's operation time"
94
+ ),
95
+ }
96
+
97
+ metrics_callback = function ()
98
+ for task_name , task in pairs (task_list ) do
99
+ local stats = task :statistics ()
100
+ for k , v in pairs (stats ) do
101
+ local prev_v = metrics_collectors [k ].task_value [task_name ] or 0
102
+ local v_inc = v - prev_v
103
+ metrics_collectors [k ].collector :inc (v_inc , {name = task_name })
104
+ metrics_collectors [k ].task_value [task_name ] = v
105
+ end
106
+ end
107
+ end
108
+ metrics .register_callback (metrics_callback )
109
+ end
110
+
111
+ local function metrics_disable ()
112
+ if metrics_callback then
113
+ for _ , c in pairs (metrics_collectors ) do
114
+ metrics .registry :unregister (c .collector )
115
+ end
116
+ metrics .unregister_callback (metrics_callback )
117
+ metrics_callback = nil
118
+ metrics_collectors = nil
119
+ end
120
+ end
121
+
52
122
-- ========================================================================= --
53
123
-- Task local functions
54
124
-- ========================================================================= --
@@ -281,6 +351,12 @@ local Task_methods = {
281
351
-- @function task.kill
282
352
kill = function (self )
283
353
self :stop ()
354
+ if metrics_collectors then
355
+ for _ , c in pairs (metrics_collectors ) do
356
+ c .collector :remove ({name = self .name })
357
+ c .task_value [self .name ] = nil
358
+ end
359
+ end
284
360
task_list [self .name ] = nil
285
361
end ,
286
362
400
476
--
401
477
-- @section Functions
402
478
479
+ --- Configure expirationd.
480
+ --
481
+ -- How to set up a configuration option:
482
+ --
483
+ -- ```
484
+ -- expirationd.cfg({metrics = true})
485
+ -- ```
486
+ --
487
+ -- How to get an option value:
488
+ --
489
+ -- ```
490
+ -- print(expirationd.cfg.metrics)
491
+ -- true
492
+ -- ```
493
+ --
494
+ -- @table options
495
+ --
496
+ -- @bool[opt] options.metrics
497
+ -- Enable or disable stats collection by [metrics][1]. metrics >= 0.10.0
498
+ -- is required. It is disabled by default.
499
+ --
500
+ -- If enabled it creates four counter collectors, see @{task.statistics}:
501
+ --
502
+ -- 1. `expirationd_checked_count`
503
+ --
504
+ -- 2. `expirationd_expired_count`
505
+ --
506
+ -- 3. `expirationd_restarts`
507
+ --
508
+ -- 4. `expirationd_working_time`
509
+ --
510
+ -- Labeled with `name = task_name`.
511
+ --
512
+ -- [1]: https://github.com/tarantool/metrics/
513
+ --
514
+ -- @return None
515
+ --
516
+ -- @function expirationd.cfg
517
+ local function expirationd_cfg (self , options )
518
+ checks (' table' , {
519
+ metrics = ' ?boolean' ,
520
+ })
521
+
522
+ if options .metrics == nil then
523
+ return
524
+ end
525
+
526
+ if cfg .metrics ~= options .metrics then
527
+ if options .metrics == true then
528
+ metrics_enable ()
529
+ else
530
+ metrics_disable ()
531
+ end
532
+ rawset (cfg , ' metrics' , options .metrics )
533
+ end
534
+ end
535
+
403
536
--- Run a scheduled task to check and process (expire) tuples in a given space.
404
537
--
405
538
-- How expirationd works in general:
@@ -949,6 +1082,12 @@ local function show_task_list_obsolete(...)
949
1082
end
950
1083
951
1084
return {
1085
+ cfg = setmetatable ({}, {
1086
+ __index = cfg ,
1087
+ __newindex = function () error (" Use expirationd.cfg{} instead" , 2 ) end ,
1088
+ __call = expirationd_cfg ,
1089
+ __serialize = function () return cfg end ,
1090
+ }),
952
1091
start = expirationd_run_task ,
953
1092
stats = expirationd_task_stats ,
954
1093
update = expirationd_update ,
0 commit comments