Skip to content

Commit

Permalink
api: introduce metrics.cfg{}
Browse files Browse the repository at this point in the history
This patch introduces `metrics.cfg` as a single entrypoint to configure
the module. It covers both `enable_default_metrics` and
`set_global_labels` with the same behavior (except for deprecated
`include={}` behavior, where it uses enable_v2 approach). It doesn't
cover external features like cartridge HTTP setup yet, but it may change
in the future. A single entrypoint is a prerequirement for configuring
the module with box.cfg after embedding.

`metrics.cfg` API is similar to `box.cfg` API (or more like `crud.cfg`
API [1] since it has read-only table values).

`metrics.cfg` values and effect are preserved between reloads. So if
some default metrics were enabled with cfg before the reload, both
their collectors and callbacks will remain active (they still be
reloaded though).

It is planned to replace `cartridge.roles.metrics` configuration code
with using metrics.cfg after the deprecated behavior will be dropped.

1. tarantool/crud@6da4f56

Part of tarantool/tarantool#7725
  • Loading branch information
DifferentialOrange committed Feb 16, 2023
1 parent 5d0e1b0 commit d892e7d
Show file tree
Hide file tree
Showing 14 changed files with 450 additions and 35 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `metrics.cfg{}` -- a single entrypoint to setup the module:
- `include` and `exclude` options with the same effect as in
`enable_default_metrics(include, exclude)` (but its deprecated
features already disabled);
- `labels` options with the same effect as `set_global_labels(labels)`;
- values and effect (like default metrics callbacks) are preserved
between reloads;
- does not deal with external features like cartridge HTTP setup

### Changed
- Setup cartridge hotreload inside the role
- Extend `enable_default_metrics()` API:
Expand Down
2 changes: 2 additions & 0 deletions cartridge/roles/metrics.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local cartridge = require('cartridge')
local argparse = require('cartridge.argparse')
local hotreload_supported, hotreload = pcall(require, 'cartridge.hotreload')
local metrics = require('metrics')
local metrics_stash = require('metrics.stash')
local log = require('log')

local metrics_vars = require('cartridge.vars').new('metrics_vars')
Expand Down Expand Up @@ -222,6 +223,7 @@ local function init()

if hotreload_supported then
hotreload.whitelist_globals({'__metrics_registry'})
metrics_stash.setup_cartridge_reload()
end
end

Expand Down
41 changes: 25 additions & 16 deletions doc/monitoring/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -303,20 +303,25 @@ You can also set global labels by calling
Metrics functions
-----------------

.. function:: enable_default_metrics([include, exclude])
.. function:: cfg([config])

Entrypoint to setup the module.

Enable Tarantool metric collection.
:param table config: module configuration options:

:param string/table include: ``'all'`` to enable all supported default metrics,
``'none'`` to disable all default metrics,
table with names of the default metrics to enable a specific set of metrics
(``{}`` is the same as ``'all'`` for backward compatibility).
Default is ``'all'``.
* ``cfg.include`` (string/table, default ``'all'``): ``'all`` to enable all
supported default metrics, ``'none'`` to disable all default metrics,
table with names of the default metrics to enable a specific set of metrics.
* ``cfg.exclude`` (table, default ``{}``): table containing the names of
the default metrics that you want to disable. Has higher priority
than ``cfg.include``.
* ``cfg.labels`` (table, default ``{}``): table containing label names as
string keys, label values as values.

:param table exclude: table containing the names of the default metrics that you want to disable.
It has higher priority than ``include``. Default is ``{}``.
You can work with ``metrics.cfg`` as a table to read values, but you must call
``metrics.cfg{}`` as a function to update them.

Default metric names:
Supported default metric names (for ``cfg.include`` and ``cfg.exclude`` tables):

* ``network``
* ``operations``
Expand All @@ -340,12 +345,7 @@ Metrics functions
See :ref:`metrics reference <metrics-reference>` for details.
All metric collectors from the collection have ``metainfo.default = true``.

.. function:: set_global_labels(label_pairs)

Set the global labels to be added to every observation.

:param table label_pairs: table containing label names as string keys,
label values as values.
``cfg.labels`` are the global labels to be added to every observation.

Global labels are applied only to metric collection. They have no effect
on how observations are stored.
Expand All @@ -358,6 +358,15 @@ Metrics functions

Note that both label names and values in ``label_pairs`` are treated as strings.

.. function:: enable_default_metrics([include, exclude])

Same as ``metrics.cfg{include=include, exclude=exclude}``, but ``include={}`` is
treated as ``include='all'`` for backward compatibility.

.. function:: set_global_labels(label_pairs)

Same as ``metrics.cfg{labels=label_pairs}``.

.. function:: collect([opts])

Collect observations from each collector.
Expand Down
11 changes: 3 additions & 8 deletions doc/monitoring/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,12 @@ Next, require it in your code:
local metrics = require('metrics')
Set a global label for your metrics:
Enable default Tarantool metrics such as network, memory, operations, etc.
You may also set a global label for your metrics:

.. code-block:: lua
metrics.set_global_labels({alias = 'alias'})
Enable default Tarantool metrics such as network, memory, operations, etc.:

.. code-block:: lua
metrics.enable_default_metrics()
metrics.cfg{alias = 'alias'}
Initialize the Prometheus exporter or export metrics in another format:

Expand Down
4 changes: 2 additions & 2 deletions doc/monitoring/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Sample settings
.. code-block:: lua
metrics = require('metrics')
metrics.enable_default_metrics()
metrics.cfg{}
prometheus = require('metrics.plugins.prometheus')
httpd = require('http.server').new('0.0.0.0', 8080)
httpd:route( { path = '/metrics' }, prometheus.collect_http)
Expand All @@ -70,7 +70,7 @@ Sample settings
cartridge = require('cartridge')
httpd = cartridge.service_get('httpd')
metrics = require('metrics')
metrics.enable_default_metrics()
metrics.cfg{}
prometheus = require('metrics.plugins.prometheus')
httpd:route( { path = '/metrics' }, prometheus.collect_http)
Expand Down
2 changes: 2 additions & 0 deletions metrics-scm-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ build = {
['metrics.tarantool.luajit'] = 'metrics/tarantool/luajit.lua',
['metrics.tarantool.vinyl'] = 'metrics/tarantool/vinyl.lua',
['metrics.utils'] = 'metrics/utils.lua',
['metrics.cfg'] = 'metrics/cfg.lua',
['metrics.stash'] = 'metrics/stash.lua',
['cartridge.roles.metrics'] = 'cartridge/roles/metrics.lua',
['cartridge.health'] = 'cartridge/health.lua',
}
Expand Down
91 changes: 91 additions & 0 deletions metrics/cfg.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
-- Based on https://github.com/tarantool/crud/blob/73bf5bf9353f9b9ee69c95bb14c610be8f2daeac/crud/cfg.lua

local checks = require('checks')

local metrics_api = require('metrics.api')
local const = require('metrics.const')
local stash = require('metrics.stash')
local metrics_tarantool = require('metrics.tarantool')

local function set_defaults_if_empty(cfg)
if cfg.include == nil then
cfg.include = const.ALL
end

if cfg.exclude == nil then
cfg.exclude = {}
end

if cfg.labels == nil then
cfg.labels = {}
end

return cfg
end

local function configure(cfg, opts)
if opts.include == nil then
opts.include = cfg.include
end

if opts.exclude == nil then
opts.exclude = cfg.exclude
end

if opts.labels == nil then
opts.labels = cfg.labels
end


metrics_tarantool.enable_v2(opts.include, opts.exclude)
metrics_api.set_global_labels(opts.labels)

rawset(cfg, 'include', opts.include)
rawset(cfg, 'exclude', opts.exclude)
rawset(cfg, 'labels', opts.labels)
end

local _cfg = set_defaults_if_empty(stash.get(stash.name.cfg))
local _cfg_internal = stash.get(stash.name.cfg_internal)

if _cfg_internal.initialized then
configure(_cfg, {})
end

local function __call(self, opts)
checks('table', {
include = '?string|table',
exclude = '?table',
labels = '?table',
})

opts = table.deepcopy(opts) or {}

configure(_cfg, opts)

_cfg_internal.initialized = true

return self
end

local function __index(_, key)
if _cfg_internal.initialized then
return _cfg[key]
else
error('Call metrics.cfg{} first')
end
end

local function __newindex()
error('Use metrics.cfg{} instead')
end

return {
-- Iterating through `metrics.cfg` with pairs is not supported yet.
cfg = setmetatable({}, {
__index = __index,
__newindex = __newindex,
__call = __call,
__serialize = function() return _cfg end
}),
}
2 changes: 2 additions & 0 deletions metrics/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

local api = require('metrics.api')
local const = require('metrics.const')
local cfg = require('metrics.cfg')
local http_middleware = require('metrics.http_middleware')
local tarantool = require('metrics.tarantool')

Expand All @@ -25,6 +26,7 @@ return {
invoke_callbacks = api.invoke_callbacks,
set_global_labels = api.set_global_labels,
enable_default_metrics = tarantool.enable,
cfg = cfg.cfg,
http_middleware = http_middleware,
collect = api.collect,
VERSION = VERSION,
Expand Down
48 changes: 48 additions & 0 deletions metrics/stash.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-- Based on https://github.com/tarantool/crud/blob/73bf5bf9353f9b9ee69c95bb14c610be8f2daeac/crud/common/stash.lua

local stash = {}

--- Available stashes list.
--
-- @tfield string cfg
-- Stash for metrics module configuration.
--
stash.name = {
cfg = '__metrics_cfg',
cfg_internal = '__metrics_cfg_internal'
}

--- Setup Tarantool Cartridge reload.
--
-- @function setup_cartridge_reload
--
-- @return Returns
--
function stash.setup_cartridge_reload()
local hotreload = require('cartridge.hotreload')
for _, name in pairs(stash.name) do
hotreload.whitelist_globals({ name })
end
end

--- Get a stash instance, initialize if needed.
--
-- Stashes are persistent to package reload.
-- To use them with Cartridge roles reload,
-- call `stash.setup_cartridge_reload` in role.
--
-- @function get
--
-- @string name
-- Stash identifier. Use one from `stash.name` table.
--
-- @treturn table A stash instance.
--
function stash.get(name)
local instance = rawget(_G, name) or {}
rawset(_G, name, instance)

return instance
end

return stash
Loading

0 comments on commit d892e7d

Please sign in to comment.