summaryrefslogtreecommitdiffstats
path: root/utils/prometheus-node-exporter-lua/files/usr/bin/prometheus-node-exporter-lua
blob: 93ecc954e9bb5b4b03ba0fca792b7f39643e8aca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/lua

-- Metrics web server

-- Copyright (c) 2016 Jeff Schornick <jeff@schornick.org>
-- Copyright (c) 2015 Kevin Lyda <kevin@lyda.ie>
-- Licensed under the Apache License, Version 2.0

socket = require("socket")

-- get configs

local omit_zero_values = os.getenv("OMIT_ZERO_VALUES") == "1"

-- 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)
  if type(value) == "nil" then
    return
  end
  out:write(metric)
  if labels then
    out:write("{")
    coma = ""
    for label,value in pairs(labels) do
      out:write(coma, label, '="', value, '"')
      coma = ","
    end
    out:write("}")
  end
  out:write(" ", value, "\n")
end

function metric(name, mtype, labels, value)
  out:write("# TYPE ", name, " ", mtype, "\n")
  -- omit_zero_vales config supress time series always being zero
  local printall = not (mtype == "counter" and omit_zero_values)
  local outputter = function(labels, value)
    if printall or tonumber(value) ~= 0 then
      print_metric(name, labels, value)
    end
  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
    io.stderr:write(err .. '\n')
  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 handle_request(env)
  -- use buffered output instead uhttpd.send()
  out = io.open("/proc/self/fd/1", "a+")
  out:setvbuf("full")
  if env.PATH_INFO ~= '/metrics' then
    out:write("Status: 404 Not Found\r\n")
    out:write("Server: lua-metrics\r\n")
    out:write("Content-Type: text/plain\r\n\r\n")
    out:write("ERROR: File Not Found.")
  else
    out:write("Status: 200 OK\r\n")
    out:write("Server: lua-metrics\r\n")
    out:write("Content-Type: text/plain; version=0.0.4\r\n\r\n")
    local cols = {}
    for c in env.QUERY_STRING:gmatch("collect[^=]*=([^&]+)") do
      cols[#cols+1] = c
    end
    if #cols == 0 then
      cols = col_names
    end
    run_all_collectors(cols)
  end
  out:flush()
end

-- Main program

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 arg ~= nil then
  out = io.output()
  run_all_collectors(col_names)
end