~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/logging_query/logging_query.cc

  • Committer: Toru Maesaka
  • Date: 2008-12-17 07:16:37 UTC
  • mto: (685.1.40 devel) (713.1.5 devel)
  • mto: This revision was merged to the branch mainline in revision 713.
  • Revision ID: dev@torum.net-20081217071637-7j9040w7lpms77r2
Removed my_time() and added error checking

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>
 
24
#include <drizzled/gettext.h>
 
25
#include <drizzled/session.h>
7
26
 
 
27
/* todo, make this dynamic as needed */
8
28
#define MAX_MSG_LEN (32*1024)
9
29
 
10
30
static char* logging_query_filename= NULL;
 
31
static bool logging_query_enable= true;
 
32
static ulong logging_query_enable_time= 0;
 
33
static ulong logging_query_threshold_big_resultset= 0;
11
34
 
12
35
static int fd= -1;
13
36
 
14
37
// copied from drizzled/sql_parse.cc
15
 
 
16
38
const LEX_STRING command_name[]={
17
39
  { C_STRING_WITH_LEN("Sleep") },
18
40
  { C_STRING_WITH_LEN("Quit") },
38
60
};
39
61
 
40
62
 
41
 
bool logging_query_func_pre (THD *thd)
 
63
/* stolen from mysys/my_getsystime
 
64
   until the Session has a good utime "now" we can use
 
65
   will have to use this instead */
 
66
 
 
67
#include <sys/time.h>
 
68
static uint64_t get_microtime()
42
69
{
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,
 
70
#if defined(HAVE_GETHRTIME)
 
71
  return gethrtime()/1000;
 
72
#else
 
73
  uint64_t newtime;
 
74
  struct timeval t;
 
75
  /*
 
76
    The following loop is here because gettimeofday may fail on some systems
63
77
  */
64
 
  wrv= write(fd, msgbuf, msgbuf_len);
65
 
  assert(wrv == msgbuf_len);
 
78
  while (gettimeofday(&t, NULL) != 0) {}
 
79
  newtime= (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
 
80
  return newtime;
 
81
#endif  /* defined(HAVE_GETHRTIME) */
 
82
}
66
83
 
 
84
/* we could just not have a pre entrypoint at all,
 
85
   and have logging_pre == NULL
 
86
   but we have this here for the sake of being an example */
 
87
bool logging_query_func_pre (Session *session __attribute__((unused)))
 
88
{
67
89
  return false;
68
90
}
69
91
 
70
 
bool logging_query_func_post (THD *thd)
 
92
bool logging_query_func_post (Session *session)
71
93
{
72
94
  char msgbuf[MAX_MSG_LEN];
73
95
  int msgbuf_len= 0;
75
97
 
76
98
  if (fd < 0) return false;
77
99
 
78
 
  assert(thd != NULL);
 
100
  assert(session != NULL);
 
101
 
 
102
  /*
 
103
    here is some time stuff from class Session
 
104
      uint64_t connect_utime;
 
105
        todo, looks like this isnt being set
 
106
        we could store the time this plugin was loaded
 
107
        but that would just be a dumb workaround
 
108
      uint64_t start_utime;
 
109
      uint64_t utime_after_lock;
 
110
      uint64_t current_utime();
 
111
        todo, cant get to because of namemangling
 
112
  */
 
113
 
 
114
  /* todo, the Session should have a "utime command completed" inside
 
115
     itself, so be more accurate, and so plugins dont have to keep
 
116
     calling current_utime, which can be slow */
 
117
  uint64_t t_mark= get_microtime();
79
118
 
80
119
  msgbuf_len=
81
120
    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);
 
121
             "thread_id=%ld query_id=%ld"
 
122
             " t_connect=%lld t_start=%lld t_lock=%lld"
 
123
             " command=%.*s"
 
124
             " rows_sent=%ld rows_examined=%u\n"
 
125
             " db=\"%.*s\" query=\"%.*s\"\n",
 
126
             (unsigned long) session->thread_id,
 
127
             (unsigned long) session->query_id,
 
128
             (unsigned long long)(t_mark - session->connect_utime),
 
129
             (unsigned long long)(t_mark - session->start_utime),
 
130
             (unsigned long long)(t_mark - session->utime_after_lock),
 
131
             (uint32_t)command_name[session->command].length,
 
132
             command_name[session->command].str,
 
133
             (unsigned long) session->sent_row_count,
 
134
             (uint32_t) session->examined_row_count,
 
135
             session->db_length, session->db,
 
136
             session->query_length, session->query);
89
137
  /* a single write has a OS level thread lock
90
138
     so there is no need to have mutexes guarding this write,
91
139
  */
92
140
  wrv= write(fd, msgbuf, msgbuf_len);
93
141
  assert(wrv == msgbuf_len);
94
142
 
95
 
 
96
143
  return false;
97
144
}
98
145
 
103
150
  if (logging_query_filename == NULL)
104
151
  {
105
152
    /* no destination filename was specified via system variables
106
 
       return now, dont set the callback pointers 
 
153
       return now, dont set the callback pointers
107
154
    */
108
155
    return 0;
109
156
  }
110
157
 
111
 
  fd= open(logging_query_filename, O_WRONLY | O_APPEND | O_CREAT);
112
 
  if (fd < 0) 
 
158
  fd= open(logging_query_filename, O_WRONLY | O_APPEND | O_CREAT,
 
159
           S_IRUSR|S_IWUSR);
 
160
  if (fd < 0)
113
161
  {
114
 
    fprintf(stderr, "fail open fn=%s er=%s\n",
115
 
            logging_query_filename,
116
 
            strerror(errno));
 
162
    sql_print_error(_("fail open() fn=%s er=%s\n"),
 
163
                    logging_query_filename,
 
164
                    strerror(errno));
117
165
 
118
 
    /* we should return an error here, so the plugin doesnt load
 
166
    /* todo
 
167
       we should return an error here, so the plugin doesnt load
119
168
       but this causes Drizzle to crash
120
169
       so until that is fixed,
121
170
       just return a success,
134
183
{
135
184
  logging_st *l= (logging_st *) p;
136
185
 
137
 
  if (fd >= 0) 
 
186
  if (fd >= 0)
138
187
  {
139
188
    close(fd);
140
189
    fd= -1;
146
195
  return 0;
147
196
}
148
197
 
149
 
static DRIZZLE_SYSVAR_STR(filename, logging_query_filename,
 
198
static DRIZZLE_SYSVAR_STR(
 
199
  filename,
 
200
  logging_query_filename,
150
201
  PLUGIN_VAR_READONLY,
151
 
  "File to log queries to.",
152
 
  NULL, NULL, NULL);
 
202
  N_("File to log to"),
 
203
  NULL, /* check func */
 
204
  NULL, /* update func*/
 
205
  NULL /* default */);
 
206
 
 
207
static DRIZZLE_SYSVAR_BOOL(
 
208
  enable,
 
209
  logging_query_enable,
 
210
  PLUGIN_VAR_NOCMDARG,
 
211
  N_("Enable logging"),
 
212
  NULL, /* check func */
 
213
  NULL, /* update func */
 
214
  true /* default */);
 
215
 
 
216
static DRIZZLE_SYSVAR_ULONG(
 
217
  enable_time,
 
218
  logging_query_enable_time,
 
219
  PLUGIN_VAR_OPCMDARG,
 
220
  N_("Disable after this many seconds. Zero for forever"),
 
221
  NULL, /* check func */
 
222
  NULL, /* update func */
 
223
  0, /* default */
 
224
  0, /* min */
 
225
  ULONG_MAX, /* max */
 
226
  0 /* blksiz */);
 
227
 
 
228
#ifdef NOT_YET
 
229
static DRIZZLE_SYSVAR_ULONG(
 
230
  threshhold_slow,
 
231
  logging_query_threshold_slow,
 
232
  PLUGIN_VAR_OPCMDARG,
 
233
  N_("Threshold for logging slow queries, in microseconds"),
 
234
  NULL, /* check func */
 
235
  NULL, /* update func */
 
236
  0, /* default */
 
237
  0, /* min */
 
238
  ULONG_MAX, /* max */
 
239
  0 /* blksiz */);
 
240
#endif
 
241
 
 
242
static DRIZZLE_SYSVAR_ULONG(
 
243
  threshold_big_resultset,
 
244
  logging_query_threshold_big_resultset,
 
245
  PLUGIN_VAR_OPCMDARG,
 
246
  N_("Threshold for logging big queries, for rows returned"),
 
247
  NULL, /* check func */
 
248
  NULL, /* update func */
 
249
  0, /* default */
 
250
  0, /* min */
 
251
  ULONG_MAX, /* max */
 
252
  0 /* blksiz */);
 
253
 
 
254
#ifdef NOT_YET
 
255
static DRIZZLE_SYSVAR_ULONG(
 
256
  threshhold_big_examined,
 
257
  logging_query_threshold_big_examined,
 
258
  PLUGIN_VAR_OPCMDARG,
 
259
  N_("Threshold for logging big queries, for rows examined"),
 
260
  NULL, /* check func */
 
261
  NULL, /* update func */
 
262
  0, /* default */
 
263
  0, /* min */
 
264
  ULONG_MAX, /* max */
 
265
  0 /* blksiz */);
 
266
#endif
153
267
 
154
268
static struct st_mysql_sys_var* logging_query_system_variables[]= {
155
269
  DRIZZLE_SYSVAR(filename),
 
270
  DRIZZLE_SYSVAR(enable),
 
271
  DRIZZLE_SYSVAR(enable_time),
 
272
  DRIZZLE_SYSVAR(threshold_big_resultset),
156
273
  NULL
157
274
};
158
275
 
162
279
  "logging_query",
163
280
  "0.1",
164
281
  "Mark Atwood <mark@fallenpegasus.com>",
165
 
  "Log queries",
 
282
  N_("Log queries to a file"),
166
283
  PLUGIN_LICENSE_GPL,
167
284
  logging_query_plugin_init,
168
285
  logging_query_plugin_deinit,