-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_http_json.lua
117 lines (92 loc) · 2.58 KB
/
check_http_json.lua
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
--
-- Copyright (c) 2010, Cloudkick, Inc.
-- All right reserved.
--
module(..., package.seeall);
local util = require 'util'
local log = util.log
local json = require 'Json'
local Check = util.Check
local http = require 'socket.http'
local ltn12 = require 'ltn12'
local function get_response(url, rcheck)
local response = {}
local r, code = http.request{url = url, sink = ltn12.sink.table(response)}
if r == nil then
rcheck:set_error('GET on %s failed: %s', url, code)
return nil
end
if (code >= 300 or code < 200) then
rcheck:set_error('GET on %s returned %s', url, code)
return nil
end
if response == nil then
rcheck:set_error('GET on %s returned no body', url)
else
log.dbg("Response body %s", table.concat(response))
end
return table.concat(response)
end
local function parse_json_response(response, rcheck)
local metric_name, metric_type, metric_value, value_type
local rv, decoded = pcall(json.Decode, response)
local valid_states = { 'ok', 'warn', 'err' }
local valid_metric_types = { 'int', 'float', 'gauge', 'string' }
if not rv then
rcheck:set_error('Failed to parse response as JSON')
return
end
local status = decoded.status
local state = decoded.state
local metrics = decoded.metrics
if not status then
status = ''
end
if not metrics then
metrics = {}
end
if not state then
rcheck:set_error('Check state missing')
return
end
if not table.contains(valid_states, state) then
rcheck:set_error('Invalid check state: %s', state)
return
end
rcheck:set_status(status)
if state == 'ok' then
rcheck:set_state_avail('A', 'G')
elseif state == 'warn' then
rcheck:set_state_avail('A', 'B')
elseif state == 'err' then
rcheck:set_state_avail('U', 'B')
end
for index, metric in pairs(metrics) do repeat
metric_name = metric['name']
metric_type = metric['type']
metric_value = metric['value']
if not metric_name or not metric_type or not metric_value then
-- Skip metrics with missing keys
break
end
if not table.contains(valid_metric_types, metric_type) then
-- Ignore invalid metric types
break
end
value_type = util.string_to_value_type(metric_type)
rcheck:add_metric(metric_name, metric_value, value_type)
until true end
end
function run(rcheck, args)
local url
if not args.url then
rcheck:set_error('Missing required argument \'url\'')
return rcheck
end
url = args.url[1]
local response = get_response(url, rcheck)
if response then
parse_json_response(response, rcheck)
end
return rcheck
end