From 695131994b5a749e129fb304e8ba709acd37afe8 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 26 May 2023 21:34:14 +0200 Subject: add support for chrony_exporter (replaces textfile collector) --- .../openwrt/chrony_prometheus-node-exporter.lua | 121 +++++++++++---------- 1 file changed, 63 insertions(+), 58 deletions(-) (limited to 'files') diff --git a/files/common/openwrt/chrony_prometheus-node-exporter.lua b/files/common/openwrt/chrony_prometheus-node-exporter.lua index eeaceb1f..95fd0093 100644 --- a/files/common/openwrt/chrony_prometheus-node-exporter.lua +++ b/files/common/openwrt/chrony_prometheus-node-exporter.lua @@ -1,30 +1,35 @@ #!/usr/bin/lua --- this is a lua-fied version of the python script that can be found here: --- https://www.mail-archive.com/chrony-users@chrony.tuxfamily.org/msg02179.html +-- this tries to create the same metrics as: https://github.com/SuperQ/chrony_exporter +-- -local chrony_sourcestats_cmd = 'chronyc -n -c sourcestats' local chrony_sources_cmd = 'chronyc -n -c sources' local chrony_tracking_cmd = 'chronyc -n -c tracking' -local status_types = {} -status_types['x'] = 0 -status_types['?'] = 1 -status_types['-'] = 2 -status_types['+'] = 3 -status_types['*'] = 4 +local source_states = {} +source_states['*'] = "sync" +source_states['?'] = "unreach" +source_states['x'] = "falseticker" +source_states['~'] = "jittery" +source_states['+'] = "candidate" +source_states['-'] = "outlier" -local metrics_mode = {} -metrics_mode['^'] = "server" -metrics_mode['='] = "peer" -metrics_mode['#'] = "reference clock" +local source_modes = {} +source_modes['^'] = "client" +source_modes['='] = "peer" +source_modes['#'] = "reference clock" function get_cmdoutput(cmd) - local chrony_sourcestats, err = io.popen(cmd) + local chronyc_out, err = io.popen(cmd) if err ~= nil then return nil, err end local lines = {} - for line in chrony_sourcestats:lines() do table.insert(lines, line) end + for line in chronyc_out:lines() do + if line == "506 Cannot talk to daemon" then + return nil, "line" + end + table.insert(lines, line) + end return lines end @@ -36,58 +41,58 @@ function comma_split(s) return elements end -function weight(value) - -- the reachability value is an octal number between 0 and 255 - -- the python script does rather complicated computations that - -- boil down to: value == 255 (377 oct) - if value == "377" then return 1 end - return 0 -end +local function scrape() + local chrony_tracking = get_cmdoutput(chrony_tracking_cmd) + local chrony_sources = get_cmdoutput(chrony_sources_cmd) + local metric_up = metric("chrony_up", "gauge") + if chrony_tracking == nil or chrony_sources == nil then + metric_up(nil, 0) + return + end + metric_up(nil, 1) -local function scrape() - local metric_freq = metric("chronyd_freq_ppm", "gauge") - local metric_freq_skew = metric("chronyd_freq_skew_ppm", "gauge") - local metric_std_dev = metric("chronyd_std_dev_seconds", "gauge") - local chrony_sourcestats = get_cmdoutput(chrony_sourcestats_cmd) - local line - for _, line in ipairs(chrony_sourcestats) do + for _, line in ipairs(chrony_tracking) do local items = comma_split(line) - local labels = { remote = items[1] } - metric_freq(labels, tonumber(items[5])) - metric_freq_skew(labels, tonumber(items[6])) - metric_std_dev(labels, tonumber(items[8])) + metric("chrony_tracking_info", "gauge", { tracking_address = items[2], tracking_refid = items[1]}, 1) + metric("chrony_tracking_last_offset_seconds", "gauge", nil, tonumber(items[6])) + metric("chrony_tracking_reference_timestamp_seconds", "gauge", nil, tonumber(items[4])) + metric("chrony_tracking_rms_offset_seconds", "gauge", nil, tonumber(items[7])) + metric("chrony_tracking_root_delay_seconds", "gauge", nil, tonumber(items[11])) + metric("chrony_tracking_root_dispersion_seconds", "gauge", nil, tonumber(items[12])) + metric("chrony_tracking_stratum", "gauge", nil, tonumber(items[3])) + metric("chrony_tracking_system_time_seconds", "gauge", nil, tonumber(items[5])) end - local metric_peer_status = metric("chronyd_peer_status", "gauge") - local metric_offset_seconds = metric("chronyd_offset_seconds", "gauge") - local metric_peer_reachable = metric("chronyd_peer_reachable", "gauge") - local chrony_sources = get_cmdoutput(chrony_sources_cmd) + local metric_sources_ls_age = metric("chrony_sources_last_sample_age_seconds", "gauge") for _, line in ipairs(chrony_sources) do local items = comma_split(line) - local common_labels = { remote = items[3] } - local peer_labels = { remote = items[3], stratum = tonumber(items[4]), mode = metrics_mode[items[1]] } - metric_peer_status(peer_labels, status_types[items[2]]) - metric_offset_seconds(common_labels, tonumber(items[9])) - metric_peer_reachable(peer_labels, weight(items[6])) + metric_sources_ls_age({ source_address = items[3] }, tonumber(items[7])) end - - local chrony_tracking = get_cmdoutput(chrony_tracking_cmd) - for _, line in ipairs(chrony_tracking) do + local metric_sources_ls_error = metric("chrony_sources_last_sample_error_margin_seconds", "gauge") + for _, line in ipairs(chrony_sources) do + local items = comma_split(line) + metric_sources_ls_error({ source_address = items[3] }, tonumber(items[10])) + end + local metric_sources_ls_offset = metric("chrony_sources_last_sample_offset_seconds", "gauge") + for _, line in ipairs(chrony_sources) do + local items = comma_split(line) + metric_sources_ls_offset({ source_address = items[3] }, tonumber(items[8])) + end + local metric_sources_polling_int = metric("chrony_sources_polling_interval_seconds", "gauge") + for _, line in ipairs(chrony_sources) do + local items = comma_split(line) + metric_sources_polling_int({ source_address = items[3] }, 2^tonumber(items[5])) + end + local metric_sources_info = metric("chrony_sources_state_info", "gauge") + for _, line in ipairs(chrony_sources) do + local items = comma_split(line) + metric_sources_info({ source_address = items[3], source_mode = source_modes[items[1]], source_state = source_states[items[2]] }, 1) + end + local metric_sources_stratum = metric("chrony_sources_stratum", "gauge") + for _, line in ipairs(chrony_sources) do local items = comma_split(line) - metric("chronyd_tracking_source", "gauge", { value = items[2]}, 1) - metric("chronyd_tracking_stratum", "gauge", nil, tonumber(items[3])) - metric("chronyd_tracking_ref_time", "gauge", nil, tonumber(items[4])) - metric("chronyd_tracking_system_time", "gauge", nil, tonumber(items[5])) - metric("chronyd_tracking_last_offset", "gauge", nil, tonumber(items[6])) - metric("chronyd_tracking_rms_offset", "gauge", nil, tonumber(items[7])) - metric("chronyd_tracking_frequency_error", "gauge", nil, tonumber(items[8])) - metric("chronyd_tracking_frequency_residual", "gauge", nil, tonumber(items[9])) - metric("chronyd_tracking_frequency_skew", "gauge", nil, tonumber(items[10])) - metric("chronyd_tracking_root_delay", "gauge", nil, tonumber(items[11])) - metric("chronyd_tracking_root_dispersion", "gauge", nil, tonumber(items[12])) - metric("chronyd_tracking_update_interval", "gauge", nil, tonumber(items[13])) - metric("chronyd_tracking_leap_status", "gauge", { value = items[14]}, 1) + metric_sources_stratum({ source_address = items[3] }, tonumber(items[4])) end end -- cgit v1.2.3