Mercurial > prosody-modules
comparison mod_server_status/mod_server_status.lua @ 541:947103177844
mod_server_status: renamed mod_xml_status to mod_server_status as the option to output the stats in JSON was added.
| author | Marco Cirillo <maranda@lightwitch.org> |
|---|---|
| date | Tue, 10 Jan 2012 19:36:28 +0000 |
| parents | mod_xml_status/mod_xml_status.lua@967ba17b1d2a |
| children | 32d9fd110cb1 |
comparison
equal
deleted
inserted
replaced
| 540:31c29832ef3e | 541:947103177844 |
|---|---|
| 1 -- (C) 2011, Marco Cirillo (LW.Org) | |
| 2 -- Display server stats in readable XML or JSON format | |
| 3 | |
| 4 module:set_global() | |
| 5 | |
| 6 local ports = module:get_option_array("server_status_http_ports", {{ port = 5280 }}) | |
| 7 local show_hosts = module:get_option_array("server_status_show_hosts", nil) | |
| 8 local show_comps = module:get_option_array("server_status_show_comps", nil) | |
| 9 local json_output = module:get_option_boolean("server_status_json", false) | |
| 10 | |
| 11 local httpserver = require "net.httpserver" | |
| 12 local json_encode = require "util.json".encode | |
| 13 | |
| 14 -- code begin | |
| 15 | |
| 16 if not prosody.stanza_counter and not show_hosts and not show_comps then | |
| 17 module:log ("error", "mod_server_status requires at least one of the following things:") | |
| 18 module:log ("error", "mod_stanza_counter loaded, or either server_status_show_hosts or server_status_show_comps configuration values set.") | |
| 19 module:log ("error", "check the module wiki at: http://code.google.com/p/prosody-modules/wiki/mod_server_status") | |
| 20 return false | |
| 21 end | |
| 22 | |
| 23 local r_err = "\n<html>\n<head>\n<title>Prosody's Server Status - Error %s</title>\n<meta name=\"robots\" content=\"noindex, nofollow\" />\n</head>\n\n<body>\n<h3>%s</h3>\n</body>\n\n</html>\n" | |
| 24 | |
| 25 local response_table = {} | |
| 26 response_table.header = '<?xml version="1.0" encoding="UTF-8" ?>' | |
| 27 response_table.doc_header = '<document>' | |
| 28 response_table.doc_closure = '</document>' | |
| 29 response_table.stanzas = { | |
| 30 elem_header = ' <stanzas>', elem_closure = ' </stanzas>', | |
| 31 incoming = ' <incoming iq="%d" message="%d" presence="%d" />', | |
| 32 outgoing = ' <outgoing iq="%d" message="%d" presence="%d" />' | |
| 33 } | |
| 34 response_table.hosts = { | |
| 35 elem_header = ' <hosts>', elem_closure = ' </hosts>', | |
| 36 status = ' <status name="%s" current="%s" />' | |
| 37 } | |
| 38 response_table.comps = { | |
| 39 elem_header = ' <components>', elem_closure = ' </components>', | |
| 40 status = ' <status name="%s" current="%s" />' | |
| 41 } | |
| 42 | |
| 43 local function forge_response_xml() | |
| 44 local hosts_s = {}; local components = {}; local stats = {}; local hosts_stats = {}; local comps_stats = {} | |
| 45 | |
| 46 local function t_builder(t,r) for _, bstring in ipairs(t) do r[#r+1] = bstring end end | |
| 47 | |
| 48 if show_hosts then t_builder(show_hosts, hosts_s) end | |
| 49 if show_comps then t_builder(show_comps, components) end | |
| 50 | |
| 51 -- build stanza stats if there | |
| 52 if prosody.stanza_counter then | |
| 53 stats[1] = response_table.stanzas.elem_header | |
| 54 stats[2] = response_table.stanzas.incoming:format(prosody.stanza_counter.iq["incoming"], | |
| 55 prosody.stanza_counter.message["incoming"], | |
| 56 prosody.stanza_counter.presence["incoming"]) | |
| 57 stats[3] = response_table.stanzas.outgoing:format(prosody.stanza_counter.iq["outgoing"], | |
| 58 prosody.stanza_counter.message["outgoing"], | |
| 59 prosody.stanza_counter.presence["outgoing"]) | |
| 60 stats[4] = response_table.stanzas.elem_closure | |
| 61 end | |
| 62 | |
| 63 -- build hosts stats if there | |
| 64 if hosts_s[1] then | |
| 65 hosts_stats[1] = response_table.hosts.elem_header | |
| 66 for _, name in ipairs(hosts_s) do | |
| 67 hosts_stats[#hosts_stats+1] = response_table.hosts.status:format( | |
| 68 name, hosts[name] and "online" or "offline") | |
| 69 end | |
| 70 hosts_stats[#hosts_stats+1] = response_table.hosts.elem_closure | |
| 71 end | |
| 72 | |
| 73 -- build components stats if there | |
| 74 if components[1] then | |
| 75 comps_stats[1] = response_table.comps.elem_header | |
| 76 for _, name in ipairs(components) do | |
| 77 comps_stats[#comps_stats+1] = response_table.comps.status:format( | |
| 78 name, hosts[name].modules.component and hosts[name].modules.component.connected and "online" or | |
| 79 hosts[name] and hosts[name].modules.component == nil and "online" or "offline") | |
| 80 end | |
| 81 comps_stats[#comps_stats+1] = response_table.comps.elem_closure | |
| 82 end | |
| 83 | |
| 84 -- build xml document | |
| 85 local result = {} | |
| 86 result[#result+1] = response_table.header; result[#result+1] = response_table.doc_header -- start | |
| 87 t_builder(stats, result); t_builder(hosts_stats, result); t_builder(comps_stats, result) | |
| 88 result[#result+1] = response_table.doc_closure -- end | |
| 89 | |
| 90 return table.concat(result, "\n") | |
| 91 end | |
| 92 | |
| 93 local function forge_response_json() | |
| 94 local result = {} | |
| 95 | |
| 96 if prosody.stanza_counter then result.stanzas = {} ; result.stanzas = prosody.stanza_counter end | |
| 97 if show_hosts then | |
| 98 result.hosts = {} | |
| 99 for _,n in ipairs(show_hosts) do result.hosts[n] = hosts[name] and "online" or "offline" end | |
| 100 end | |
| 101 if show_comps then | |
| 102 result.comps = {} | |
| 103 for _,n in ipairs(show_hosts) do | |
| 104 result.comps[n] = hosts[name].modules.component and hosts[name].modules.component.connected and "online" or | |
| 105 hosts[name] and hosts[name].modules.component == nil and "online" or "offline" | |
| 106 end | |
| 107 end | |
| 108 | |
| 109 return json_encode(result) | |
| 110 end | |
| 111 | |
| 112 -- http handlers | |
| 113 | |
| 114 local function response(code, r, h) | |
| 115 local response = { status = code, body = r } | |
| 116 | |
| 117 if h then response.headers = h end | |
| 118 return response | |
| 119 end | |
| 120 | |
| 121 local function request(method, body, request) | |
| 122 if method == "GET" then | |
| 123 if not json_output then return response(200, forge_response_xml()) else return response(200, forge_response_json()) end | |
| 124 else | |
| 125 local err405 = r_err:format("405", "Only GET is supported") | |
| 126 return response(405, err405, {["Allow"] = "GET"}) | |
| 127 end | |
| 128 end | |
| 129 | |
| 130 -- initialization. | |
| 131 -- init http interface | |
| 132 local function setup() | |
| 133 httpserver.new_from_config(ports, request, { base = "server-status" }) | |
| 134 end | |
| 135 | |
| 136 if prosody.start_time then | |
| 137 setup() | |
| 138 else | |
| 139 module:hook("server-started", setup) | |
| 140 end |
