1
/* drizzle/plugin/logging_query/logging_query.cc */
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Mark Atwood
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3
20
/* need to define DRIZZLE_SERVER to get inside the THD */
4
21
#define DRIZZLE_SERVER 1
5
22
#include <drizzled/server_includes.h>
6
23
#include <drizzled/plugin_logging.h>
25
/* todo, make this dynamic as needed */
8
26
#define MAX_MSG_LEN (32*1024)
10
28
static char* logging_query_filename= NULL;
29
static bool logging_query_enable= true;
30
static ulong logging_query_enable_time= 0;
31
static ulong logging_query_threshold_big_resultset= 0;
14
35
// copied from drizzled/sql_parse.cc
16
36
const LEX_STRING command_name[]={
17
37
{ C_STRING_WITH_LEN("Sleep") },
18
38
{ C_STRING_WITH_LEN("Quit") },
41
bool logging_query_func_pre (THD *thd)
61
/* stolen from mysys/my_getsystime
62
until the THD has a good utime "now" we can use
63
will have to use this instead */
66
static uint64_t get_microtime()
43
char msgbuf[MAX_MSG_LEN];
53
snprintf(msgbuf, MAX_MSG_LEN,
54
"log bgn thread_id=%ld query_id=%ld command=%.*s"
55
" db=\"%.*s\" query=\"%.*s\"\n",
56
(unsigned long) thd->thread_id,
57
(unsigned long) thd->query_id,
58
(uint32_t)command_name[thd->command].length, command_name[thd->command].str,
59
thd->db_length, thd->db,
60
thd->query_length, thd->query);
61
/* a single write has a OS level thread lock
62
so there is no need to have mutexes guarding this write,
68
#if defined(HAVE_GETHRTIME)
69
return gethrtime()/1000;
74
The following loop is here because gettimeofday may fail on some systems
64
wrv= write(fd, msgbuf, msgbuf_len);
65
assert(wrv == msgbuf_len);
76
while (gettimeofday(&t, NULL) != 0) {}
77
newtime= (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
79
#endif /* defined(HAVE_GETHRTIME) */
82
/* we could just not have a pre entrypoint at all,
83
and have logging_pre == NULL
84
but we have this here for the sake of being an example */
85
bool logging_query_func_pre (THD *thd __attribute__((unused)))
78
98
assert(thd != NULL);
101
here is some time stuff from class THD
102
uint64_t connect_utime;
103
todo, looks like this isnt being set
104
we could store the time this plugin was loaded
105
but that would just be a dumb workaround
106
uint64_t start_utime;
107
uint64_t utime_after_lock;
108
uint64_t current_utime();
109
todo, cant get to because of namemangling
112
/* todo, the THD should have a "utime command completed" inside
113
itself, so be more accurate, and so plugins dont have to keep
114
calling current_utime, which can be slow */
115
uint64_t t_mark= get_microtime();
81
118
snprintf(msgbuf, MAX_MSG_LEN,
82
"log end thread_id=%ld query_id=%ld command=%.*s"
83
" rows.sent=%ld rows.exam=%u\n",
119
_("thread_id=%ld query_id=%ld"
120
" t_connect=%lld t_start=%lld t_lock=%lld"
122
" rows_sent=%ld rows_examined=%u\n"
123
" db=\"%.*s\" query=\"%.*s\"\n"),
84
124
(unsigned long) thd->thread_id,
85
125
(unsigned long) thd->query_id,
86
(uint32_t)command_name[thd->command].length, command_name[thd->command].str,
126
(unsigned long long)(t_mark - thd->connect_utime),
127
(unsigned long long)(t_mark - thd->start_utime),
128
(unsigned long long)(t_mark - thd->utime_after_lock),
129
(uint32_t)command_name[thd->command].length,
130
command_name[thd->command].str,
87
131
(unsigned long) thd->sent_row_count,
88
(uint32_t) thd->examined_row_count);
132
(uint32_t) thd->examined_row_count,
133
thd->db_length, thd->db,
134
thd->query_length, thd->query);
89
135
/* a single write has a OS level thread lock
90
136
so there is no need to have mutexes guarding this write,
92
138
wrv= write(fd, msgbuf, msgbuf_len);
93
139
assert(wrv == msgbuf_len);
112
157
S_IRUSR|S_IWUSR);
115
fprintf(stderr, "fail open fn=%s er=%s\n",
116
logging_query_filename,
160
sql_print_error(_("fail open() fn=%s er=%s\n"),
161
logging_query_filename,
119
/* we should return an error here, so the plugin doesnt load
165
we should return an error here, so the plugin doesnt load
120
166
but this causes Drizzle to crash
121
167
so until that is fixed,
122
168
just return a success,
150
static DRIZZLE_SYSVAR_STR(filename, logging_query_filename,
196
static DRIZZLE_SYSVAR_STR(
198
logging_query_filename,
151
199
PLUGIN_VAR_READONLY,
152
"File to log queries to.",
200
N_("File to log to"),
201
NULL, /* check func */
202
NULL, /* update func*/
205
static DRIZZLE_SYSVAR_BOOL(
207
logging_query_enable,
209
N_("Enable logging"),
210
NULL, /* check func */
211
NULL, /* update func */
214
static DRIZZLE_SYSVAR_ULONG(
216
logging_query_enable_time,
218
N_("Disable after this many seconds. Zero for forever"),
219
NULL, /* check func */
220
NULL, /* update func */
227
static DRIZZLE_SYSVAR_ULONG(
229
logging_query_threshold_slow,
231
N_("Threshold for logging slow queries, in microseconds"),
232
NULL, /* check func */
233
NULL, /* update func */
240
static DRIZZLE_SYSVAR_ULONG(
241
threshold_big_resultset,
242
logging_query_threshold_big_resultset,
244
N_("Threshold for logging big queries, for rows returned"),
245
NULL, /* check func */
246
NULL, /* update func */
253
static DRIZZLE_SYSVAR_ULONG(
254
threshhold_big_examined,
255
logging_query_threshold_big_examined,
257
N_("Threshold for logging big queries, for rows examined"),
258
NULL, /* check func */
259
NULL, /* update func */
155
266
static struct st_mysql_sys_var* logging_query_system_variables[]= {
156
267
DRIZZLE_SYSVAR(filename),
268
DRIZZLE_SYSVAR(enable),
269
DRIZZLE_SYSVAR(enable_time),
270
DRIZZLE_SYSVAR(threshold_big_resultset),