Comparison

mod_statistics/prosodytop.lua @ 1072:4dbdb1b465e8

mod_statistics: Initial version, and a rough 'prosodyctl mod_statistics top'
author Matthew Wild <mwild1@gmail.com>
date Sat, 15 Jun 2013 19:08:34 +0100
child 1085:56fc7a86eb20
comparison
equal deleted inserted replaced
1071:8f59b45fe6a7 1072:4dbdb1b465e8
1 local curses = require "curses";
2 local server = require "net.server_select";
3 local timer = require "util.timer";
4
5 assert(curses.timeout, "Incorrect version of curses library. Try 'sudo luarocks install luaposix'");
6
7 local top = require "top";
8
9 function main()
10 local stdscr = curses.stdscr() -- it's a userdatum
11 --stdscr:clear();
12 local view = top.new({
13 stdscr = stdscr;
14 prosody = { up_since = os.time() };
15 conn_list = {};
16 });
17
18 timer.add_task(0.01, function ()
19 local ch = stdscr:getch();
20 if ch then
21 if stdscr:getch() == 410 then
22 view:resized();
23 else
24 curses.ungetch(ch);
25 end
26 end
27 return 0.2;
28 end);
29
30 timer.add_task(0, function ()
31 view:draw();
32 return 1;
33 end);
34
35 --[[
36 posix.signal(28, function ()
37 table.insert(view.conn_list, { jid = "WINCH" });
38 --view:draw();
39 end);
40 ]]
41
42 -- Fake socket object around stdin
43 local stdin = {
44 getfd = function () return 0; end;
45 dirty = function (self) return false; end;
46 settimeout = function () end;
47 send = function (_, d) return #d, 0; end;
48 close = function () end;
49 receive = function (_, patt)
50 local ch = stdscr:getch();
51 if ch >= 0 and ch <=255 then
52 return string.char(ch);
53 elseif ch == 410 then
54 view:resized();
55 else
56 table.insert(view.conn_list, { jid = tostring(ch) }); --FIXME
57 end
58 return "";
59 end
60 };
61 local function on_incoming(stdin, text)
62 -- TODO: Handle keypresses
63 if text:lower() == "q" then os.exit(); end
64 end
65 stdin = server.wrapclient(stdin, "stdin", 0, {
66 onincoming = on_incoming, ondisconnect = function () end
67 }, "*a");
68
69 local function handle_line(line)
70 local e = {
71 STAT = function (name) return function (value)
72 view:update_stat(name, value);
73 end end;
74 SESS = function (id) return function (jid) return function (stats)
75 view:update_session(id, jid, stats);
76 end end end;
77 };
78 local chunk = assert(loadstring(line));
79 setfenv(chunk, e);
80 chunk();
81 end
82
83 local stats_listener = {};
84
85 function stats_listener.onconnect(conn)
86 --stdscr:mvaddstr(6, 0, "CONNECTED");
87 end
88
89 local partial;
90 function stats_listener.onincoming(conn, data)
91 --print("DATA", data)
92 if partial then
93 partial, data = nil, partial..data;
94 end
95 if not data:match("\n") then
96 partial = data;
97 return;
98 end
99 local lastpos = 1;
100 for line, pos in data:gmatch("([^\n]+)\n()") do
101 lastpos = pos;
102 handle_line(line);
103 end
104 if lastpos == #data then
105 partial = nil;
106 else
107 partial = data:sub(lastpos+1);
108 end
109 end
110
111 function stats_listener.ondisconnect(conn, err)
112 stdscr:mvaddstr(6, 0, "DISCONNECTED: "..(err or "unknown"));
113 end
114
115 local conn = require "socket".tcp();
116 assert(conn:connect("localhost", 5782));
117 handler = server.wrapclient(conn, "localhost", 5279, stats_listener, "*a");
118 end
119
120 return {
121 run = function ()
122 --os.setlocale("UTF-8", "all")
123
124 curses.initscr()
125 curses.cbreak()
126 curses.echo(false) -- not noecho !
127 curses.nl(false) -- not nonl !
128 curses.timeout(0);
129
130 local ok, err = pcall(main);
131
132 --while true do stdscr:getch() end
133 --stdscr:endwin()
134
135 if ok then
136 ok, err = xpcall(server.loop, debug.traceback);
137 end
138
139 curses.endwin();
140
141 --stdscr:refresh();
142 if not ok then
143 print(err);
144 end
145
146 print"DONE"
147 end;
148 };