prometheus-node-exporter-lua: use uhttpd-mod-lua
authorEtienne Champetier <champetier.etienne@gmail.com>
Sun, 24 Apr 2022 03:29:30 +0000 (23:29 -0400)
committerEtienne Champetier <champetier.etienne@gmail.com>
Mon, 25 Apr 2022 16:22:22 +0000 (12:22 -0400)
listen_ipv6 config option is removed and we now
listen on both ipv4 and ipv6 addresses.
HTTP keepalive is enabled and set to 70s by default.

With uhttpd-mod-lua there is a small change in behavior,
all code is loaded/parsed/executed once on startup as before,
but now each request is executed in his own fork, so we can't
keep a state between requests.

Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
utils/prometheus-node-exporter-lua/Makefile
utils/prometheus-node-exporter-lua/files/etc/config/prometheus-node-exporter-lua
utils/prometheus-node-exporter-lua/files/etc/init.d/prometheus-node-exporter-lua
utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua

index f5caed7cdab02fb13ca3ee04755d82671051adb0..b5472c68f53c51b74850da6e79f8167edc4d6ea3 100644 (file)
@@ -4,7 +4,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=prometheus-node-exporter-lua
-PKG_VERSION:=2022.04.18
+PKG_VERSION:=2022.04.23
 PKG_RELEASE:=1
 
 PKG_MAINTAINER:=Etienne CHAMPETIER <champetier.etienne@gmail.com>
@@ -23,7 +23,7 @@ endef
 
 define Package/prometheus-node-exporter-lua
   $(call Package/prometheus-node-exporter-lua/Default)
-  DEPENDS:=+luasocket +lua
+  DEPENDS:=+luasocket +lua +uhttpd +uhttpd-mod-lua
 endef
 
 define Package/prometheus-node-exporter-lua/install
index 585e29b33550ca3c4a0895b8e252295fe81ff387..d424fe6322c66436720d1b7a2fdc9eed1ffd9814 100644 (file)
@@ -1,4 +1,3 @@
 config prometheus-node-exporter-lua 'main'
        option listen_interface 'loopback'
-       option listen_ipv6 '0'
        option listen_port '9100'
index 582e2116153de47869a0138118d0ccf229eab4d5..57440d5efa6b0434d6420a89532b4bd3fb7f5980 100644 (file)
@@ -11,34 +11,31 @@ _log() {
 start_service() {
        . /lib/functions/network.sh
 
-       local interface ipv6 port bind
+       local interface port bind
 
        config_load prometheus-node-exporter-lua.main
+       config_get keepalive "main" http_keepalive 70
        config_get interface "main" listen_interface "loopback"
-       config_get_bool ipv6 "main" listen_ipv6 0
        config_get port "main" listen_port 9100
 
+       procd_open_instance
+
+       procd_set_param command /usr/sbin/uhttpd -f -c /dev/null -l / -L /usr/bin/prometheus-node-exporter-lua
+       [ $keepalive -gt 0 ] && procd_append_param command -k $keepalive
+
        if [ "$interface" = "*" ]; then
-               [ "$ipv6" = 1 ] && bind="::" || bind="0.0.0.0"
+               procd_append_param command -p $port
        else
-               if [ "$ipv6" = 1 ]; then
-                       network_get_ipaddr6 bind "$interface"
-               else
-                       network_get_ipaddr bind "$interface"
-               fi
-
-               network_is_up "$interface" && [ -n "$bind" ] || {
+               network_is_up "$interface" || {
                        _log "defering start until listen interface $interface becomes ready"
                        return 0
                }
+               network_get_ipaddr6 bind "$interface"
+               [ -n "$bind" ] && procd_append_param command -p [$bind]:$port
+               network_get_ipaddr bind "$interface"
+               [ -n "$bind" ] && procd_append_param command -p $bind:$port
        fi
 
-       procd_open_instance
-
-       procd_set_param command /usr/bin/prometheus-node-exporter-lua
-       procd_append_param command --bind ${bind}
-       procd_append_param command --port ${port}
-
        procd_set_param stdout 1
        procd_set_param stderr 1
        procd_set_param respawn
index dec55baa1b1f9b9f0e33c01c47e7bc9505db28e3..36f064c5b4f111ab364b31e4b5ba4518439fffd4 100755 (executable)
@@ -59,7 +59,7 @@ function timed_scrape(collector)
   local status, err = pcall(collector.scrape)
   if not status then
     success = 0
-    print(err)
+    io.stderr:write(err)
   end
   return (socket.gettime() - start_time), success
 end
@@ -79,22 +79,18 @@ 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()
+function handle_request(env)
+  if env.PATH_INFO ~= '/metrics' then
+    uhttpd.send("Status: 404 Not Found\r\n")
+    uhttpd.send("Server: lua-metrics\r\n")
+    uhttpd.send("Content-Type: text/plain\r\n\r\n")
+    uhttpd.send("ERROR: File Not Found.")
   else
-    http_ok_header()
+    uhttpd.send("Status: 200 OK\r\n")
+    uhttpd.send("Server: lua-metrics\r\n")
+    uhttpd.send("Content-Type: text/plain; version=0.0.4\r\n\r\n")
     local cols = {}
-    for c in q:gmatch("collect[^=]*=([^&]+)") do
+    for c in env.QUERY_STRING:gmatch("collect[^=]*=([^&]+)") do
       cols[#cols+1] = c
     end
     if #cols == 0 then
@@ -102,21 +98,10 @@ function serve(request)
     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")
@@ -127,22 +112,9 @@ for c in ls_fd:lines() do
 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()
+output = function (str) uhttpd.send(str.."\n") end
 
-    if not err then
-      output = function (str) client:send(str.."\n") end
-      if not serve(request) then
-        break
-      end
-    end
-  end
-else
+if arg ~= nil then
   output = print
   run_all_collectors(col_names)
 end