From 4e94edce516efefce45f94ae5708f25c1a37f3a8 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 01/11] prometheus-node-exporter-lua: send stdout/stderr to logread Signed-off-by: Etienne Champetier --- .../files/etc/init.d/prometheus-node-exporter-lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/prometheus-node-exporter-lua/files/etc/init.d/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/etc/init.d/prometheus-node-exporter-lua index fc8a0b2e6..a1a47079c 100644 --- a/utils/prometheus-node-exporter-lua/files/etc/init.d/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/etc/init.d/prometheus-node-exporter-lua @@ -15,5 +15,8 @@ start_service() { 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 } From c79e75d0c128debf02fa28c1af6e7bd7551793c6 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 02/11] prometheus-node-exporter-lua: respond with HTTP/1.0 also reduce calls to output() Signed-off-by: Etienne Champetier --- .../files/usr/bin/prometheus-node-exporter-lua | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua index fea846926..739881e24 100755 --- a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua @@ -327,18 +327,11 @@ end -- Web server-specific functions function http_ok_header() - output("HTTP/1.1 200 OK\r") - output("Server: lua-metrics\r") - output("Content-Type: text/plain; version=0.0.4\r") - output("\r") + 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.1 404 Not Found\r") - output("Server: lua-metrics\r") - output("Content-Type: text/plain\r") - output("\r") - output("ERROR: File 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) From 58c136a521b7c5b20433484a33925914131771f6 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 03/11] prometheus-node-exporter-lua: improve node_uname_info Testing on a bullet m2, uname collector was taking on average 0.12 it now takes 0.0007 Signed-off-by: Etienne Champetier --- .../usr/bin/prometheus-node-exporter-lua | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua index 739881e24..9fce62029 100755 --- a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua @@ -248,20 +248,19 @@ function scraper_time() metric("node_time", "counter", nil, os.time()) end -function scraper_uname() - -- version can have spaces, so grab it directly - local version = string.sub(io.popen("uname -v"):read("*a"), 1, -2) - -- avoid individual popen calls for the rest of the values - local uname_string = io.popen("uname -a"):read("*a") - local sysname, nodename, release = unpack(space_split(uname_string)) - local labels = {domainname = "(none)", nodename = nodename, release = release, - sysname = sysname, version = version} +uname_labels = { +domainname = "", +nodename = "", +release = string.sub(get_contents("/proc/sys/kernel/osrelease"), 1, -2), +sysname = string.sub(get_contents("/proc/sys/kernel/ostype"), 1, -2), +version = string.sub(get_contents("/proc/sys/kernel/version"), 1, -2), +machine = string.sub(io.popen("uname -m"):read("*a"), 1, -2) +} - -- The machine hardware name is immediately after the version string, so add - -- up the values we know and add in the 4 spaces to find the offset... - machine_offset = string.len(sysname .. nodename .. release .. version) + 4 - labels['machine'] = string.match(string.sub(uname_string, machine_offset), "(%S+)" ) - metric("node_uname_info", "gauge", labels, 1) +function scraper_uname() + uname_labels["domainname"] = string.sub(get_contents("/proc/sys/kernel/domainname"), 1, -2) + uname_labels["nodename"] = string.sub(get_contents("/proc/sys/kernel/hostname"), 1, -2) + metric("node_uname_info", "gauge", uname_labels, 1) end function scraper_nat() From 747f4ce7af53a840ff9674d33851767818f96dba Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 04/11] prometheus-node-exporter-lua: fix nat scraper Signed-off-by: Etienne Champetier --- .../files/usr/bin/prometheus-node-exporter-lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua index 9fce62029..488374ddd 100755 --- a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua @@ -266,8 +266,7 @@ end function scraper_nat() -- documetation about nf_conntrack: -- https://www.frozentux.net/iptables-tutorial/chunkyhtml/x1309.html - -- local natstat = line_split(get_contents("/proc/net/nf_conntrack")) - local natstat = line_split(get_contents("nf_conntrack")) + local natstat = line_split(get_contents("/proc/net/nf_conntrack")) nat_metric = metric("node_nat_traffic", "gauge" ) for i, e in ipairs(natstat) do From 7b1b69ca6ca29fc26b2dad1386128c6e8444ef0c Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 05/11] prometheus-node-exporter-lua: rewrite wifi scraper On my bullet m2, scrape duration goes from between 0.2 and 0.5 to a stable 0.025 We also don't depend on luci anymore This remove wifi_network_up metric, but this metric was buggy wifi_network_up{ifname="wlan0-1",ssid="test1",channel="11",mode="Master",bssid="12:34:56:78:9A:BC",country="FR",frequency="2.462"} 1 wifi_network_up{ifname="radio0.network2",ssid="test1",channel="11",mode="Master",country="US",frequency="2.462"} 0 Signed-off-by: Etienne Champetier --- utils/prometheus-node-exporter-lua/Makefile | 2 +- .../usr/bin/prometheus-node-exporter-lua | 83 +++++++++---------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/Makefile b/utils/prometheus-node-exporter-lua/Makefile index 6662eb060..d079e6071 100644 --- a/utils/prometheus-node-exporter-lua/Makefile +++ b/utils/prometheus-node-exporter-lua/Makefile @@ -16,7 +16,7 @@ define Package/prometheus-node-exporter-lua SECTION:=utils CATEGORY:=Utilities TITLE:=Provides system statistics as Prometheus scraping endpoint - DEPENDS:=+luasocket + DEPENDS:=+luasocket +libiwinfo-lua +libubus-lua +lua URL:=https://github.com/rbo/openwrt_exporter PKGARCH:=all endef diff --git a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua index 488374ddd..f0435ad66 100755 --- a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua @@ -69,11 +69,10 @@ function metric(name, mtype, labels, value) return outputter end -function scraper_wifi() - local rv = { } - local ntm = require "luci.model.network".init() +local ubus = require "ubus" +local iwinfo = require "iwinfo" - local metric_wifi_network_up = metric("wifi_network_up","gauge") +function scraper_wifi() local metric_wifi_network_quality = metric("wifi_network_quality","gauge") local metric_wifi_network_bitrate = metric("wifi_network_bitrate","gauge") local metric_wifi_network_noise = metric("wifi_network_noise","gauge") @@ -83,53 +82,47 @@ function scraper_wifi() local metric_wifi_station_tx_packets = metric("wifi_station_tx_packets","gauge") local metric_wifi_station_rx_packets = metric("wifi_station_rx_packets","gauge") - local dev - for _, dev in ipairs(ntm:get_wifidevs()) do - local rd = { - up = dev:is_up(), - device = dev:name(), - name = dev:get_i18n(), - networks = { } - } + local u = ubus.connect() + local status = u:call("network.wireless", "status", {}) - local net - for _, net in ipairs(dev:get_wifinets()) do + for dev, dev_table in pairs(status) do + for _, intf in ipairs(dev_table['interfaces']) do + local ifname = intf['ifname'] + local iw = iwinfo[iwinfo.type(ifname)] local labels = { - channel = net:channel(), - ssid = net:active_ssid(), - bssid = net:active_bssid(), - mode = net:active_mode(), - ifname = net:ifname(), - country = net:country(), - frequency = net:frequency(), + channel = iw.channel(ifname), + ssid = iw.ssid(ifname), + bssid = iw.bssid(ifname), + mode = iw.mode(ifname), + ifname = ifname, + country = iw.country(ifname), + frequency = iw.frequency(ifname), + device = dev, } - if net:is_up() then - metric_wifi_network_up(labels, 1) - local signal = net:signal_percent() - if signal ~= 0 then - metric_wifi_network_quality(labels, net:signal_percent()) - end - metric_wifi_network_noise(labels, net:noise()) - local bitrate = net:bitrate() - if bitrate then - metric_wifi_network_bitrate(labels, bitrate) - end - local assoclist = net:assoclist() - for mac, station in pairs(assoclist) do - local labels = { - ifname = net:ifname(), - mac = mac, - } - metric_wifi_station_signal(labels, station.signal) - metric_wifi_station_tx_packets(labels, station.tx_packets) - metric_wifi_station_rx_packets(labels, station.rx_packets) - end - else - metric_wifi_network_up(labels, 0) + local qc = iw.quality(ifname) or 0 + local qm = iw.quality_max(ifname) or 0 + local quality = 0 + if qc > 0 and qm > 0 then + quality = math.floor((100 / qm) * qc) + end + + metric_wifi_network_quality(labels, quality) + metric_wifi_network_noise(labels, iw.noise(ifname) or 0) + metric_wifi_network_bitrate(labels, iw.bitrate(ifname) or 0) + metric_wifi_network_signal(labels, iw.signal(ifname) or -255) + + local assoclist = iw.assoclist(ifname) + for mac, station in pairs(assoclist) do + local labels = { + ifname = ifname, + mac = mac, + } + metric_wifi_station_signal(labels, station.signal) + metric_wifi_station_tx_packets(labels, station.tx_packets) + metric_wifi_station_rx_packets(labels, station.rx_packets) end end - rv[#rv+1] = rd end end From 32e1baeddda2a568962c1858bae7c964b165ff31 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 06/11] prometheus-node-exporter-lua: make it modular As prometheus-node-exporter-lua is a reimplementation of node_exporter, I'm using "collector" instead of "scraper" and renaming some collectors put each collector in a separate file report collector success/failure and duration per scrape (follow https://github.com/prometheus/node_exporter/pull/516) allow to filter collectors using "collect[]" params (see https://github.com/prometheus/node_exporter#filtering-enabled-collectors) Signed-off-by: Etienne Champetier --- utils/prometheus-node-exporter-lua/Makefile | 2 + .../usr/bin/prometheus-node-exporter-lua | 288 +++--------------- .../usr/lib/lua/prometheus-collectors/cpu.lua | 39 +++ .../lib/lua/prometheus-collectors/filefd.lua | 8 + .../lib/lua/prometheus-collectors/loadavg.lua | 9 + .../lib/lua/prometheus-collectors/meminfo.lua | 13 + .../lua/prometheus-collectors/nat_traffic.lua | 33 ++ .../lib/lua/prometheus-collectors/netdev.lua | 28 ++ .../lib/lua/prometheus-collectors/netstat.lua | 20 ++ .../lib/lua/prometheus-collectors/time.lua | 6 + .../lib/lua/prometheus-collectors/uname.lua | 16 + .../lib/lua/prometheus-collectors/wifi.lua | 58 ++++ 12 files changed, 267 insertions(+), 253 deletions(-) create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/filefd.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/loadavg.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netstat.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/time.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/uname.lua create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua diff --git a/utils/prometheus-node-exporter-lua/Makefile b/utils/prometheus-node-exporter-lua/Makefile index d079e6071..2f8e4ef15 100644 --- a/utils/prometheus-node-exporter-lua/Makefile +++ b/utils/prometheus-node-exporter-lua/Makefile @@ -40,6 +40,8 @@ define Package/prometheus-node-exporter-lua/install $(INSTALL_BIN) ./files/etc/init.d/prometheus-node-exporter-lua $(1)/etc/init.d/prometheus-node-exporter-lua $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) ./files/usr/bin/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/* $(1)/usr/lib/lua/prometheus-collectors/ endef $(eval $(call BuildPackage,prometheus-node-exporter-lua)) diff --git a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua index f0435ad66..4ca77814d 100755 --- a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua @@ -11,11 +11,6 @@ socket = require("socket") -- Allow us to call unpack under both lua5.1 and lua5.2+ local unpack = unpack or table.unpack --- This table defines the scrapers to run. --- Each corresponds directly to a scraper_ function. -scrapers = { "cpu", "load_averages", "memory", "file_handles", "network", - "network_devices", "time", "uname", "nat", "wifi"} - -- Parsing function space_split(s) @@ -69,249 +64,27 @@ function metric(name, mtype, labels, value) return outputter end -local ubus = require "ubus" -local iwinfo = require "iwinfo" - -function scraper_wifi() - local metric_wifi_network_quality = metric("wifi_network_quality","gauge") - local metric_wifi_network_bitrate = metric("wifi_network_bitrate","gauge") - local metric_wifi_network_noise = metric("wifi_network_noise","gauge") - local metric_wifi_network_signal = metric("wifi_network_signal","gauge") - - local metric_wifi_station_signal = metric("wifi_station_signal","gauge") - local metric_wifi_station_tx_packets = metric("wifi_station_tx_packets","gauge") - local metric_wifi_station_rx_packets = metric("wifi_station_rx_packets","gauge") - - local u = ubus.connect() - local status = u:call("network.wireless", "status", {}) - - for dev, dev_table in pairs(status) do - for _, intf in ipairs(dev_table['interfaces']) do - local ifname = intf['ifname'] - local iw = iwinfo[iwinfo.type(ifname)] - local labels = { - channel = iw.channel(ifname), - ssid = iw.ssid(ifname), - bssid = iw.bssid(ifname), - mode = iw.mode(ifname), - ifname = ifname, - country = iw.country(ifname), - frequency = iw.frequency(ifname), - device = dev, - } - - local qc = iw.quality(ifname) or 0 - local qm = iw.quality_max(ifname) or 0 - local quality = 0 - if qc > 0 and qm > 0 then - quality = math.floor((100 / qm) * qc) - end - - metric_wifi_network_quality(labels, quality) - metric_wifi_network_noise(labels, iw.noise(ifname) or 0) - metric_wifi_network_bitrate(labels, iw.bitrate(ifname) or 0) - metric_wifi_network_signal(labels, iw.signal(ifname) or -255) - - local assoclist = iw.assoclist(ifname) - for mac, station in pairs(assoclist) do - local labels = { - ifname = ifname, - mac = mac, - } - metric_wifi_station_signal(labels, station.signal) - metric_wifi_station_tx_packets(labels, station.tx_packets) - metric_wifi_station_rx_packets(labels, station.rx_packets) - end - end - end -end - -function scraper_cpu() - local stat = get_contents("/proc/stat") - - -- system boot time, seconds since epoch - metric("node_boot_time", "gauge", nil, string.match(stat, "btime ([0-9]+)")) - - -- context switches since boot (all CPUs) - metric("node_context_switches", "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", "counter") - while string.match(stat, string.format("cpu%d ", i)) do - local cpu = space_split(string.match(stat, string.format("cpu%d ([0-9 ]+)", i))) - local labels = {cpu = "cpu" .. i} - for ii, mode in ipairs(cpu_mode) do - labels['mode'] = mode - cpu_metric(labels, cpu[ii] / 100) - end - i = i + 1 - end - - -- interrupts served - metric("node_intr", "counter", nil, string.match(stat, "intr ([0-9]+)")) - - -- processes forked - metric("node_forks", "counter", nil, string.match(stat, "processes ([0-9]+)")) - - -- processes running - metric("node_procs_running", "gauge", nil, string.match(stat, "procs_running ([0-9]+)")) - - -- processes blocked for I/O - metric("node_procs_blocked", "gauge", nil, string.match(stat, "procs_blocked ([0-9]+)")) -end - -function scraper_load_averages() - 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 - -function scraper_memory() - local meminfo = line_split(get_contents("/proc/meminfo"):gsub("[):]", ""):gsub("[(]", "_")) - - for i, mi in ipairs(meminfo) do - local name, size, unit = unpack(space_split(mi)) - if unit == 'kB' then - size = size * 1024 - end - metric("node_memory_" .. name, "gauge", nil, size) - end -end - -function scraper_file_handles() - 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 - -function scraper_network() - -- NOTE: Both of these are missing in OpenWRT kernels. - -- See: https://dev.openwrt.org/ticket/15781 - local netstat = get_contents("/proc/net/netstat") .. get_contents("/proc/net/snmp") - - -- all devices - local netsubstat = {"IcmpMsg", "Icmp", "IpExt", "Ip", "TcpExt", "Tcp", "UdpLite", "Udp"} - for i, nss in ipairs(netsubstat) do - local substat_s = string.match(netstat, nss .. ": ([A-Z][A-Za-z0-9 ]+)") - if substat_s then - local substat = space_split(substat_s) - local substatv = space_split(string.match(netstat, nss .. ": ([0-9 -]+)")) - for ii, ss in ipairs(substat) do - metric("node_netstat_" .. nss .. "_" .. ss, "gauge", nil, substatv[ii]) - end - end - end -end - -function scraper_network_devices() - local netdevstat = line_split(get_contents("/proc/net/dev")) - local netdevsubstat = {"receive_bytes", "receive_packets", "receive_errs", - "receive_drop", "receive_fifo", "receive_frame", "receive_compressed", - "receive_multicast", "transmit_bytes", "transmit_packets", - "transmit_errs", "transmit_drop", "transmit_fifo", "transmit_colls", - "transmit_carrier", "transmit_compressed"} - for i, line in ipairs(netdevstat) do - netdevstat[i] = string.match(netdevstat[i], "%S.*") - end - local nds_table = {} - local devs = {} - for i, nds in ipairs(netdevstat) do - local dev, stat_s = string.match(netdevstat[i], "([^:]+): (.*)") - if dev then - nds_table[dev] = space_split(stat_s) - table.insert(devs, dev) - end - end - for i, ndss in ipairs(netdevsubstat) do - netdev_metric = metric("node_network_" .. ndss, "gauge") - for ii, d in ipairs(devs) do - netdev_metric({device=d}, nds_table[d][i]) - end - end -end - -function scraper_time() - -- current time - metric("node_time", "counter", nil, os.time()) -end - -uname_labels = { -domainname = "", -nodename = "", -release = string.sub(get_contents("/proc/sys/kernel/osrelease"), 1, -2), -sysname = string.sub(get_contents("/proc/sys/kernel/ostype"), 1, -2), -version = string.sub(get_contents("/proc/sys/kernel/version"), 1, -2), -machine = string.sub(io.popen("uname -m"):read("*a"), 1, -2) -} - -function scraper_uname() - uname_labels["domainname"] = string.sub(get_contents("/proc/sys/kernel/domainname"), 1, -2) - uname_labels["nodename"] = string.sub(get_contents("/proc/sys/kernel/hostname"), 1, -2) - metric("node_uname_info", "gauge", uname_labels, 1) -end - -function scraper_nat() - -- documetation about nf_conntrack: - -- https://www.frozentux.net/iptables-tutorial/chunkyhtml/x1309.html - local natstat = line_split(get_contents("/proc/net/nf_conntrack")) - - nat_metric = metric("node_nat_traffic", "gauge" ) - for i, e in ipairs(natstat) do - -- output(string.format("%s\n",e )) - local fields = space_split(e) - local src, dest, bytes; - bytes = 0; - for ii, field in ipairs(fields) do - if src == nil and string.match(field, '^src') then - src = string.match(field,"src=([^ ]+)"); - elseif dest == nil and string.match(field, '^dst') then - dest = string.match(field,"dst=([^ ]+)"); - elseif string.match(field, '^bytes') then - local b = string.match(field, "bytes=([^ ]+)"); - bytes = bytes + b; - -- output(string.format("\t%d %s",ii,field )); - end - - end - -- local src, dest, bytes = string.match(natstat[i], "src=([^ ]+) dst=([^ ]+) .- bytes=([^ ]+)"); - -- local src, dest, bytes = string.match(natstat[i], "src=([^ ]+) dst=([^ ]+) sport=[^ ]+ dport=[^ ]+ packets=[^ ]+ bytes=([^ ]+)") - - local labels = { src = src, dest = dest } - -- output(string.format("src=|%s| dest=|%s| bytes=|%s|", src, dest, bytes )) - nat_metric(labels, bytes ) - end -end - -function timed_scrape(scraper) +function timed_scrape(collector) local start_time = socket.gettime() - -- build the function name and call it from global variable table - _G["scraper_"..scraper]() - local duration = socket.gettime() - start_time - return duration + 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_scrapers() - times = {} - for i,scraper in ipairs(scrapers) do - runtime = timed_scrape(scraper) - times[scraper] = runtime - scrape_time_sums[scraper] = scrape_time_sums[scraper] + runtime - scrape_counts[scraper] = scrape_counts[scraper] + 1 - end - - local name = "node_exporter_scrape_duration_seconds" - local duration_metric = metric(name, "summary") - for i,scraper in ipairs(scrapers) do - local labels = {collector=scraper, result="success"} - duration_metric(labels, times[scraper]) - print_metric(name.."_sum", labels, scrape_time_sums[scraper]) - print_metric(name.."_count", labels, scrape_counts[scraper]) +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 @@ -326,11 +99,19 @@ function http_not_found() end function serve(request) - if not string.match(request, "GET /metrics.*") then + local q = request:match("^GET /metrics%??([^ ]*) HTTP/1%.[01]$") + if q == nil then http_not_found() else http_ok_header() - run_all_scrapers() + 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 @@ -347,11 +128,12 @@ for k,v in ipairs(arg) do end end -scrape_counts = {} -scrape_time_sums = {} -for i,scraper in ipairs(scrapers) do - scrape_counts[scraper] = 0 - scrape_time_sums[scraper] = 0 +col_mods = {} +col_names = {} +for c in io.popen("ls -1 /usr/lib/lua/prometheus-collectors/*.lua"):lines() do + c = c:match("([^/]+)%.lua$") + col_mods[c] = require('prometheus-collectors.'..c) + col_names[#col_names+1] = c end if port then @@ -371,5 +153,5 @@ if port then end else output = print - run_all_scrapers() + run_all_collectors(col_names) end diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua new file mode 100644 index 000000000..0f7526eff --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua @@ -0,0 +1,39 @@ +-- stat/cpu collector +local function scrape() + local stat = get_contents("/proc/stat") + + -- system boot time, seconds since epoch + metric("node_boot_time", "gauge", nil, string.match(stat, "btime ([0-9]+)")) + + -- context switches since boot (all CPUs) + metric("node_context_switches", "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", "counter") + while string.match(stat, string.format("cpu%d ", i)) do + local cpu = space_split(string.match(stat, string.format("cpu%d ([0-9 ]+)", i))) + local labels = {cpu = "cpu" .. i} + for ii, mode in ipairs(cpu_mode) do + labels['mode'] = mode + cpu_metric(labels, cpu[ii] / 100) + end + i = i + 1 + end + + -- interrupts served + metric("node_intr", "counter", nil, string.match(stat, "intr ([0-9]+)")) + + -- processes forked + metric("node_forks", "counter", nil, string.match(stat, "processes ([0-9]+)")) + + -- processes running + metric("node_procs_running", "gauge", nil, string.match(stat, "procs_running ([0-9]+)")) + + -- processes blocked for I/O + metric("node_procs_blocked", "gauge", nil, string.match(stat, "procs_blocked ([0-9]+)")) +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/filefd.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/filefd.lua new file mode 100644 index 000000000..7e2ff6391 --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/filefd.lua @@ -0,0 +1,8 @@ +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 } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/loadavg.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/loadavg.lua new file mode 100644 index 000000000..6bfab89b0 --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/loadavg.lua @@ -0,0 +1,9 @@ +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 } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua new file mode 100644 index 000000000..a0021c4ad --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua @@ -0,0 +1,13 @@ +local function scrape() + local meminfo = line_split(get_contents("/proc/meminfo"):gsub("[):]", ""):gsub("[(]", "_")) + + for i, mi in ipairs(meminfo) do + local name, size, unit = unpack(space_split(mi)) + if unit == 'kB' then + size = size * 1024 + end + metric("node_memory_" .. name, "gauge", nil, size) + end +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua new file mode 100644 index 000000000..4173a0c5a --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua @@ -0,0 +1,33 @@ +local function scrape() + -- documetation about nf_conntrack: + -- https://www.frozentux.net/iptables-tutorial/chunkyhtml/x1309.html + local natstat = line_split(get_contents("/proc/net/nf_conntrack")) + + nat_metric = metric("node_nat_traffic", "gauge" ) + for i, e in ipairs(natstat) do + -- output(string.format("%s\n",e )) + local fields = space_split(e) + local src, dest, bytes; + bytes = 0; + for ii, field in ipairs(fields) do + if src == nil and string.match(field, '^src') then + src = string.match(field,"src=([^ ]+)"); + elseif dest == nil and string.match(field, '^dst') then + dest = string.match(field,"dst=([^ ]+)"); + elseif string.match(field, '^bytes') then + local b = string.match(field, "bytes=([^ ]+)"); + bytes = bytes + b; + -- output(string.format("\t%d %s",ii,field )); + end + + end + -- local src, dest, bytes = string.match(natstat[i], "src=([^ ]+) dst=([^ ]+) .- bytes=([^ ]+)"); + -- local src, dest, bytes = string.match(natstat[i], "src=([^ ]+) dst=([^ ]+) sport=[^ ]+ dport=[^ ]+ packets=[^ ]+ bytes=([^ ]+)") + + local labels = { src = src, dest = dest } + -- output(string.format("src=|%s| dest=|%s| bytes=|%s|", src, dest, bytes )) + nat_metric(labels, bytes ) + end +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua new file mode 100644 index 000000000..c49d4038a --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua @@ -0,0 +1,28 @@ +local function scrape() + local netdevstat = line_split(get_contents("/proc/net/dev")) + local netdevsubstat = {"receive_bytes", "receive_packets", "receive_errs", + "receive_drop", "receive_fifo", "receive_frame", "receive_compressed", + "receive_multicast", "transmit_bytes", "transmit_packets", + "transmit_errs", "transmit_drop", "transmit_fifo", "transmit_colls", + "transmit_carrier", "transmit_compressed"} + for i, line in ipairs(netdevstat) do + netdevstat[i] = string.match(netdevstat[i], "%S.*") + end + local nds_table = {} + local devs = {} + for i, nds in ipairs(netdevstat) do + local dev, stat_s = string.match(netdevstat[i], "([^:]+): (.*)") + if dev then + nds_table[dev] = space_split(stat_s) + table.insert(devs, dev) + end + end + for i, ndss in ipairs(netdevsubstat) do + netdev_metric = metric("node_network_" .. ndss, "gauge") + for ii, d in ipairs(devs) do + netdev_metric({device=d}, nds_table[d][i]) + end + end +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netstat.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netstat.lua new file mode 100644 index 000000000..cd62bffac --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netstat.lua @@ -0,0 +1,20 @@ +local function scrape() + -- NOTE: Both of these are missing in OpenWRT kernels. + -- See: https://dev.openwrt.org/ticket/15781 + local netstat = get_contents("/proc/net/netstat") .. get_contents("/proc/net/snmp") + + -- all devices + local netsubstat = {"IcmpMsg", "Icmp", "IpExt", "Ip", "TcpExt", "Tcp", "UdpLite", "Udp"} + for i, nss in ipairs(netsubstat) do + local substat_s = string.match(netstat, nss .. ": ([A-Z][A-Za-z0-9 ]+)") + if substat_s then + local substat = space_split(substat_s) + local substatv = space_split(string.match(netstat, nss .. ": ([0-9 -]+)")) + for ii, ss in ipairs(substat) do + metric("node_netstat_" .. nss .. "_" .. ss, "gauge", nil, substatv[ii]) + end + end + end +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/time.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/time.lua new file mode 100644 index 000000000..d0abb66a1 --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/time.lua @@ -0,0 +1,6 @@ +local function scrape() + -- current time + metric("node_time", "counter", nil, os.time()) +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/uname.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/uname.lua new file mode 100644 index 000000000..9874b53a9 --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/uname.lua @@ -0,0 +1,16 @@ +local labels = { + domainname = "", + nodename = "", + release = string.sub(get_contents("/proc/sys/kernel/osrelease"), 1, -2), + sysname = string.sub(get_contents("/proc/sys/kernel/ostype"), 1, -2), + version = string.sub(get_contents("/proc/sys/kernel/version"), 1, -2), + machine = string.sub(io.popen("uname -m"):read("*a"), 1, -2) +} + +local function scrape() + labels["domainname"] = string.sub(get_contents("/proc/sys/kernel/domainname"), 1, -2) + labels["nodename"] = string.sub(get_contents("/proc/sys/kernel/hostname"), 1, -2) + metric("node_uname_info", "gauge", labels, 1) +end + +return { scrape = scrape } diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua new file mode 100644 index 000000000..a57b81a70 --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua @@ -0,0 +1,58 @@ +local ubus = require "ubus" +local iwinfo = require "iwinfo" + +local function scrape() + local metric_wifi_network_quality = metric("wifi_network_quality","gauge") + local metric_wifi_network_bitrate = metric("wifi_network_bitrate","gauge") + local metric_wifi_network_noise = metric("wifi_network_noise","gauge") + local metric_wifi_network_signal = metric("wifi_network_signal","gauge") + + local metric_wifi_station_signal = metric("wifi_station_signal","gauge") + local metric_wifi_station_tx_packets = metric("wifi_station_tx_packets","gauge") + local metric_wifi_station_rx_packets = metric("wifi_station_rx_packets","gauge") + + local u = ubus.connect() + local status = u:call("network.wireless", "status", {}) + + for dev, dev_table in pairs(status) do + for _, intf in ipairs(dev_table['interfaces']) do + local ifname = intf['ifname'] + local iw = iwinfo[iwinfo.type(ifname)] + local labels = { + channel = iw.channel(ifname), + ssid = iw.ssid(ifname), + bssid = iw.bssid(ifname), + mode = iw.mode(ifname), + ifname = ifname, + country = iw.country(ifname), + frequency = iw.frequency(ifname), + device = dev, + } + + local qc = iw.quality(ifname) or 0 + local qm = iw.quality_max(ifname) or 0 + local quality = 0 + if qc > 0 and qm > 0 then + quality = math.floor((100 / qm) * qc) + end + + metric_wifi_network_quality(labels, quality) + metric_wifi_network_noise(labels, iw.noise(ifname) or 0) + metric_wifi_network_bitrate(labels, iw.bitrate(ifname) or 0) + metric_wifi_network_signal(labels, iw.signal(ifname) or -255) + + local assoclist = iw.assoclist(ifname) + for mac, station in pairs(assoclist) do + local labels = { + ifname = ifname, + mac = mac, + } + metric_wifi_station_signal(labels, station.signal) + metric_wifi_station_tx_packets(labels, station.tx_packets) + metric_wifi_station_rx_packets(labels, station.rx_packets) + end + end + end +end + +return { scrape = scrape } From fba739d32d53806e4dbac33b56a18748c2d3c4f0 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:36 -0800 Subject: [PATCH 07/11] prometheus-node-exporter-lua: put wifi collector in 2 separate packages this allow to remove libubus-lua/libiwinfo-lua dependency from main package this also allow to have different scrape_interval Signed-off-by: Etienne Champetier split stations Signed-off-by: Etienne Champetier --- utils/prometheus-node-exporter-lua/Makefile | 45 ++++++++++++++++--- .../lib/lua/prometheus-collectors/wifi.lua | 15 ------- .../prometheus-collectors/wifi_stations.lua | 31 +++++++++++++ 3 files changed, 71 insertions(+), 20 deletions(-) create mode 100644 utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi_stations.lua diff --git a/utils/prometheus-node-exporter-lua/Makefile b/utils/prometheus-node-exporter-lua/Makefile index 2f8e4ef15..84cdd8605 100644 --- a/utils/prometheus-node-exporter-lua/Makefile +++ b/utils/prometheus-node-exporter-lua/Makefile @@ -12,15 +12,18 @@ PKG_LICENSE:=Apache-2.0 include $(INCLUDE_DIR)/package.mk -define Package/prometheus-node-exporter-lua +define Package/prometheus-node-exporter-lua/Default SECTION:=utils CATEGORY:=Utilities - TITLE:=Provides system statistics as Prometheus scraping endpoint - DEPENDS:=+luasocket +libiwinfo-lua +libubus-lua +lua - URL:=https://github.com/rbo/openwrt_exporter + TITLE:=Prometheus node exporter PKGARCH:=all endef +define Package/prometheus-node-exporter-lua + $(call Package/prometheus-node-exporter-lua/Default) + DEPENDS:=+luasocket +lua +endef + define Package/prometheus-node-exporter-lua/conffiles /etc/config/prometheus-node-exporter-lua endef @@ -31,6 +34,18 @@ define Package/prometheus-node-exporter-lua/description This service is a lightweight rewrite in LUA of the offical Prometheus node_exporter. endef +define Package/prometheus-node-exporter-lua-wifi + $(call Package/prometheus-node-exporter-lua/Default) + TITLE+= (wifi collector) + DEPENDS:=prometheus-node-exporter-lua +libiwinfo-lua +libubus-lua +endef + +define Package/prometheus-node-exporter-lua-wifi_stations + $(call Package/prometheus-node-exporter-lua/Default) + TITLE+= (wifi_stations collector) + DEPENDS:=prometheus-node-exporter-lua +libiwinfo-lua +libubus-lua +endef + Build/Compile= define Package/prometheus-node-exporter-lua/install @@ -41,7 +56,27 @@ define Package/prometheus-node-exporter-lua/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) ./files/usr/bin/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/* $(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/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/nat_traffic.lua $(1)/usr/lib/lua/prometheus-collectors/ + $(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/netstat.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/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/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 $(eval $(call BuildPackage,prometheus-node-exporter-lua)) +$(eval $(call BuildPackage,prometheus-node-exporter-lua-wifi)) +$(eval $(call BuildPackage,prometheus-node-exporter-lua-wifi_stations)) diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua index a57b81a70..975b7dd5f 100644 --- a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi.lua @@ -7,10 +7,6 @@ local function scrape() local metric_wifi_network_noise = metric("wifi_network_noise","gauge") local metric_wifi_network_signal = metric("wifi_network_signal","gauge") - local metric_wifi_station_signal = metric("wifi_station_signal","gauge") - local metric_wifi_station_tx_packets = metric("wifi_station_tx_packets","gauge") - local metric_wifi_station_rx_packets = metric("wifi_station_rx_packets","gauge") - local u = ubus.connect() local status = u:call("network.wireless", "status", {}) @@ -40,17 +36,6 @@ local function scrape() metric_wifi_network_noise(labels, iw.noise(ifname) or 0) metric_wifi_network_bitrate(labels, iw.bitrate(ifname) or 0) metric_wifi_network_signal(labels, iw.signal(ifname) or -255) - - local assoclist = iw.assoclist(ifname) - for mac, station in pairs(assoclist) do - local labels = { - ifname = ifname, - mac = mac, - } - metric_wifi_station_signal(labels, station.signal) - metric_wifi_station_tx_packets(labels, station.tx_packets) - metric_wifi_station_rx_packets(labels, station.rx_packets) - end end end end diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi_stations.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi_stations.lua new file mode 100644 index 000000000..06c79a8bd --- /dev/null +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/wifi_stations.lua @@ -0,0 +1,31 @@ +local ubus = require "ubus" +local iwinfo = require "iwinfo" + +local function scrape() + local metric_wifi_station_signal = metric("wifi_station_signal","gauge") + local metric_wifi_station_tx_packets = metric("wifi_station_tx_packets","gauge") + local metric_wifi_station_rx_packets = metric("wifi_station_rx_packets","gauge") + + local u = ubus.connect() + local status = u:call("network.wireless", "status", {}) + + for dev, dev_table in pairs(status) do + for _, intf in ipairs(dev_table['interfaces']) do + local ifname = intf['ifname'] + local iw = iwinfo[iwinfo.type(ifname)] + + local assoclist = iw.assoclist(ifname) + for mac, station in pairs(assoclist) do + local labels = { + ifname = ifname, + mac = mac, + } + metric_wifi_station_signal(labels, station.signal) + metric_wifi_station_tx_packets(labels, station.tx_packets) + metric_wifi_station_rx_packets(labels, station.rx_packets) + end + end + end +end + +return { scrape = scrape } From 84023027a2196f898f4b1fbc151b27626ec67923 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:37 -0800 Subject: [PATCH 08/11] prometheus-node-exporter-lua: split out nat_traffic and netstat nat_traffic is too verbose to be really useful by default netstat is broken by default on OpenWrt/LEDE Signed-off-by: Etienne Champetier --- utils/prometheus-node-exporter-lua/Makefile | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/Makefile b/utils/prometheus-node-exporter-lua/Makefile index 84cdd8605..5a93c06d8 100644 --- a/utils/prometheus-node-exporter-lua/Makefile +++ b/utils/prometheus-node-exporter-lua/Makefile @@ -34,6 +34,18 @@ define Package/prometheus-node-exporter-lua/description This service is a lightweight rewrite in LUA of the offical Prometheus node_exporter. endef +define Package/prometheus-node-exporter-lua-nat_traffic + $(call Package/prometheus-node-exporter-lua/Default) + TITLE+= (nat_traffic collector) + DEPENDS:=prometheus-node-exporter-lua +endef + +define Package/prometheus-node-exporter-lua-netstat + $(call Package/prometheus-node-exporter-lua/Default) + TITLE+= (netstat collector) + DEPENDS:=prometheus-node-exporter-lua +endef + define Package/prometheus-node-exporter-lua-wifi $(call Package/prometheus-node-exporter-lua/Default) TITLE+= (wifi collector) @@ -60,13 +72,21 @@ define Package/prometheus-node-exporter-lua/install $(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/nat_traffic.lua $(1)/usr/lib/lua/prometheus-collectors/ - $(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/netstat.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/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/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/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/ @@ -78,5 +98,7 @@ define Package/prometheus-node-exporter-lua-wifi_stations/install endef $(eval $(call BuildPackage,prometheus-node-exporter-lua)) +$(eval $(call BuildPackage,prometheus-node-exporter-lua-nat_traffic)) +$(eval $(call BuildPackage,prometheus-node-exporter-lua-netstat)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-wifi)) $(eval $(call BuildPackage,prometheus-node-exporter-lua-wifi_stations)) From ed7d60d8710c63eeb4c6d094eb6038c3dc7d86c8 Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:37 -0800 Subject: [PATCH 09/11] prometheus-node-exporter-lua: use io.lines(), remove line_split Signed-off-by: Etienne Champetier --- .../usr/bin/prometheus-node-exporter-lua | 13 +--------- .../lib/lua/prometheus-collectors/meminfo.lua | 8 +++--- .../lua/prometheus-collectors/nat_traffic.lua | 6 ++--- .../lib/lua/prometheus-collectors/netdev.lua | 25 ++++++++----------- 4 files changed, 17 insertions(+), 35 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua index 4ca77814d..62e402280 100755 --- a/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua +++ b/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua @@ -8,27 +8,16 @@ socket = require("socket") --- Allow us to call unpack under both lua5.1 and lua5.2+ -local unpack = unpack or table.unpack - -- Parsing function space_split(s) - elements = {} + local elements = {} for element in s:gmatch("%S+") do table.insert(elements, element) end return elements end -function line_split(s) - elements = {} - for element in s:gmatch("[^\n]+") do - table.insert(elements, element) - end - return elements -end - function get_contents(filename) local f = io.open(filename, "rb") local contents = "" diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua index a0021c4ad..01f262b47 100644 --- a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/meminfo.lua @@ -1,12 +1,10 @@ local function scrape() - local meminfo = line_split(get_contents("/proc/meminfo"):gsub("[):]", ""):gsub("[(]", "_")) - - for i, mi in ipairs(meminfo) do - local name, size, unit = unpack(space_split(mi)) + for line in io.lines("/proc/meminfo") do + local name, size, unit = string.match(line, "([^:]+):%s+(%d+)%s?(k?B?)") if unit == 'kB' then size = size * 1024 end - metric("node_memory_" .. name, "gauge", nil, size) + metric("node_memory_" .. name:gsub("[):]", ""):gsub("[(]", "_"), "gauge", nil, size) end end diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua index 4173a0c5a..0b2da7dc3 100644 --- a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/nat_traffic.lua @@ -1,15 +1,13 @@ local function scrape() -- documetation about nf_conntrack: -- https://www.frozentux.net/iptables-tutorial/chunkyhtml/x1309.html - local natstat = line_split(get_contents("/proc/net/nf_conntrack")) - nat_metric = metric("node_nat_traffic", "gauge" ) - for i, e in ipairs(natstat) do + for e in io.lines("/proc/net/nf_conntrack") do -- output(string.format("%s\n",e )) local fields = space_split(e) local src, dest, bytes; bytes = 0; - for ii, field in ipairs(fields) do + for _, field in ipairs(fields) do if src == nil and string.match(field, '^src') then src = string.match(field,"src=([^ ]+)"); elseif dest == nil and string.match(field, '^dst') then diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua index c49d4038a..9127e12b4 100644 --- a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/netdev.lua @@ -1,26 +1,23 @@ -local function scrape() - local netdevstat = line_split(get_contents("/proc/net/dev")) - local netdevsubstat = {"receive_bytes", "receive_packets", "receive_errs", + +local netdevsubstat = {"receive_bytes", "receive_packets", "receive_errs", "receive_drop", "receive_fifo", "receive_frame", "receive_compressed", "receive_multicast", "transmit_bytes", "transmit_packets", "transmit_errs", "transmit_drop", "transmit_fifo", "transmit_colls", "transmit_carrier", "transmit_compressed"} - for i, line in ipairs(netdevstat) do - netdevstat[i] = string.match(netdevstat[i], "%S.*") - end +local pattern = "([^%s:]+):%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)" + +local function scrape() local nds_table = {} - local devs = {} - for i, nds in ipairs(netdevstat) do - local dev, stat_s = string.match(netdevstat[i], "([^:]+): (.*)") - if dev then - nds_table[dev] = space_split(stat_s) - table.insert(devs, dev) + for line in io.lines("/proc/net/dev") do + local t = {string.match(line, pattern)} + if #t == 17 then + nds_table[t[1]] = t end end for i, ndss in ipairs(netdevsubstat) do netdev_metric = metric("node_network_" .. ndss, "gauge") - for ii, d in ipairs(devs) do - netdev_metric({device=d}, nds_table[d][i]) + for dev, nds_dev in pairs(nds_table) do + netdev_metric({device=dev}, nds_dev[i+1]) end end end From ea5b7492fe9894ed85fa0b0c1260cbb479c1c4ce Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:37 -0800 Subject: [PATCH 10/11] prometheus-node-exporter-lua: rework cpu collector replace 2 string.match and 1 string.gmatch (space_split) by 1 string.match Signed-off-by: Etienne Champetier --- .../files/usr/lib/lua/prometheus-collectors/cpu.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua index 0f7526eff..9d083dbf0 100644 --- a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua +++ b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/cpu.lua @@ -13,12 +13,13 @@ local function scrape() "softirq", "steal", "guest", "guest_nice"} local i = 0 local cpu_metric = metric("node_cpu", "counter") - while string.match(stat, string.format("cpu%d ", i)) do - local cpu = space_split(string.match(stat, string.format("cpu%d ([0-9 ]+)", i))) - local labels = {cpu = "cpu" .. i} + 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 - labels['mode'] = mode - cpu_metric(labels, cpu[ii] / 100) + cpu_metric({cpu="cpu"..i, mode=mode}, cpu[ii] / 100) end i = i + 1 end From d1b461137a689ca8ce681df115b89e929be001dc Mon Sep 17 00:00:00 2001 From: Etienne Champetier Date: Fri, 8 Dec 2017 19:03:37 -0800 Subject: [PATCH 11/11] prometheus-node-exporter-lua: bump version Signed-off-by: Etienne Champetier --- utils/prometheus-node-exporter-lua/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/prometheus-node-exporter-lua/Makefile b/utils/prometheus-node-exporter-lua/Makefile index 5a93c06d8..8f9e3ccad 100644 --- a/utils/prometheus-node-exporter-lua/Makefile +++ b/utils/prometheus-node-exporter-lua/Makefile @@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=prometheus-node-exporter-lua -PKG_VERSION:=2017.05.07 +PKG_VERSION:=2017.12.08 PKG_RELEASE:=1 PKG_MAINTAINER:=Christian Simon