~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/logging_query/logging_query.cc

  • Committer: Monty Taylor
  • Date: 2008-10-22 21:31:15 UTC
  • Revision ID: monty@inaugust.com-20081022213115-xuxc80r939tl88p1
Renamed drizzle_common again. Removed sql_common. (empty) 
Now all we need to do is merge/disect base.h, common.h, common_includes.h, server_includes.h and globa.h (good grief)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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:
 
3
 *
 
4
 *  Copyright (C) 2008 Mark Atwood
 
5
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 */
2
19
 
3
 
/* need to define DRIZZLE_SERVER to get inside the THD */
 
20
/* need to define DRIZZLE_SERVER to get inside the Session */
4
21
#define DRIZZLE_SERVER 1
5
22
#include <drizzled/server_includes.h>
6
23
#include <drizzled/plugin_logging.h>
7
24
 
 
25
/* todo, make this dynamic as needed */
8
26
#define MAX_MSG_LEN (32*1024)
9
27
 
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;
11
32
 
12
33
static int fd= -1;
13
34
 
14
35
// copied from drizzled/sql_parse.cc
15
 
 
16
36
const LEX_STRING command_name[]={
17
37
  { C_STRING_WITH_LEN("Sleep") },
18
38
  { C_STRING_WITH_LEN("Quit") },
38
58
};
39
59
 
40
60
 
41
 
bool logging_query_func_pre (THD *thd)
 
61
/* stolen from mysys/my_getsystime 
 
62
   until the Session has a good utime "now" we can use
 
63
   will have to use this instead */
 
64
 
 
65
#include <sys/time.h>
 
66
static uint64_t get_microtime()
42
67
{
43
 
  char msgbuf[MAX_MSG_LEN];
44
 
  int msgbuf_len= 0;
45
 
  int wrv;
46
 
 
47
 
  if (fd < 0) 
48
 
    return false;
49
 
 
50
 
  assert(thd != NULL);
51
 
 
52
 
  msgbuf_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;
 
70
#else
 
71
  uint64_t newtime;
 
72
  struct timeval t;
 
73
  /*
 
74
    The following loop is here because gettimeofday may fail on some systems
63
75
  */
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;
 
78
  return newtime;
 
79
#endif  /* defined(HAVE_GETHRTIME) */
 
80
}
66
81
 
 
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 (Session *session __attribute__((unused)))
 
86
{
67
87
  return false;
68
88
}
69
89
 
70
 
bool logging_query_func_post (THD *thd)
 
90
bool logging_query_func_post (Session *session)
71
91
{
72
92
  char msgbuf[MAX_MSG_LEN];
73
93
  int msgbuf_len= 0;
75
95
 
76
96
  if (fd < 0) return false;
77
97
 
78
 
  assert(thd != NULL);
 
98
  assert(session != NULL);
 
99
 
 
100
  /*
 
101
    here is some time stuff from class Session
 
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
 
110
  */
 
111
 
 
112
  /* todo, the Session 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();
79
116
 
80
117
  msgbuf_len=
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",
84
 
             (unsigned long) thd->thread_id, 
85
 
             (unsigned long) thd->query_id,
86
 
             (uint32_t)command_name[thd->command].length, command_name[thd->command].str,
87
 
             (unsigned long) thd->sent_row_count,
88
 
             (uint32_t) thd->examined_row_count);
 
119
             _("thread_id=%ld query_id=%ld"
 
120
               " t_connect=%lld t_start=%lld t_lock=%lld"
 
121
               " command=%.*s"
 
122
               " rows_sent=%ld rows_examined=%u\n"
 
123
               " db=\"%.*s\" query=\"%.*s\"\n"),
 
124
             (unsigned long) session->thread_id, 
 
125
             (unsigned long) session->query_id,
 
126
             (unsigned long long)(t_mark - session->connect_utime),
 
127
             (unsigned long long)(t_mark - session->start_utime),
 
128
             (unsigned long long)(t_mark - session->utime_after_lock),
 
129
             (uint32_t)command_name[session->command].length,
 
130
             command_name[session->command].str,
 
131
             (unsigned long) session->sent_row_count,
 
132
             (uint32_t) session->examined_row_count,
 
133
             session->db_length, session->db,
 
134
             session->query_length, session->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,
91
137
  */
92
138
  wrv= write(fd, msgbuf, msgbuf_len);
93
139
  assert(wrv == msgbuf_len);
94
140
 
95
 
 
96
141
  return false;
97
142
}
98
143
 
108
153
    return 0;
109
154
  }
110
155
 
111
 
  fd= open(logging_query_filename, O_WRONLY | O_APPEND | O_CREAT);
 
156
  fd= open(logging_query_filename, O_WRONLY | O_APPEND | O_CREAT,
 
157
           S_IRUSR|S_IWUSR);
112
158
  if (fd < 0) 
113
159
  {
114
 
    fprintf(stderr, "fail open fn=%s er=%s\n",
115
 
            logging_query_filename,
116
 
            strerror(errno));
 
160
    sql_print_error(_("fail open() fn=%s er=%s\n"),
 
161
                    logging_query_filename,
 
162
                    strerror(errno));
117
163
 
118
 
    /* we should return an error here, so the plugin doesnt load
 
164
    /* todo
 
165
       we should return an error here, so the plugin doesnt load
119
166
       but this causes Drizzle to crash
120
167
       so until that is fixed,
121
168
       just return a success,
146
193
  return 0;
147
194
}
148
195
 
149
 
static DRIZZLE_SYSVAR_STR(filename, logging_query_filename,
 
196
static DRIZZLE_SYSVAR_STR(
 
197
  filename,
 
198
  logging_query_filename,
150
199
  PLUGIN_VAR_READONLY,
151
 
  "File to log queries to.",
152
 
  NULL, NULL, NULL);
 
200
  N_("File to log to"),
 
201
  NULL, /* check func */
 
202
  NULL, /* update func*/
 
203
  NULL /* default */);
 
204
 
 
205
static DRIZZLE_SYSVAR_BOOL(
 
206
  enable,
 
207
  logging_query_enable,
 
208
  PLUGIN_VAR_NOCMDARG,
 
209
  N_("Enable logging"),
 
210
  NULL, /* check func */
 
211
  NULL, /* update func */
 
212
  true /* default */);
 
213
 
 
214
static DRIZZLE_SYSVAR_ULONG(
 
215
  enable_time,
 
216
  logging_query_enable_time,
 
217
  PLUGIN_VAR_OPCMDARG,
 
218
  N_("Disable after this many seconds. Zero for forever"),
 
219
  NULL, /* check func */
 
220
  NULL, /* update func */
 
221
  0, /* default */
 
222
  0, /* min */
 
223
  ULONG_MAX, /* max */
 
224
  0 /* blksiz */);
 
225
 
 
226
#ifdef NOT_YET
 
227
static DRIZZLE_SYSVAR_ULONG(
 
228
  threshhold_slow,
 
229
  logging_query_threshold_slow,
 
230
  PLUGIN_VAR_OPCMDARG,
 
231
  N_("Threshold for logging slow queries, in microseconds"),
 
232
  NULL, /* check func */
 
233
  NULL, /* update func */
 
234
  0, /* default */
 
235
  0, /* min */
 
236
  ULONG_MAX, /* max */
 
237
  0 /* blksiz */);
 
238
#endif
 
239
 
 
240
static DRIZZLE_SYSVAR_ULONG(
 
241
  threshold_big_resultset,
 
242
  logging_query_threshold_big_resultset,
 
243
  PLUGIN_VAR_OPCMDARG,
 
244
  N_("Threshold for logging big queries, for rows returned"),
 
245
  NULL, /* check func */
 
246
  NULL, /* update func */
 
247
  0, /* default */
 
248
  0, /* min */
 
249
  ULONG_MAX, /* max */
 
250
  0 /* blksiz */);
 
251
 
 
252
#ifdef NOT_YET
 
253
static DRIZZLE_SYSVAR_ULONG(
 
254
  threshhold_big_examined,
 
255
  logging_query_threshold_big_examined,
 
256
  PLUGIN_VAR_OPCMDARG,
 
257
  N_("Threshold for logging big queries, for rows examined"),
 
258
  NULL, /* check func */
 
259
  NULL, /* update func */
 
260
  0, /* default */
 
261
  0, /* min */
 
262
  ULONG_MAX, /* max */
 
263
  0 /* blksiz */);
 
264
#endif
153
265
 
154
266
static struct st_mysql_sys_var* logging_query_system_variables[]= {
155
267
  DRIZZLE_SYSVAR(filename),
 
268
  DRIZZLE_SYSVAR(enable),
 
269
  DRIZZLE_SYSVAR(enable_time),
 
270
  DRIZZLE_SYSVAR(threshold_big_resultset),
156
271
  NULL
157
272
};
158
273
 
162
277
  "logging_query",
163
278
  "0.1",
164
279
  "Mark Atwood <mark@fallenpegasus.com>",
165
 
  "Log queries",
 
280
  N_("Log queries to a file"),
166
281
  PLUGIN_LICENSE_GPL,
167
282
  logging_query_plugin_init,
168
283
  logging_query_plugin_deinit,