Commit 986926cd authored by Nico's avatar Nico
Browse files

add ffs prometheus node exporter

parent 7d2102f5
#
# Copyright (C) 2013-2017 OpenWrt.org
#
include $(TOPDIR)/rules.mk
PKG_NAME:=ffs-prometheus-node-exporter-lua
PKG_VERSION:=2019.04.12
PKG_RELEASE:=1
PKG_MAINTAINER:=Etienne CHAMPETIER <champetier.etienne@gmail.com>
PKG_LICENSE:=Apache-2.0
include $(INCLUDE_DIR)/package.mk
define Package/ffs-prometheus-node-exporter-lua/Default
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Prometheus node exporter
PKGARCH:=all
endef
define Package/ffs-prometheus-node-exporter-lua
$(call Package/ffs-prometheus-node-exporter-lua/Default)
DEPENDS:=+luasocket +lua
endef
define Package/ffs-prometheus-node-exporter-lua/conffiles
/etc/config/ffs-prometheus-node-exporter-lua
endef
define Package/ffs-prometheus-node-exporter-lua/description
Provides node metrics as Prometheus scraping endpoint.
This service is a lightweight rewrite in LUA of the offical Prometheus node_exporter.
endef
define Package/ffs-prometheus-node-exporter-lua-nat_traffic
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (nat_traffic collector)
DEPENDS:=ffs-prometheus-node-exporter-lua
endef
define Package/ffs-prometheus-node-exporter-lua-netstat
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (netstat collector)
DEPENDS:=ffs-prometheus-node-exporter-lua
endef
define Package/ffs-prometheus-node-exporter-lua-wifi
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (wifi collector)
DEPENDS:=ffs-prometheus-node-exporter-lua +libiwinfo-lua +libubus-lua
endef
define Package/ffs-prometheus-node-exporter-lua-wifi_stations
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (wifi_stations collector)
DEPENDS:=ffs-prometheus-node-exporter-lua +libiwinfo-lua +libubus-lua
endef
define Package/ffs-prometheus-node-exporter-lua-bmx6
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (bmx6 links collector)
DEPENDS:=ffs-prometheus-node-exporter-lua bmx6 +lua-cjson +bmx6-json
endef
define Package/ffs-prometheus-node-exporter-lua-bmx7
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (bmx7 links collector)
DEPENDS:=ffs-prometheus-node-exporter-lua bmx7 +lua-cjson +bmx7-json
endef
define Package/ffs-prometheus-node-exporter-lua-textfile
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (textfile collector)
DEPENDS:=ffs-prometheus-node-exporter-lua +luci-lib-nixio
endef
define Package/ffs-prometheus-node-exporter-lua-openwrt
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (openwrt collector)
DEPENDS:=ffs-prometheus-node-exporter-lua
endef
define Package/ffs-prometheus-node-exporter-lua-ltq-dsl
$(call Package/ffs-prometheus-node-exporter-lua/Default)
TITLE+= (lantiq dsl collector)
DEPENDS:=ffs-prometheus-node-exporter-lua @(PACKAGE_ltq-adsl-app||PACKAGE_ltq-vdsl-app)
endef
Build/Compile=
define Package/ffs-prometheus-node-exporter-lua/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/ffs-prometheus-node-exporter-lua $(1)/etc/config/prometheus-node-exporter-lua
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/ffs-prometheus-node-exporter-lua $(1)/etc/init.d/prometheus-node-exporter-lua
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/usr/bin/ffs-prometheus-node-exporter-lua $(1)/usr/bin/prometheus-node-exporter-lua
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/cpu.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/conntrack.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/filefd.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/loadavg.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/meminfo.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/netdev.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/time.lua $(1)/usr/lib/lua/prometheus-collectors/
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/uname.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-nat_traffic/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/nat_traffic.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-netstat/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/netstat.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-wifi/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/wifi.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-wifi_stations/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/wifi_stations.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-bmx6/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/bmx6.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-bmx7/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/bmx7.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-textfile/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/textfile.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-openwrt/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/openwrt.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
define Package/ffs-prometheus-node-exporter-lua-ltq-dsl/install
$(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/ltq-dsl.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-nat_traffic))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-netstat))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-wifi))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-wifi_stations))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-bmx6))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-bmx7))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-textfile))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-openwrt))
$(eval $(call BuildPackage,ffs-prometheus-node-exporter-lua-ltq-dsl))
config ffs-prometheus-node-exporter-lua 'main'
option listen_address '::1'
option listen_port '9100'
#!/bin/sh /etc/rc.common
# Copyright (C) 2013-2017 OpenWrt.org
START=60
USE_PROCD=1
start_service() {
procd_open_instance
config_load ffs-prometheus-node-exporter-lua.main
config_get bind "main" listen_address ::1
config_get port "main" listen_port 9100
procd_set_param command /usr/bin/ffs-prometheus-node-exporter-lua
procd_append_param command --port ${port}
procd_append_param command --bind ${bind}
procd_set_param stdout 1
procd_set_param stderr 1
procd_close_instance
}
#!/usr/bin/lua
-- Metrics web server
-- Copyright (c) 2016 Jeff Schornick <jeff@schornick.org>
-- Copyright (c) 2015 Kevin Lyda
-- Licensed under the Apache License, Version 2.0
socket = require("socket")
-- Parsing
function space_split(s)
local elements = {}
for element in s:gmatch("%S+") do
table.insert(elements, element)
end
return elements
end
function get_contents(filename)
local f = io.open(filename, "rb")
local contents = ""
if f then
contents = f:read "*a"
f:close()
end
return contents
end
-- Metric printing
function print_metric(metric, labels, value)
local label_string = ""
if labels then
for label,value in pairs(labels) do
label_string = label_string .. label .. '="' .. value .. '",'
end
label_string = "{" .. string.sub(label_string, 1, -2) .. "}"
end
output(string.format("%s%s %s", metric, label_string, value))
end
function metric(name, mtype, labels, value)
output("# TYPE " .. name .. " " .. mtype)
local outputter = function(labels, value)
print_metric(name, labels, value)
end
if value then
outputter(labels, value)
end
return outputter
end
function timed_scrape(collector)
local start_time = socket.gettime()
local success = 1
local status, err = pcall(collector.scrape)
if not status then
success = 0
print(err)
end
return (socket.gettime() - start_time), success
end
function run_all_collectors(collectors)
local metric_duration = metric("node_scrape_collector_duration_seconds", "gauge")
local metric_success = metric("node_scrape_collector_success", "gauge")
for _,cname in pairs(collectors) do
if col_mods[cname] ~= nil then
local duration, success = timed_scrape(col_mods[cname])
local labels = {collector=cname}
metric_duration(labels, duration)
metric_success(labels, success)
end
end
end
-- Web server-specific functions
function http_ok_header()
output("HTTP/1.0 200 OK\r\nServer: lua-metrics\r\nContent-Type: text/plain; version=0.0.4\r\n\r")
end
function http_not_found()
output("HTTP/1.0 404 Not Found\r\nServer: lua-metrics\r\nContent-Type: text/plain\r\n\r\nERROR: File Not Found.")
end
function serve(request)
local q = request:match("^GET /metrics%??([^ ]*) HTTP/1%.[01]$")
if q == nil then
http_not_found()
else
http_ok_header()
local cols = {}
for c in q:gmatch("collect[^=]*=([^&]+)") do
cols[#cols+1] = c
end
if #cols == 0 then
cols = col_names
end
run_all_collectors(cols)
end
client:close()
return true
end
-- Main program
for k,v in ipairs(arg) do
if (v == "-p") or (v == "--port") then
port = arg[k+1]
end
if (v == "-b") or (v == "--bind") then
bind = arg[k+1]
end
end
col_mods = {}
col_names = {}
ls_fd = io.popen("ls -1 /usr/lib/lua/prometheus-collectors/*.lua")
for c in ls_fd:lines() do
c = c:match("([^/]+)%.lua$")
col_mods[c] = require('prometheus-collectors.'..c)
col_names[#col_names+1] = c
end
ls_fd:close()
if port then
server = assert(socket.bind(bind, port))
while 1 do
client = server:accept()
client:settimeout(60)
local request, err = client:receive()
if not err then
output = function (str) client:send(str.."\n") end
if not serve(request) then
break
end
end
end
else
output = print
run_all_collectors(col_names)
end
#!/usr/bin/lua
local json = require "cjson"
local function interpret_suffix(rate)
local value = string.sub(rate, 1, -2)
local suffix = string.sub(rate, -1)
if suffix == "K" then return tonumber(value) * 10^3 end
if suffix == "M" then return tonumber(value) * 10^6 end
if suffix == "G" then return tonumber(value) * 10^9 end
return rate
end
local function scrape()
local status = json.decode(get_contents("/var/run/bmx6/json/status")).status
local labels = {
version = status.version,
id = status.name,
address = status.primaryIp
}
metric("bmx6_status", "gauge", labels, 1)
local links = json.decode(get_contents("/var/run/bmx6/json/links")).links
local metric_bmx6_rxRate = metric("bmx6_link_rxRate","gauge")
local metric_bmx6_txRate = metric("bmx6_link_txRate","gauge")
for _, link in pairs(links) do
local labels = {
source = status.name,
target = link.name,
dev = link.viaDev
}
metric_bmx6_rxRate(labels, interpret_suffix(link.rxRate))
metric_bmx6_txRate(labels, interpret_suffix(link.txRate))
end
end
return { scrape = scrape }
#!/usr/bin/lua
local json = require "cjson"
local function interpret_suffix(rate)
if rate ~= nil then
local value = string.sub(rate, 1, -2)
local suffix = string.sub(rate, -1)
if suffix == "K" then return tonumber(value) * 10^3 end
if suffix == "M" then return tonumber(value) * 10^6 end
if suffix == "G" then return tonumber(value) * 10^9 end
end
return rate
end
local function scrape()
local status = json.decode(get_contents("/var/run/bmx7/json/status")).status
local labels = {
id = status.shortId,
name = status.name,
address = status.primaryIp,
revision = status.revision,
}
metric("bmx7_status", "gauge", labels, 1)
metric("bmx7_cpu_usage", "gauge", nil, status.cpu)
metric("bmx7_mem_usage", "gauge", nil, interpret_suffix(status.mem))
local links = json.decode(get_contents("/var/run/bmx7/json/links")).links
local metric_bmx7_rxRate = metric("bmx7_link_rxRate","gauge")
local metric_bmx7_txRate = metric("bmx7_link_txRate","gauge")
for _, link in pairs(links) do
local labels = {
source = status.shortId,
target = link.shortId,
name = link.name,
dev = link.dev
}
metric_bmx7_rxRate(labels, interpret_suffix(link.rxRate))
metric_bmx7_txRate(labels, interpret_suffix(link.txRate))
end
local metric_bmx7_tunIn = metric("bmx7_tunIn", "gauge")
local parameters = json.decode(get_contents("/var/run/bmx7/json/parameters")).OPTIONS
for _, option in pairs(parameters) do
if option.name == "tunIn" then
for _, instance in pairs(option.INSTANCES) do
for _, child_instance in pairs(instance.CHILD_INSTANCES) do
local labels = {
name = instance.value,
network = child_instance.value
}
metric_bmx7_tunIn(labels, 1)
end
end
elseif option.name == "plugin" then
local metric_bmx7_plugin = metric("bmx7_plugin", "gauge")
for _, instance in pairs(option.INSTANCES) do
metric_bmx7_plugin({ name = instance.value }, 1)
end
end
end
end
return { scrape = scrape }
local function scrape()
local count = get_contents("/proc/sys/net/netfilter/nf_conntrack_count")
local max = get_contents("/proc/sys/net/netfilter/nf_conntrack_max")
if count ~= "" then
metric("node_nf_conntrack_entries", "gauge", nil, string.sub(count, 1, -2))
end
if max ~= "" then
metric("node_nf_conntrack_entries_limit", "gauge", nil, string.sub(max, 1, -2))
end
end
return { scrape = scrape }
-- stat/cpu collector
local function scrape()
local stat = get_contents("/proc/stat")
-- system boot time, seconds since epoch
metric("node_boot_time_seconds", "gauge", nil,
string.match(stat, "btime ([0-9]+)"))
-- context switches since boot (all CPUs)
metric("node_context_switches_total", "counter", nil,
string.match(stat, "ctxt ([0-9]+)"))
-- cpu times, per CPU, per mode
local cpu_mode = {"user", "nice", "system", "idle", "iowait", "irq",
"softirq", "steal", "guest", "guest_nice"}
local i = 0
local cpu_metric = metric("node_cpu_seconds_total", "counter")
while true do
local cpu = {string.match(stat,
"cpu"..i.." (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+)")}
if #cpu ~= 10 then
break
end
for ii, mode in ipairs(cpu_mode) do
cpu_metric({cpu="cpu"..i, mode=mode}, cpu[ii] / 100)
end
i = i + 1
end
-- interrupts served
metric("node_intr_total", "counter", nil,
string.match(stat, "intr ([0-9]+)"))
-- processes forked
metric("node_forks_total", "counter", nil,
string.match(stat, "processes ([0-9]+)"))
-- processes running
metric("node_procs_running_total", "gauge", nil,
string.match(stat, "procs_running ([0-9]+)"))
-- processes blocked for I/O
metric("node_procs_blocked_total", "gauge", nil,
string.match(stat, "procs_blocked ([0-9]+)"))
end
return { scrape = scrape }
local function scrape()
local file_nr = space_split(get_contents("/proc/sys/fs/file-nr"))
metric("node_filefd_allocated", "gauge", nil, file_nr[1])
metric("node_filefd_maximum", "gauge", nil, file_nr[3])
end
return { scrape = scrape }
local function scrape()
local loadavg = space_split(get_contents("/proc/loadavg"))
metric("node_load1", "gauge", nil, loadavg[1])
metric("node_load5", "gauge", nil, loadavg[2])
metric("node_load15", "gauge", nil, loadavg[3])
end
return { scrape = scrape }
local function scrape()
local fd = io.popen("/etc/init.d/dsl_control lucistat")
local dsl_func = loadstring(fd:read("*a"))
fd:close()
if not dsl_func then
return
end
local dsl_stat = dsl_func()
local dsl_line_attenuation = metric("dsl_line_attenuation_db", "gauge")
local dsl_signal_attenuation = metric("dsl_signal_attenuation_db", "gauge")
local dsl_snr = metric("dsl_signal_to_noise_margin_db", "gauge")
local dsl_aggregated_transmit_power = metric("dsl_aggregated_transmit_power_db", "gauge")
local dsl_latency = metric("dsl_latency_seconds", "gauge")
local dsl_datarate = metric("dsl_datarate", "gauge")
local dsl_max_datarate = metric("dsl_max_datarate", "gauge")
local dsl_error_seconds_total = metric("dsl_error_seconds_total", "counter")
local dsl_errors_total = metric("dsl_errors_total", "counter")
-- dsl hardware/firmware information
metric("dsl_info", "gauge", {
atuc_vendor_id = dsl_stat.atuc_vendor_id,
atuc_system_vendor_id = dsl_stat.atuc_system_vendor_id,
chipset = dsl_stat.chipset,
firmware_version = dsl_stat.firmware_version,
api_version = dsl_stat.api_version,
}, 1)
-- dsl line settings information
metric("dsl_line_info", "gauge", {
xtse1 = dsl_stat.xtse1,
xtse2 = dsl_stat.xtse2,
xtse3 = dsl_stat.xtse3,
xtse4 = dsl_stat.xtse4,
xtse5 = dsl_stat.xtse5,
xtse6 = dsl_stat.xtse6,
xtse7 = dsl_stat.xtse7,
xtse8 = dsl_stat.xtse8,
annex = dsl_stat.annex_s,
mode = dsl_stat.line_mode_s,
profile = dsl_stat.profile_s,
}, 1)