From dab7a7e25d791b9f57ed89b7faf8f6b341c1d190 Mon Sep 17 00:00:00 2001 From: Sven Nierlein Date: Tue, 5 Nov 2019 12:11:24 +0100 Subject: [PATCH] WIP: add QH command to access the query handler via livestatus this PR adds access to the query handler via livestatus. Since livestatus is commonly used it would be nice to subscribe to events via livestatus too. So we simply pass through query handler commands and therefor allow things like: echo "QH help" | nc -U tmp/run/live or echo "QH @nerd subscribe servicechecks" | nc -U tmp/run/live TODO: - It is not yet interactive, so you send a command once and will get the results. - implement proper shutdown Signed-off-by: Sven Nierlein --- src/Store.cc | 33 ++++++++++++++++++++++++++++++++- src/Store.h | 3 ++- src/module.c | 2 +- src/store.cc | 4 ++-- src/store.h | 2 +- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/Store.cc b/src/Store.cc index 556efc9..2b43d24 100644 --- a/src/Store.cc +++ b/src/Store.cc @@ -113,7 +113,7 @@ void Store::registerDowntime(nebstruct_downtime_data *d) _table_downtimes.addDowntime(d); } -bool Store::answerRequest(InputBuffer *input, OutputBuffer *output) +bool Store::answerRequest(InputBuffer *input, OutputBuffer *output, int fd) { output->reset(); int r = input->readRequest(); @@ -135,6 +135,10 @@ bool Store::answerRequest(InputBuffer *input, OutputBuffer *output) answerCommandRequest(lstrip((char *)line + 8), output); output->setDoKeepalive(true); } + else if (!strncmp(line, "QH ", 3)) { + output->setDoKeepalive(true); + answerQueryHandlerRequest(lstrip((char *)line + 3), output, fd); + } else if (!strncmp(line, "LOGROTATE", 9)) { logger(LG_INFO, "Forcing logfile rotation"); rotate_log_file(time(0)); @@ -171,6 +175,33 @@ void Store::answerCommandRequest(const char *command, OutputBuffer *output) return; } +void Store::answerQueryHandlerRequest(const char *command, OutputBuffer *output, int fd) +{ + int ret, sd; + char buf[4096]; + sd = nsock_unix(qh_socket_path, NSOCK_TCP | NSOCK_CONNECT); + if (sd < 0) { + logger(LG_INFO, "Failed to connect to query socket '%s': %s: %s", qh_socket_path, nsock_strerror(sd), strerror(errno)); + return; + } + ret = nsock_printf_nul(sd, "%s", command); + if (ret < 0) { + logger(LG_INFO, "failed to submit command by query handler"); + } + output->reset(); + while(TRUE) { + ret = read(sd, buf, 4095); + if(ret <= 0) + break; + buf[ret] = 0; + dprintf(fd, "%s", buf); + } + close(sd); + return; +} + + + void Store::answerGetRequest(InputBuffer *input, OutputBuffer *output, const char *tablename) { diff --git a/src/Store.h b/src/Store.h index f489e0b..7669202 100644 --- a/src/Store.h +++ b/src/Store.h @@ -69,12 +69,13 @@ class Store void registerHostgroup(hostgroup *); void registerComment(nebstruct_comment_data *); void registerDowntime(nebstruct_downtime_data *); - bool answerRequest(InputBuffer *, OutputBuffer *); + bool answerRequest(InputBuffer *, OutputBuffer *, int); private: Table *findTable(string name); void answerGetRequest(InputBuffer *, OutputBuffer *, const char *); void answerCommandRequest(const char *, OutputBuffer *); + void answerQueryHandlerRequest(const char *, OutputBuffer *, int); }; #endif // Store_h diff --git a/src/module.c b/src/module.c index ccb8e3f..b344617 100644 --- a/src/module.c +++ b/src/module.c @@ -192,7 +192,7 @@ void *client_thread(void *data) while (keepalive && !g_should_terminate) { if (g_debug_level >= 2 && requestnr > 1) logger(LG_INFO, "Handling request %d on same connection", requestnr); - keepalive = store_answer_request(input_buffer, output_buffer); + keepalive = store_answer_request(input_buffer, output_buffer, cc); flush_output_buffer(output_buffer, cc); g_counters[COUNTER_REQUESTS]++; requestnr ++; diff --git a/src/store.cc b/src/store.cc index fc6814b..c636f7e 100644 --- a/src/store.cc +++ b/src/store.cc @@ -75,9 +75,9 @@ void store_register_downtime(nebstruct_downtime_data *d) g_store->registerDowntime(d); } -int store_answer_request(void *ib, void *ob) +int store_answer_request(void *ib, void *ob, int fd) { - return g_store->answerRequest((InputBuffer *)ib, (OutputBuffer *)ob); + return g_store->answerRequest((InputBuffer *)ib, (OutputBuffer *)ob, fd); } void *create_outputbuffer(int *termination_flag) diff --git a/src/store.h b/src/store.h index 2abe060..3a10ddb 100644 --- a/src/store.h +++ b/src/store.h @@ -36,7 +36,7 @@ extern "C" void store_deinit(); void store_register_comment(nebstruct_comment_data *); void store_register_downtime(nebstruct_downtime_data *); - int store_answer_request(void *input_buffer, void *output_buffer); + int store_answer_request(void *input_buffer, void *output_buffer, int fd); void *create_outputbuffer(int *termination_flag); void flush_output_buffer(void *ob, int fd); void delete_outputbuffer(void *);