22 #include <boost/scoped_array.hpp>
24 #include <drizzled/plugin.h>
25 #include <drizzled/plugin/logging.h>
26 #include <drizzled/gettext.h>
27 #include <drizzled/session.h>
28 #include <drizzled/session/times.h>
29 #include <drizzled/sql_parse.h>
30 #include <drizzled/errmsg_print.h>
31 #include <boost/date_time.hpp>
32 #include <boost/program_options.hpp>
34 #include <libgearman/gearman.h>
36 #include <sys/types.h>
43 namespace drizzle_plugin {
45 namespace po= boost::program_options;
48 static const int MAX_MSG_LEN= 32*1024;
65 static unsigned char *quotify (
const unsigned char *src,
size_t srclen,
66 unsigned char *dst,
size_t dstlen)
68 static const char hexit[]= {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
69 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' };
76 for (dst_ndx= 0,src_ndx= 0; src_ndx < srclen; src_ndx++)
83 if ((dstlen - dst_ndx) < 5)
85 dst[dst_ndx]= (
unsigned char)0x00;
89 if (src[src_ndx] > 0x7f)
92 dst[dst_ndx++]= src[src_ndx];
94 else if (src[src_ndx] == 0x00)
96 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'0';
98 else if (src[src_ndx] == 0x07)
100 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'a';
102 else if (src[src_ndx] == 0x08)
104 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'b';
106 else if (src[src_ndx] == 0x09)
108 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
't';
110 else if (src[src_ndx] == 0x0a)
112 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'n';
114 else if (src[src_ndx] == 0x0b)
116 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'v';
118 else if (src[src_ndx] == 0x0c)
120 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'f';
122 else if (src[src_ndx] == 0x0d)
124 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'r';
126 else if (src[src_ndx] == 0x1b)
128 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (
unsigned char)
'e';
130 else if (src[src_ndx] == 0x22)
132 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x22;
134 else if (src[src_ndx] == 0x2C)
136 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x2C;
138 else if (src[src_ndx] == 0x5C)
140 dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= 0x5C;
142 else if ((src[src_ndx] < 0x20) || (src[src_ndx] == 0x7F))
144 dst[dst_ndx++]= 0x5C;
145 dst[dst_ndx++]= (
unsigned char)
'x';
146 dst[dst_ndx++]= hexit[(src[src_ndx] >> 4) & 0x0f];
147 dst[dst_ndx++]= hexit[src[src_ndx] & 0x0f];
151 dst[dst_ndx++]= src[src_ndx];
162 const std::string _host;
163 const std::string _function;
165 int _gearman_client_ok;
166 gearman_client_st _gearman_client;
174 const std::string &
function) :
178 _gearman_client_ok(0),
181 gearman_return_t ret;
184 if (gearman_client_create(&_gearman_client) == NULL)
186 drizzled::sql_perror(_(
"fail gearman_client_create()"));
192 ret= gearman_client_add_server(&_gearman_client,
194 if (ret != GEARMAN_SUCCESS)
196 drizzled::errmsg_printf(drizzled::error::ERROR, _(
"fail gearman_client_add_server(): %s"),
197 gearman_client_error(&_gearman_client));
201 _gearman_client_ok= 1;
207 if (_gearman_client_ok)
209 gearman_client_free(&_gearman_client);
215 boost::scoped_array<char> msgbuf(
new char[MAX_MSG_LEN]);
218 assert(session != NULL);
224 if (not _gearman_client_ok)
232 uint64_t t_mark= session->times.getCurrentTimestamp(
false);
236 unsigned char qs[255];
239 drizzled::util::string::ptr dbs(session->schema());
242 snprintf(msgbuf.get(), MAX_MSG_LEN,
243 "%"PRIu64
",%"PRIu64
",%"PRIu64
",\"%.*s\",\"%s\",\"%.*s\","
244 "%"PRIu64
",%"PRIu64
",%"PRIu64
",%"PRIu64
",%"PRIu64
","
245 "%"PRIu32
",%"PRIu32
",%"PRIu32
",\"%s\"",
250 (int)dbs->size(), dbs->c_str(),
252 quotify((
const unsigned char *)session->getQueryString()->c_str(), session->getQueryString()->length(), qs,
sizeof(qs)),
255 (int)drizzled::getCommandName(session->
command).size(),
256 drizzled::getCommandName(session->
command).c_str(),
258 (t_mark - session->times.getConnectMicroseconds()),
259 (session->times.getElapsedTime()),
260 (t_mark - session->times.utime_after_lock),
264 session->total_warn_count,
266 drizzled::getServerHostname().c_str()
269 char job_handle[GEARMAN_JOB_HANDLE_SIZE];
271 (void) gearman_client_do_background(&_gearman_client,
274 (
void *) msgbuf.get(),
289 vm[
"function"].as<std::string>());
290 context.add(handler);
300 po::value<std::string>()->default_value(
"localhost"),
301 _(
"Hostname for logging to a Gearman server"));
303 po::value<std::string>()->default_value(
"drizzlelog"),
304 _(
"Gearman Function to send logging to"));
309 DRIZZLE_DECLARE_PLUGIN
315 N_(
"Logs queries to a Gearman server"),
316 drizzled::PLUGIN_LICENSE_GPL,
317 drizzle_plugin::logging_gearman_plugin_init,
319 drizzle_plugin::init_options
321 DRIZZLE_DECLARE_PLUGIN_END;