Electroneum
Loading...
Searching...
No Matches
munin_connection_handler.h
Go to the documentation of this file.
1// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution.
11// * Neither the name of the Andrey N. Sabelnikov nor the
12// names of its contributors may be used to endorse or promote products
13// derived from this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26
27
28
29#ifndef _MUNIN_CONNECTION_HANDLER_H_
30#define _MUNIN_CONNECTION_HANDLER_H_
31
32#include <string>
33#include "net_utils_base.h"
35#include "http_base.h"
36#include "reg_exp_definer.h"
37
38#define MUNIN_ARGS_DEFAULT(vertial_lable_str) "graph_args --base 1000 -l 0 --vertical-label " vertial_lable_str " \n"
39#define MUNIN_ARGS_FORCE_AUPPER_LIMIT(vertial_lable_str, limit) "graph_args --base 1000 -l 0 --vertical-label " vertial_lable_str " --rigid --upper-limit " limit " \n"
40#define MUNIN_TITLE(title_str) "graph_title " title_str "\n"
41#define MUNIN_CATEGORY(category_str) "graph_category " category_str "\n"
42#define MUNIN_INFO(info_str) "graph_info " info_str "\n"
43#define MUNIN_ENTRY(var_name) #var_name".label " #var_name "\n" #var_name".info "#var_name".\n"
44#define MUNIN_ENTRY_AREA(var_name) #var_name".label " #var_name "\n" #var_name".info "#var_name".\n" #var_name".draw AREASTACK\n"
45#define MUNIN_ENTRY_ALIAS(var_name, alias) #var_name".label " #alias"\n" #var_name".info "#alias".\n"
46#define BEGIN_MUNIN_SERVICE(servivece_name_str) if(servivece_name_str == pservice->m_service_name) {
47#define END_MUNIN_SERVICE() }
48#define MUNIN_SERVICE_PARAM(munin_var_name_str, variable) paramters_text += std::string() + munin_var_name_str ".value " + boost::lexical_cast<std::string>(variable) + "\n"
49
50
51
52
53namespace epee
54{
55namespace net_utils
56{
57 namespace munin
58 {
59
60
61 /************************************************************************/
62 /* */
63 /************************************************************************/
64 struct munin_service;
65
67 {
68 virtual bool update_service_data(munin_service* pservice, std::string& paramters_text)=0;
69 };
70
77
79 {
80 std::list<munin_service> m_services;
81 //TODO:
82 };
83
85 {
86 virtual bool do_send(const void* ptr, size_t cb)
87 {
88 m_cache += std::string((const char*)ptr, cb);
89 return true;
90 }
91 public:
92
93 std::string m_cache;
94 };
95
96 /************************************************************************/
97 /* */
98 /************************************************************************/
100 {
101 public:
104
106 m_machine_state(http_state_retriving_comand_line),
107 m_config(config)
108 {
109 init();
110 }
112 {
113
114 }
115
117 {
118 return true;
119 }
121 {
122 std::string hello_str = "# munin node at ";
123 hello_str += m_host_name + "\n";
124 send_hook(hello_str);
125 return true;
126 }
127
128 virtual bool thread_init()
129 {
130 return true;
131 }
132
133 virtual bool thread_deinit()
134 {
135 return true;
136 }
137
139 {
140
141 }
142
143 virtual bool handle_recv(const void* ptr, size_t cb)
144 {
145
146 const char* pbuff = (const char*)ptr;
147 std::string recvd_buff(pbuff, cb);
148 LOG_PRINT("munin_recv: \n" << recvd_buff, LOG_LEVEL_3);
149
150 m_cache += recvd_buff;
151
152 bool stop_handling = false;
153 while(!stop_handling)
154 {
155 switch(m_machine_state)
156 {
157 case http_state_retriving_comand_line:
158 {
159
160 std::string::size_type fpos = m_cache.find('\n');
161 if(std::string::npos != fpos )
162 {
163 bool res = handle_command(m_cache);
164 if(!res)
165 return false;
166 m_cache.erase(0, fpos+1);
167 continue;
168 }
169 stop_handling = true;
170 }
171 break;
172 case http_state_error:
173 stop_handling = true;
174 return false;
175 default:
176 LOG_ERROR("Error in munin state machine! Unknown state=" << m_machine_state);
177 stop_handling = true;
178 m_machine_state = http_state_error;
179 return false;
180 }
181
182 }
183
184 return true;
185 }
186
187 private:
188
189
190 bool init()
191 {
192 char hostname[64] = {0};
193 int res = gethostname(hostname, 64);
194 hostname[63] = 0;//be happy
195 m_host_name = hostname;
196 return true;
197 }
198 bool handle_command(const std::string& command)
199 {
200 // list, nodes, config, fetch, version or quit
201 STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^((list)|(nodes)|(config)|(fetch)|(version)|(quit))(\\s+(\\S+))?", boost::regex::icase | boost::regex::normal);
202 // 12 3 4 5 6 7 8 9
203 size_t match_len = 0;
204 boost::smatch result;
205 if(boost::regex_search(command, result, rexp_match_command_line, boost::match_default) && result[0].matched)
206 {
207 if(result[2].matched)
208 {//list command
209 return handle_list_command();
210 }else if(result[3].matched)
211 {//nodes command
212 return handle_nodes_command();
213 }else if(result[4].matched)
214 {//config command
215 if(result[9].matched)
216 return handle_config_command(result[9]);
217 else
218 {
219 send_hook("Unknown service\n");
220 }
221 }else if(result[5].matched)
222 {//fetch command
223 if(result[9].matched)
224 return handle_fetch_command(result[9]);
225 else
226 {
227 send_hook("Unknown service\n");
228 }
229 }else if(result[6].matched)
230 {//version command
231 return handle_version_command();
232 }else if(result[7].matched)
233 {//quit command
234 return handle_quit_command();
235 }
236 else
237 return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
238 }
239
240 return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");;
241 }
242
243 bool handle_list_command()
244 {
245 std::string buff_to_send;
246 for(std::list<munin_service>::const_iterator it = m_config.m_services.begin(); it!=m_config.m_services.end();it++)
247 {
248 buff_to_send += it->m_service_name + " ";
249 }
250 buff_to_send+='\n';
251 return send_hook(buff_to_send);
252 }
253 bool handle_nodes_command()
254 {
255 //supports only one node - host name
256 send_hook(m_host_name + "\n.\n");
257 return true;
258 }
259 bool handle_config_command(const std::string& service_name)
260 {
261 munin_service* psrv = get_service_by_name(service_name);
262 if(!psrv)
263 return send_hook(std::string() + "Unknown service\n");
264
265
266 return send_hook(psrv->m_service_config_string + ".\n");
267 }
268
269 bool handle_fetch_command(const std::string& service_name)
270 {
271 munin_service* psrv = get_service_by_name(service_name);
272 if(!psrv)
273 return send_hook(std::string() + "Unknown service\n");
274
275 std::string buff;
276 psrv->m_pdata_provider->update_service_data(psrv, buff);
277
278 buff += ".\n";
279 return send_hook(buff);
280 }
281 bool handle_version_command()
282 {
283 return send_hook("Munin node component by Andrey Sabelnikov\n");
284 }
285 bool handle_quit_command()
286 {
287 return false;
288 }
289
290 bool send_hook(const std::string& buff)
291 {
292 LOG_PRINT("munin_send: \n" << buff, LOG_LEVEL_3);
293
294 if(m_psnd_hndlr)
295 return m_psnd_hndlr->do_send(buff.data(), buff.size());
296 else
297 return false;
298 }
299
300
301 munin_service* get_service_by_name(const std::string& srv_name)
302 {
303 std::list<munin_service>::iterator it = m_config.m_services.begin();
304 for(; it!=m_config.m_services.end(); it++)
305 if(it->m_service_name == srv_name)
306 break;
307
308 if(it==m_config.m_services.end())
309 return NULL;
310
311 return &(*it);
312 }
313
314 enum machine_state{
315 http_state_retriving_comand_line,
316 http_state_error
317 };
318
319
320 config_type& m_config;
321 machine_state m_machine_state;
322 std::string m_cache;
323 std::string m_host_name;
324 protected:
326 };
327
328
329 inline bool test_self()
330 {
331 /*WSADATA w;
332 ::WSAStartup(MAKEWORD(1, 1), &w);
333 node_server_config sc;
334 sc.m_services.push_back(munin_service());
335 sc.m_services.back().m_service_name = "test_service";
336
337 sc.m_services.back().m_service_config_string =
338 "graph_args --base 1000 -l 0 --vertical-label N --upper-limit 329342976\n"
339 "graph_title REPORTS STATICTICS\n"
340 "graph_category bind\n"
341 "graph_info This graph shows how many reports came in fixed time period.\n"
342 "graph_order apps free swap\n"
343 "apps.label apps\n"
344 "apps.draw AREA\n"
345 "apps.info Memory used by user-space applications.\n"
346 "swap.label swap\n"
347 "swap.draw STACK\n"
348 "swap.info Swap space used.\n"
349 "free.label unused\n"
350 "free.draw STACK\n"
351 "free.info Wasted memory. Memory that is not used for anything at all.\n"
352 "committed.label committed\n"
353 "committed.draw LINE2\n"
354 "committed.warn 625410048\n"
355 "committed.info The amount of memory that would be used if all the memory that's been allocated were to be used.\n";
356
357
358 sc.m_services.push_back(munin_service());
359 sc.m_services.back().m_service_name = "test_service1";
360 fake_send_handler fh;
361 munin_node_server_connection_handler mh(&fh, sc);
362
363 std::string buff = "list\n";
364 mh.handle_recv(buff.data(), buff.size());
365
366
367 buff = "nodes\n";
368 mh.handle_recv(buff.data(), buff.size());
369*/
370 return true;
371 }
372
373 }
374}
375}
376#endif
munin_node_server_connection_handler(i_service_endpoint *psnd_hndlr, config_type &config, const connection_context_base &context)
const char * res
#define LOG_ERROR(x)
Definition misc_log_ex.h:98
#define STATIC_REGEXP_EXPR_1(var_name, xpr_text, reg_exp_flags)
virtual bool do_send(const void *ptr, size_t cb)
virtual bool update_service_data(munin_service *pservice, std::string &paramters_text)=0
munin_service_data_provider * m_pdata_provider