util/openmetrics.lua
author Kim Alvefur <zash@zash.se>
Sun, 24 Mar 2024 21:32:00 +0100
changeset 13468 2dbc169aae6a
parent 12979 d10957394a3c
permissions -rw-r--r--
util.startup: Abort before initialization of logging when started as root Prevents creation of log files owned by the root user which could be inaccessible once started correctly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     1
--[[
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     2
This module implements a subset of the OpenMetrics Internet Draft version 00.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     3
12821
176fd3ea505c util.openmetrics: Update tools.ietf.org URL to datatracker
Kim Alvefur <zash@zash.se>
parents: 12594
diff changeset
     4
URL: https://datatracker.ietf.org/doc/html/draft-richih-opsawg-openmetrics-00
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     5
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     6
The following metric types are supported:
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     7
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     8
- Counter
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
     9
- Gauge
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    10
- Histogram
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    11
- Summary
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    12
12391
05c250fa335a Spelling: Fix various spelling mistakes (thanks timeless)
Kim Alvefur <zash@zash.se>
parents: 11933
diff changeset
    13
It is used by util.statsd and util.statistics to provide the OpenMetrics API.
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    14
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    15
To understand what this module is about, it is useful to familiarize oneself
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    16
with the terms MetricFamily, Metric, LabelSet, Label and MetricPoint as
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    17
defined in the I-D linked above.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    18
--]]
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    19
-- metric constructor interface:
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    20
-- metric_ctor(..., family_name, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    21
12979
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12821
diff changeset
    22
local time = require "prosody.util.time".now;
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    23
local select = select;
12979
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12821
diff changeset
    24
local array = require "prosody.util.array";
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12821
diff changeset
    25
local log = require "prosody.util.logger".init("util.openmetrics");
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12821
diff changeset
    26
local new_multitable = require "prosody.util.multitable".new;
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12821
diff changeset
    27
local iter_multitable = require "prosody.util.multitable".iter;
11933
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    28
local t_concat, t_insert = table.concat, table.insert;
12594
5eaf77114fdb compat: Use table.pack (there since Lua 5.2) over our util.table
Kim Alvefur <zash@zash.se>
parents: 12593
diff changeset
    29
local t_pack, t_unpack = table.pack, table.unpack;
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    31
-- BEGIN of Utility: "metric proxy"
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    32
-- This allows to wrap a MetricFamily in a proxy which only provides the
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    33
-- `with_labels` and `with_partial_label` methods. This allows to pre-set one
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    34
-- or more labels on a metric family. This is used in particular via
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    35
-- `with_partial_label` by the moduleapi in order to pre-set the `host` label
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    36
-- on metrics created in non-global modules.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    37
local metric_proxy_mt = {}
12539
7ef7abb72cdd util.openmetrics: Set __name field on metatables to improve error messages
Kim Alvefur <zash@zash.se>
parents: 12538
diff changeset
    38
metric_proxy_mt.__name = "metric_proxy"
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    39
metric_proxy_mt.__index = metric_proxy_mt
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    40
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    41
local function new_metric_proxy(metric_family, with_labels_proxy_fun)
12538
3caff1f93520 util.openmetrics: Set (previously unused, empty) metatable
Kim Alvefur <zash@zash.se>
parents: 12391
diff changeset
    42
	return setmetatable({
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    43
		_family = metric_family,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    44
		with_labels = function(self, ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    45
			return with_labels_proxy_fun(self._family, ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    46
		end;
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    47
		with_partial_label = function(self, label)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    48
			return new_metric_proxy(self._family, function(family, ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    49
				return family:with_labels(label, ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    50
			end)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    51
		end
12538
3caff1f93520 util.openmetrics: Set (previously unused, empty) metatable
Kim Alvefur <zash@zash.se>
parents: 12391
diff changeset
    52
	}, metric_proxy_mt);
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    53
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    54
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    55
-- END of Utility: "metric proxy"
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
    56
11933
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    57
-- BEGIN Rendering helper functions (internal)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    58
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    59
local function escape(text)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    60
	return text:gsub("\\", "\\\\"):gsub("\"", "\\\""):gsub("\n", "\\n");
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    61
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    62
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    63
local function escape_name(name)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    64
	return name:gsub("/", "__"):gsub("[^A-Za-z0-9_]", "_"):gsub("^[^A-Za-z_]", "_%1");
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    65
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    66
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    67
local function repr_help(metric, docstring)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    68
	docstring = docstring:gsub("\\", "\\\\"):gsub("\n", "\\n");
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    69
	return "# HELP "..escape_name(metric).." "..docstring.."\n";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    70
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    71
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    72
local function repr_unit(metric, unit)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    73
	if not unit then
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    74
		unit = ""
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    75
	else
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    76
		unit = unit:gsub("\\", "\\\\"):gsub("\n", "\\n");
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    77
	end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    78
	return "# UNIT "..escape_name(metric).." "..unit.."\n";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    79
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    80
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    81
-- local allowed_types = { counter = true, gauge = true, histogram = true, summary = true, untyped = true };
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    82
-- local allowed_types = { "counter", "gauge", "histogram", "summary", "untyped" };
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    83
local function repr_type(metric, type_)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    84
	-- if not allowed_types:contains(type_) then
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    85
	-- 	return;
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    86
	-- end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    87
	return "# TYPE "..escape_name(metric).." "..type_.."\n";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    88
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    89
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    90
local function repr_label(key, value)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    91
	return key.."=\""..escape(value).."\"";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    92
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    93
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    94
local function repr_labels(labelkeys, labelvalues, extra_labels)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    95
	local values = {}
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    96
	if labelkeys then
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    97
		for i, key in ipairs(labelkeys) do
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    98
			local value = labelvalues[i]
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
    99
			t_insert(values, repr_label(escape_name(key), escape(value)));
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   100
		end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   101
	end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   102
	if extra_labels then
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   103
		for key, value in pairs(extra_labels) do
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   104
			t_insert(values, repr_label(escape_name(key), escape(value)));
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   105
		end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   106
	end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   107
	if #values == 0 then
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   108
		return "";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   109
	end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   110
	return "{"..t_concat(values, ",").."}";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   111
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   112
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   113
local function repr_sample(metric, labelkeys, labelvalues, extra_labels, value)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   114
	return escape_name(metric)..repr_labels(labelkeys, labelvalues, extra_labels).." "..string.format("%.17g", value).."\n";
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   115
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   116
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   117
-- END Rendering helper functions (internal)
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   118
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   119
local function render_histogram_le(v)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   120
	if v == 1/0 then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   121
		-- I-D-00: 4.1.2.2.1:
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   122
		--    Exposers MUST produce output for positive infinity as +Inf.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   123
		return "+Inf"
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   124
	end
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   125
11597
0db763f3f3be util.openmetrics: Prettify format of histogram buckets
Kim Alvefur <zash@zash.se>
parents: 11527
diff changeset
   126
	return string.format("%.14g", v)
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   127
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   128
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   129
-- BEGIN of generic MetricFamily implementation
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   130
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   131
local metric_family_mt = {}
12539
7ef7abb72cdd util.openmetrics: Set __name field on metatables to improve error messages
Kim Alvefur <zash@zash.se>
parents: 12538
diff changeset
   132
metric_family_mt.__name = "metric_family"
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   133
metric_family_mt.__index = metric_family_mt
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   134
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   135
local function histogram_metric_ctor(orig_ctor, buckets)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   136
	return function(family_name, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   137
		return orig_ctor(buckets, family_name, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   138
	end
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   139
end
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   140
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   141
local function new_metric_family(backend, type_, family_name, unit, description, label_keys, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   142
	local metric_ctor = assert(backend[type_], "statistics backend does not support "..type_.." metrics families")
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   143
	local labels = label_keys or {}
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   144
	local user_labels = #labels
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   145
	if type_ == "histogram" then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   146
		local buckets = extra and extra.buckets
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   147
		if not buckets then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   148
			error("no buckets given for histogram metric")
6558
7b2d16c14659 statsmanager, util.statistics: API changes, remove debugging
Matthew Wild <mwild1@gmail.com>
parents: 6556
diff changeset
   149
		end
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   150
		buckets = array(buckets)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   151
		buckets:push(1/0)  -- must have +inf bucket
6558
7b2d16c14659 statsmanager, util.statistics: API changes, remove debugging
Matthew Wild <mwild1@gmail.com>
parents: 6556
diff changeset
   152
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   153
		metric_ctor = histogram_metric_ctor(metric_ctor, buckets)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   154
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   155
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   156
	local data
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   157
	if #labels == 0 then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   158
		data = metric_ctor(family_name, nil, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   159
	else
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   160
		data = new_multitable()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   161
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   162
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   163
	local mf = {
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   164
		family_name = family_name,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   165
		data = data,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   166
		type_ = type_,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   167
		unit = unit,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   168
		description = description,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   169
		user_labels = user_labels,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   170
		label_keys = labels,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   171
		extra = extra,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   172
		_metric_ctor = metric_ctor,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   173
	}
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   174
	setmetatable(mf, metric_family_mt);
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   175
	return mf
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   176
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   177
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   178
function metric_family_mt:new_metric(labels)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   179
	return self._metric_ctor(self.family_name, labels, self.extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   180
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   181
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   182
function metric_family_mt:clear()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   183
	for _, metric in self:iter_metrics() do
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   184
		metric:reset()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   185
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   186
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   187
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   188
function metric_family_mt:with_labels(...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   189
	local count = select('#', ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   190
	if count ~= self.user_labels then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   191
		error("number of labels passed to with_labels does not match number of label keys")
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   192
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   193
	if count == 0 then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   194
		return self.data
6558
7b2d16c14659 statsmanager, util.statistics: API changes, remove debugging
Matthew Wild <mwild1@gmail.com>
parents: 6556
diff changeset
   195
	end
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   196
	local metric = self.data:get(...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   197
	if not metric then
11604
a02c277eb97a util.openmetrics: Use pack from util.table, detect appropriate unpack for Lua 5.1 (thanks sups)
Matthew Wild <mwild1@gmail.com>
parents: 11597
diff changeset
   198
		local values = t_pack(...)
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   199
		metric = self:new_metric(values)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   200
		values[values.n+1] = metric
11604
a02c277eb97a util.openmetrics: Use pack from util.table, detect appropriate unpack for Lua 5.1 (thanks sups)
Matthew Wild <mwild1@gmail.com>
parents: 11597
diff changeset
   201
		self.data:set(t_unpack(values, 1, values.n+1))
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   202
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   203
	return metric
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   204
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   205
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   206
function metric_family_mt:with_partial_label(label)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   207
	return new_metric_proxy(self, function (family, ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   208
		return family:with_labels(label, ...)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   209
	end)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   210
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   211
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   212
function metric_family_mt:iter_metrics()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   213
	if #self.label_keys == 0 then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   214
		local done = false
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   215
		return function()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   216
			if done then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   217
				return nil
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   218
			end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   219
			done = true
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   220
			return {}, self.data
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   221
		end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   222
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   223
	local searchkeys = {};
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   224
	local nlabels = #self.label_keys
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   225
	for i=1,nlabels do
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   226
		searchkeys[i] = nil;
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   227
	end
11604
a02c277eb97a util.openmetrics: Use pack from util.table, detect appropriate unpack for Lua 5.1 (thanks sups)
Matthew Wild <mwild1@gmail.com>
parents: 11597
diff changeset
   228
	local it, state = iter_multitable(self.data, t_unpack(searchkeys, 1, nlabels))
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   229
	return function(_s)
11604
a02c277eb97a util.openmetrics: Use pack from util.table, detect appropriate unpack for Lua 5.1 (thanks sups)
Matthew Wild <mwild1@gmail.com>
parents: 11597
diff changeset
   230
		local label_values = t_pack(it(_s))
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   231
		if label_values.n == 0 then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   232
			return nil, nil
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   233
		end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   234
		local metric = label_values[label_values.n]
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   235
		label_values[label_values.n] = nil
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   236
		label_values.n = label_values.n - 1
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   237
		return label_values, metric
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   238
	end, state
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   239
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   240
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   241
-- END of generic MetricFamily implementation
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   242
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   243
-- BEGIN of MetricRegistry implementation
6558
7b2d16c14659 statsmanager, util.statistics: API changes, remove debugging
Matthew Wild <mwild1@gmail.com>
parents: 6556
diff changeset
   244
7b2d16c14659 statsmanager, util.statistics: API changes, remove debugging
Matthew Wild <mwild1@gmail.com>
parents: 6556
diff changeset
   245
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   246
-- Helper to test whether two metrics are "equal".
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   247
local function equal_metric_family(mf1, mf2)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   248
	if mf1.type_ ~= mf2.type_ then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   249
		return false
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   250
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   251
	if #mf1.label_keys ~= #mf2.label_keys then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   252
		return false
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   253
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   254
	-- Ignoring unit here because in general it'll be part of the name anyway
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   255
	-- So either the unit was moved into/out of the name (which is a valid)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   256
	-- thing to do on an upgrade or we would expect not to see any conflicts
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   257
	-- anyway.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   258
	--[[
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   259
	if mf1.unit ~= mf2.unit then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   260
		return false
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   261
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   262
	]]
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   263
	for i, key in ipairs(mf1.label_keys) do
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   264
		if key ~= mf2.label_keys[i] then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   265
			return false
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   266
		end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   267
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   268
	return true
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   269
end
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   270
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   271
-- If the unit is not empty, add it to the full name as per the I-D spec.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   272
local function compose_name(name, unit)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   273
	local full_name = name
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   274
	if unit and unit ~= "" then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   275
		full_name = full_name .. "_" .. unit
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   276
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   277
	-- TODO: prohibit certain suffixes used by metrics if where they may cause
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   278
	-- conflicts
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   279
	return full_name
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   280
end
6558
7b2d16c14659 statsmanager, util.statistics: API changes, remove debugging
Matthew Wild <mwild1@gmail.com>
parents: 6556
diff changeset
   281
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   282
local metric_registry_mt = {}
12539
7ef7abb72cdd util.openmetrics: Set __name field on metatables to improve error messages
Kim Alvefur <zash@zash.se>
parents: 12538
diff changeset
   283
metric_registry_mt.__name = "metric_registry"
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   284
metric_registry_mt.__index = metric_registry_mt
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   285
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   286
local function new_metric_registry(backend)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   287
	local reg = {
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   288
		families = {},
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   289
		backend = backend,
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   290
	}
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   291
	setmetatable(reg, metric_registry_mt)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   292
	return reg
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   293
end
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   294
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   295
function metric_registry_mt:register_metric_family(name, metric_family)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   296
	local existing = self.families[name];
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   297
	if existing then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   298
		if not equal_metric_family(metric_family, existing) then
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   299
			-- We could either be strict about this, or replace the
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   300
			-- existing metric family with the new one.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   301
			-- Being strict is nice to avoid programming errors /
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   302
			-- conflicts, but causes issues when a new version of a module
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   303
			-- is loaded.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   304
			--
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   305
			-- We will thus assume that the new metric is the correct one;
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   306
			-- That is probably OK because unless you're reaching down into
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   307
			-- the util.openmetrics or core.statsmanager API, your metric
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   308
			-- name is going to be scoped to `prosody_mod_$modulename`
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   309
			-- anyway and the damage is thus controlled.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   310
			--
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   311
			-- To make debugging such issues easier, we still log.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   312
			log("debug", "replacing incompatible existing metric family %s", name)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   313
			-- Below is the code to be strict.
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   314
			--error("conflicting declarations for metric family "..name)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   315
		else
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   316
			return existing
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   317
		end
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   318
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   319
	self.families[name] = metric_family
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   320
	return metric_family
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   321
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   322
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   323
function metric_registry_mt:gauge(name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   324
	name = compose_name(name, unit)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   325
	local mf = new_metric_family(self.backend, "gauge", name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   326
	mf = self:register_metric_family(name, mf)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   327
	return mf
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   328
end
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   329
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   330
function metric_registry_mt:counter(name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   331
	name = compose_name(name, unit)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   332
	local mf = new_metric_family(self.backend, "counter", name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   333
	mf = self:register_metric_family(name, mf)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   334
	return mf
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   335
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   336
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   337
function metric_registry_mt:histogram(name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   338
	name = compose_name(name, unit)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   339
	local mf = new_metric_family(self.backend, "histogram", name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   340
	mf = self:register_metric_family(name, mf)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   341
	return mf
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   342
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   343
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   344
function metric_registry_mt:summary(name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   345
	name = compose_name(name, unit)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   346
	local mf = new_metric_family(self.backend, "summary", name, unit, description, labels, extra)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   347
	mf = self:register_metric_family(name, mf)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   348
	return mf
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   349
end
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   350
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   351
function metric_registry_mt:get_metric_families()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   352
	return self.families
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   353
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   354
11933
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   355
function metric_registry_mt:render()
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   356
	local answer = {};
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   357
	for metric_family_name, metric_family in pairs(self:get_metric_families()) do
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   358
		t_insert(answer, repr_help(metric_family_name, metric_family.description))
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   359
		t_insert(answer, repr_unit(metric_family_name, metric_family.unit))
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   360
		t_insert(answer, repr_type(metric_family_name, metric_family.type_))
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   361
		for labelset, metric in metric_family:iter_metrics() do
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   362
			for suffix, extra_labels, value in metric:iter_samples() do
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   363
				t_insert(answer, repr_sample(metric_family_name..suffix, metric_family.label_keys, labelset, extra_labels, value))
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   364
			end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   365
		end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   366
	end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   367
	t_insert(answer, "# EOF\n")
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   368
	return t_concat(answer, "");
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   369
end
85d51bfcf56b mod_http_openmetrics: Imported from prosody-modules mod_prometheus @df2246b15075
Matthew Wild <mwild1@gmail.com>
parents: 11604
diff changeset
   370
11527
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   371
-- END of MetricRegistry implementation
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   372
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   373
-- BEGIN of general helpers for implementing high-level APIs on top of OpenMetrics
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   374
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   375
local function timed(metric)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   376
	local t0 = time()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   377
	local submitter = assert(metric.sample or metric.set, "metric type cannot be used with timed()")
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   378
	return function()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   379
		local t1 = time()
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   380
		submitter(metric, t1-t0)
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   381
	end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   382
end
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   383
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   384
-- END of general helpers
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   385
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   386
return {
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   387
	new_metric_proxy = new_metric_proxy;
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   388
	new_metric_registry = new_metric_registry;
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   389
	render_histogram_le = render_histogram_le;
5f15ab7c6ae5 Statistics: Rewrite statistics backends to use OpenMetrics
Jonas Schäfer <jonas@wielicki.name>
parents: 10887
diff changeset
   390
	timed = timed;
6556
0e29c05c3503 util.statistics: New library for gathering various kinds of statistics
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   391
}