Skip to content

Commit 4b2a6c4

Browse files
metrics: introduce config status gauge
The approach used to represent enum metric here is similar to one discussed in [1, 2]. It allows to support a new status later, if required. For example, one can visualize it with hack like [3]. 1. prometheus/client_python#416 2. open-telemetry/opentelemetry-specification#1711 3. https://stackoverflow.com/a/75761900/11646599 Part of tarantool/grafana-dashboard#224
1 parent 19fb64f commit 4b2a6c4

4 files changed

Lines changed: 136 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
### Added
99
- New Tarantool 3 metrics:
1010
- tnt_config_alerts
11+
- tnt_config_status
1112

1213
## [1.1.0] - 2024-05-17
1314
### Added

doc/monitoring/metrics_reference.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,4 +1010,23 @@ These metrics are available starting from Tarantool 3.0.
10101010
- Count of current instance :ref:`configuration apply alerts <config_api_reference_info>`.
10111011
``{level="warn"}`` label covers warnings and
10121012
``{level="error"}`` covers errors.
1013+
1014+
* - ``tnt_config_status``
1015+
- The status of current instance :ref:`configuration apply <config_api_reference_info>`.
1016+
``status`` label contains possible status name.
1017+
Current status has metric value ``1``, inactive statuses have metric value ``0``.
1018+
1019+
.. code-block:: none
1020+
1021+
# HELP tnt_config_status Tarantool 3 configuration status
1022+
# TYPE tnt_config_status gauge
1023+
tnt_config_status{status="reload_in_progress",alias="router-001-a"} 0
1024+
tnt_config_status{status="uninitialized",alias="router-001-a"} 0
1025+
tnt_config_status{status="check_warnings",alias="router-001-a"} 0
1026+
tnt_config_status{status="ready",alias="router-001-a"} 1
1027+
tnt_config_status{status="check_errors",alias="router-001-a"} 0
1028+
tnt_config_status{status="startup_in_progress",alias="router-001-a"} 0
1029+
1030+
For example, this set of metrics means that current configuration
1031+
for ``router-001-a`` status is ``ready``.
10131032

metrics/tarantool/config.lua

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@ local function get_config_alerts(config_info)
1616
return config_alerts
1717
end
1818

19+
local function get_config_status(config_info)
20+
-- See state diagram here
21+
-- https://github.com/tarantool/doc/issues/3544#issuecomment-1866033480
22+
local config_status = {
23+
uninitialized = 0,
24+
startup_in_progress = 0,
25+
reload_in_progress = 0,
26+
check_warnings = 0,
27+
check_errors = 0,
28+
ready = 0,
29+
}
30+
31+
config_status[config_info.status] = 1
32+
33+
return config_status
34+
end
35+
1936
local function update()
2037
if not utils.is_tarantool3() then
2138
return
@@ -38,6 +55,19 @@ local function update()
3855
{default = true}
3956
)
4057
end
58+
59+
local config_status = get_config_status(config_info)
60+
61+
for status, value in pairs(config_status) do
62+
collectors_list.config_status = utils.set_gauge(
63+
'config_status',
64+
'Tarantool 3 configuration status',
65+
value,
66+
{status = status},
67+
nil,
68+
{default = true}
69+
)
70+
end
4171
end
4272

4373
return {

test/tarantool/config_metrics_test.lua

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,51 +123,122 @@ local function assert_config_alerts_metrics(server, expected_values)
123123
t.assert_equals(errors.value, expected_values['error'])
124124
end
125125

126+
local function assert_config_status_metrics(server, expected_values)
127+
local observations = server:exec(function()
128+
local metrics = require('metrics')
129+
metrics.invoke_callbacks()
130+
return metrics.collect()
131+
end)
126132

127-
g.before_test('test_config_alerts_if_healthy', start_server)
128-
g.after_test('test_config_alerts_if_healthy', stop_server)
133+
for status, expected_value in pairs(expected_values) do
134+
local actual_obs = utils.find_obs(
135+
'tnt_config_status',
136+
{status = status, alias = 'server-001-a'},
137+
observations
138+
)
139+
t.assert_equals(actual_obs.value, expected_value,
140+
("got expected value for %q"):format(status))
141+
end
142+
end
129143

130-
g.test_config_alerts_if_healthy = function(cg)
144+
145+
g.before_test('test_config_metrics_if_healthy', start_server)
146+
g.after_test('test_config_metrics_if_healthy', stop_server)
147+
148+
g.test_config_metrics_if_healthy = function(cg)
131149
assert_config_alerts_metrics(cg.server, {warn = 0, error = 0})
150+
assert_config_status_metrics(cg.server, {
151+
uninitialized = 0,
152+
startup_in_progress = 0,
153+
reload_in_progress = 0,
154+
check_warnings = 0,
155+
check_errors = 0,
156+
ready = 1,
157+
})
132158
end
133159

134160

135-
g.before_test('test_config_alerts_if_minor_trouble', start_server)
136-
g.after_test('test_config_alerts_if_minor_trouble', stop_server)
161+
g.before_test('test_config_metrics_if_minor_trouble', start_server)
162+
g.after_test('test_config_metrics_if_minor_trouble', stop_server)
137163

138-
g.test_config_alerts_if_minor_trouble = function(cg)
164+
g.test_config_metrics_if_minor_trouble = function(cg)
139165
local config = table.deepcopy(default_config)
140166
config['credentials']['users']['user_one'] = {roles = {'role_two'}}
141167
reload_config(cg, config)
142168

143169
assert_config_alerts_metrics(cg.server, {warn = 1, error = 0})
170+
assert_config_status_metrics(cg.server, {
171+
uninitialized = 0,
172+
startup_in_progress = 0,
173+
reload_in_progress = 0,
174+
check_warnings = 1,
175+
check_errors = 0,
176+
ready = 0,
177+
})
144178
end
145179

146180

147-
g.before_test('test_config_alerts_if_critical_failure', start_server)
148-
g.after_test('test_config_alerts_if_critical_failure', stop_server)
181+
g.before_test('test_config_metrics_if_critical_failure', start_server)
182+
g.after_test('test_config_metrics_if_critical_failure', stop_server)
149183

150-
g.test_config_alerts_if_critical_failure = function(cg)
184+
g.test_config_metrics_if_critical_failure = function(cg)
151185
local config = table.deepcopy(default_config)
152186
config['groups']['servers'] = {}
153187
reload_config(cg, config)
154188

155189
assert_config_alerts_metrics(cg.server, {warn = 0, error = 1})
190+
assert_config_status_metrics(cg.server, {
191+
uninitialized = 0,
192+
startup_in_progress = 0,
193+
reload_in_progress = 0,
194+
check_warnings = 0,
195+
check_errors = 1,
196+
ready = 0,
197+
})
156198
end
157199

158200

159-
g.before_test('test_config_alerts_if_unsupported', function(cg)
201+
g.before_test('test_config_metrics_if_uninitialized', function(cg)
202+
t.skip_if(not utils.is_tarantool_3_config_supported(),
203+
'Skip since Tarantool 3 config is unsupported')
204+
utils.create_server(cg)
205+
cg.server:exec(function()
206+
-- Config do it by default:
207+
-- https://github.com/tarantool/tarantool/blob/319357d5973d15d08b8eda6a230eada08b710802/src/box/lua/config/applier/box_cfg.lua#L614
208+
box.cfg{metrics = {labels = {alias = 'server-001-a'}}}
209+
end)
210+
end)
211+
212+
g.after_test('test_config_metrics_if_uninitialized', function(cg)
213+
utils.drop_server(cg)
214+
cg.server = nil
215+
end)
216+
217+
g.test_config_metrics_if_uninitialized = function(cg)
218+
assert_config_alerts_metrics(cg.server, {warn = 0, error = 0})
219+
assert_config_status_metrics(cg.server, {
220+
uninitialized = 1,
221+
startup_in_progress = 0,
222+
reload_in_progress = 0,
223+
check_warnings = 0,
224+
check_errors = 0,
225+
ready = 0,
226+
})
227+
end
228+
229+
230+
g.before_test('test_config_metrics_if_unsupported', function(cg)
160231
t.skip_if(utils.is_tarantool_3_config_supported(),
161232
'Skip since Tarantool 3 config is supported')
162233
utils.create_server(cg)
163234
end)
164235

165-
g.after_test('test_config_alerts_if_unsupported', function(cg)
236+
g.after_test('test_config_metrics_if_unsupported', function(cg)
166237
utils.drop_server(cg)
167238
cg.server = nil
168239
end)
169240

170-
g.test_config_alerts_if_unsupported = function(cg)
241+
g.test_config_metrics_if_unsupported = function(cg)
171242
local observations = cg.server:exec(function()
172243
local metrics = require('metrics')
173244
metrics.invoke_callbacks()
@@ -176,4 +247,7 @@ g.test_config_alerts_if_unsupported = function(cg)
176247

177248
local alerts = utils.find_metric('tnt_config_alerts', observations)
178249
t.assert_equals(alerts, nil)
250+
251+
local status = utils.find_metric('tnt_config_status', observations)
252+
t.assert_equals(status, nil)
179253
end

0 commit comments

Comments
 (0)