22 #include <boost/scoped_array.hpp>
24 #include <drizzled/item.h>
25 #include <drizzled/plugin.h>
26 #include <drizzled/plugin/logging.h>
27 #include <drizzled/gettext.h>
28 #include <drizzled/session.h>
29 #include <drizzled/session/times.h>
30 #include <drizzled/sql_parse.h>
31 #include <drizzled/errmsg_print.h>
32 #include <boost/date_time.hpp>
33 #include <boost/program_options.hpp>
35 #include <libgearman/gearman.h>
37 #include <sys/types.h>
44 using namespace drizzled;
46 namespace drizzle_plugin {
47 namespace logging_gearman {
49 namespace po= boost::program_options;
54 static const int MAX_MSG_LEN= 32*1024;
71 static unsigned char *quotify (
const unsigned char *src,
size_t srclen,
72 unsigned char *dst,
size_t dstlen)
74 static const char hexit[]= {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
75 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' };
82 for (dst_ndx= 0,src_ndx= 0; src_ndx < srclen; src_ndx++)
89 if ((dstlen - dst_ndx) < 5)
91 dst[dst_ndx]= (
unsigned char)0x00;
95 if (src[src_ndx] > 0x7f)
98 dst[dst_ndx++]= src[src_ndx];
100 else if (src[src_ndx] == 0x00)
102 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'0';
104 else if (src[src_ndx] == 0x07)
106 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'a';
108 else if (src[src_ndx] == 0x08)
110 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'b';
112 else if (src[src_ndx] == 0x09)
114 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
't';
116 else if (src[src_ndx] == 0x0a)
118 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'n';
120 else if (src[src_ndx] == 0x0b)
122 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'v';
124 else if (src[src_ndx] == 0x0c)
126 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'f';
128 else if (src[src_ndx] == 0x0d)
130 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'r';
132 else if (src[src_ndx] == 0x1b)
134 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'e';
136 else if (src[src_ndx] == 0x22)
138 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x22;
140 else if (src[src_ndx] == 0x2C)
142 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x2C;
144 else if (src[src_ndx] == 0x5C)
146 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x5C;
148 else if ((src[src_ndx] < 0x20) || (src[src_ndx] == 0x7F))
150 dst[dst_ndx++]= 0x5C;
151 dst[dst_ndx++]= (
unsigned char)
'x';
152 dst[dst_ndx++]= hexit[(src[src_ndx] >> 4) & 0x0f];
153 dst[dst_ndx++]= hexit[src[src_ndx] & 0x0f];
157 dst[dst_ndx++]= src[src_ndx];
168 std::string sysvar_host;
169 std::string sysvar_function;
171 int _gearman_client_ok;
172 gearman_client_st _gearman_client;
180 const std::string &
function) :
183 sysvar_function(
function),
184 _gearman_client_ok(0),
187 gearman_return_t ret;
190 if (gearman_client_create(&_gearman_client) == NULL)
192 drizzled::sql_perror(_(
"fail gearman_client_create()"));
198 ret= gearman_client_add_server(&_gearman_client,
200 if (ret != GEARMAN_SUCCESS)
202 drizzled::errmsg_printf(drizzled::error::ERROR, _(
"fail gearman_client_add_server(): %s"),
203 gearman_client_error(&_gearman_client));
207 _gearman_client_ok= 1;
213 if (_gearman_client_ok)
215 gearman_client_free(&_gearman_client);
221 boost::scoped_array<char> msgbuf(
new char[MAX_MSG_LEN]);
224 assert(session != NULL);
230 if (not _gearman_client_ok)
238 uint64_t t_mark= session->times.getCurrentTimestamp(
false);
242 unsigned char qs[255];
245 drizzled::util::string::ptr dbs(session->schema());
248 snprintf(msgbuf.get(), MAX_MSG_LEN,
249 "%"PRIu64
",%"PRIu64
",%"PRIu64
",\"%.*s\",\"%s\",\"%.*s\","
250 "%"PRIu64
",%"PRIu64
",%"PRIu64
",%"PRIu64
",%"PRIu64
","
251 "%"PRIu32
",%"PRIu32
",%"PRIu32
",\"%s\"",
256 (int)dbs->size(), dbs->c_str(),
258 quotify((
const unsigned char *)session->getQueryString()->c_str(), session->getQueryString()->length(), qs,
sizeof(qs)),
261 (int)drizzled::getCommandName(session->
command).size(),
262 drizzled::getCommandName(session->
command).c_str(),
264 (t_mark - session->times.getConnectMicroseconds()),
265 (session->times.getElapsedTime()),
266 (t_mark - session->times.utime_after_lock),
270 session->total_warn_count,
272 drizzled::getServerHostname().c_str()
275 char job_handle[GEARMAN_JOB_HANDLE_SIZE];
277 (void) gearman_client_do_background(&_gearman_client,
278 sysvar_function.c_str(),
280 (
void *) msgbuf.get(),
294 gearman_return_t tmp_ret;
304 tmp_ret= gearman_client_add_server(&_gearman_client,
305 new_host.c_str(), 0);
306 if (tmp_ret != GEARMAN_SUCCESS)
308 drizzled::errmsg_printf(drizzled::error::ERROR, _(
"fail gearman_client_add_server(): %s"),
309 gearman_client_error(&_gearman_client));
313 gearman_client_remove_servers(&_gearman_client);
314 gearman_client_add_server(&_gearman_client, new_host.c_str(), 0);
315 sysvar_host= new_host;
326 sysvar_function= new_function;
347 return sysvar_function;
351 static LoggingGearman *handler= NULL;
362 std::string newHost(var->value->
str_value.data());
368 errmsg_printf(error::ERROR, _(
"logging_gearman_host cannot be NULL"));
381 std::string newFunction(var->value->
str_value.data());
387 errmsg_printf(error::ERROR, _(
"logging_gearman_function cannot be NULL"));
396 handler=
new LoggingGearman(vm[
"host"].as<std::string>(),
397 vm[
"function"].as<std::string>());
398 context.add(handler);
408 po::value<std::string>()->default_value(
"localhost"),
409 _(
"Hostname for logging to a Gearman server"));
411 po::value<std::string>()->default_value(
"drizzlelog"),
412 _(
"Gearman Function to send logging to"));
418 DRIZZLE_DECLARE_PLUGIN
424 N_(
"Logs queries to a Gearman server"),
425 drizzled::PLUGIN_LICENSE_GPL,
426 drizzle_plugin::logging_gearman::init,
428 drizzle_plugin::logging_gearman::init_options
430 DRIZZLE_DECLARE_PLUGIN_END;
ha_rows examined_row_count
An Proxy Wrapper around boost::program_options::variables_map.
bool setHost(std::string &new_host)
query_id_t getQueryId() const
enum_server_command command
uint32_t getServerId() const
bool setFunction(std::string &new_function)
std::string & getFunction()