~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/logging_query/logging_query.cc

  • Committer: Mark Atwood
  • Date: 2009-01-29 19:22:23 UTC
  • mto: (779.5.1 devel)
  • mto: This revision was merged to the branch mainline in revision 823.
  • Revision ID: me@mark.atwood.name-20090129192223-fg0zixkjr9f081e8
logging to syslog

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <drizzled/gettext.h>
23
23
#include <drizzled/session.h>
24
24
 
25
 
/* todo, make this dynamic as needed */
 
25
/* TODO make this dynamic as needed */
26
26
#define MAX_MSG_LEN (32*1024)
27
27
 
28
 
static char* logging_query_filename= NULL;
29
 
static bool logging_query_enable= true;
30
 
static ulong logging_query_threshold_slow= 0;
31
 
static ulong logging_query_threshold_big_resultset= 0;
32
 
static ulong logging_query_threshold_big_examined= 0;
 
28
static bool sysvar_logging_query_enable= false;
 
29
static char* sysvar_logging_query_filename= NULL;
 
30
static ulong sysvar_logging_query_threshold_slow= 0;
 
31
static ulong sysvar_logging_query_threshold_big_resultset= 0;
 
32
static ulong sysvar_logging_query_threshold_big_examined= 0;
33
33
 
34
34
static int fd= -1;
35
35
 
59
59
   and all the ASCII unprintable characters
60
60
   as long as we pass the high-bit bytes unchanged
61
61
   this is safe to do to a UTF8 string
62
 
   we have to be careful about overrunning the targetbuffer
63
 
   or else a very long query can overwrite memory
 
62
   we dont allow overrunning the targetbuffer
 
63
   to avoid having a very long query overwrite memory
64
64
 
65
65
   TODO consider remapping the unprintables instead to "Printable
66
66
   Representation", the Unicode characters from the area U+2400 to
75
75
{
76
76
  static char hexit[]= { '0', '1', '2', '3', '4', '5', '6', '7',
77
77
                          '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
78
 
  size_t dst_ndx;  /* index down the dst */
79
 
  size_t src_ndx;  /* index down the src */
 
78
  size_t dst_ndx;  /* ndx down the dst */
 
79
  size_t src_ndx;  /* ndx down the src */
80
80
 
81
81
  assert(dst);
82
82
  assert(dstlen > 0);
83
83
 
84
 
  for (dst_ndx=0,src_ndx=0; src_ndx<srclen; src_ndx++)
 
84
  for (dst_ndx= 0,src_ndx= 0; src_ndx < srclen; src_ndx++)
85
85
  {
86
86
 
87
 
    /* Worst case, need 5 dst bytes for the next src byte. 
 
87
    /* Worst case, need 5 dst bytes for the next src byte.
88
88
       backslash x hexit hexit null
89
89
       so if not enough room, just terminate the string and return
90
90
    */
105
105
    }
106
106
    else if (src[src_ndx] == 0x07)  // bell
107
107
    {
108
 
      dst[dst_ndx++]= 0x5C; dst[dst_ndx++]=  (unsigned char) 'a';
 
108
      dst[dst_ndx++]= 0x5C; dst[dst_ndx++]= (unsigned char) 'a';
109
109
    }
110
110
    else if (src[src_ndx] == 0x08)  // backspace
111
111
    {
183
183
  if (fd < 0)
184
184
    return false;
185
185
 
186
 
  /* Yes, we know that checking logging_query_enable,
187
 
     logging_query_threshold_big_resultset, and
188
 
     logging_query_threshold_big_examined is not threadsafe, because some
189
 
     other thread might change these sysvars.  But we don't care.  We
190
 
     might start logging a little late as it spreads to other threads.
191
 
     Big deal. */
 
186
  /* Yes, we know that checking sysvar_logging_query_enable,
 
187
     sysvar_logging_query_threshold_big_resultset, and
 
188
     sysvar_logging_query_threshold_big_examined is not threadsafe,
 
189
     because some other thread might change these sysvars.  But we
 
190
     don't care.  We might start logging a little late as it spreads
 
191
     to other threads.  Big deal. */
192
192
 
193
193
  // return if not enabled or query was too fast or resultset was too small
194
 
  if (logging_query_enable == false)
195
 
    return false;
196
 
  if (session->sent_row_count < logging_query_threshold_big_resultset)
197
 
    return false;
198
 
  if (session->examined_row_count < logging_query_threshold_big_examined)
 
194
  if (sysvar_logging_query_enable == false)
 
195
    return false;
 
196
  if (session->sent_row_count < sysvar_logging_query_threshold_big_resultset)
 
197
    return false;
 
198
  if (session->examined_row_count < sysvar_logging_query_threshold_big_examined)
199
199
    return false;
200
200
 
201
201
  // logging this is far too verbose
211
211
 
212
212
  uint64_t t_mark= get_microtime();
213
213
 
214
 
  if ((t_mark - session->start_utime) < (logging_query_threshold_slow)) return false;
 
214
  if ((t_mark - session->start_utime) < (sysvar_logging_query_threshold_slow))
 
215
    return false;
215
216
 
216
217
  // buffer to quotify the query
217
218
  unsigned char qs[255];
218
219
 
 
220
  // to avoid trying to printf %s something that is potentially NULL
 
221
  char *dbs= (char *) session->db;
 
222
  int dbl= (int) session->db_length;
 
223
  if (dbs == NULL)
 
224
  {
 
225
    dbs= "";
 
226
    dbl= 0;
 
227
  }
 
228
 
219
229
  msgbuf_len=
220
230
    snprintf(msgbuf, MAX_MSG_LEN,
221
231
             "%lld,%ld,%ld,\"%.*s\",\"%s\",\"%.*s\",%lld,%lld,%lld,%ld,%ld\n",
223
233
             (unsigned long) session->thread_id,
224
234
             (unsigned long) session->query_id,
225
235
             // dont need to quote the db name, always CSV safe
226
 
             session->db_length, session->db,
 
236
             dbl, dbs,
227
237
             // do need to quote the query
228
238
             (char *) quotify((unsigned char *) session->query, session->query_length,
229
239
                              qs, sizeof(qs)),
250
260
{
251
261
  logging_t *l= (logging_t *) p;
252
262
 
253
 
  if (logging_query_filename == NULL)
 
263
  if (sysvar_logging_query_filename == NULL)
254
264
  {
255
265
    /* no destination filename was specified via system variables
256
266
       return now, dont set the callback pointers
258
268
    return 0;
259
269
  }
260
270
 
261
 
  fd= open(logging_query_filename,
 
271
  fd= open(sysvar_logging_query_filename,
262
272
           O_WRONLY | O_APPEND | O_CREAT,
263
273
           S_IRUSR|S_IWUSR);
264
274
  if (fd < 0)
265
275
  {
266
276
    errmsg_printf(ERRMSG_LVL_ERROR, _("fail open() fn=%s er=%s\n"),
267
 
                  logging_query_filename,
 
277
                  sysvar_logging_query_filename,
268
278
                  strerror(errno));
269
279
 
270
280
    /* TODO
299
309
  return 0;
300
310
}
301
311
 
 
312
static DRIZZLE_SYSVAR_BOOL(
 
313
  enable,
 
314
  sysvar_logging_query_enable,
 
315
  PLUGIN_VAR_NOCMDARG,
 
316
  N_("Enable logging to CSV file"),
 
317
  NULL, /* check func */
 
318
  NULL, /* update func */
 
319
  false /* default */);
 
320
 
302
321
static DRIZZLE_SYSVAR_STR(
303
322
  filename,
304
 
  logging_query_filename,
 
323
  sysvar_logging_query_filename,
305
324
  PLUGIN_VAR_READONLY,
306
325
  N_("File to log to"),
307
326
  NULL, /* check func */
308
327
  NULL, /* update func*/
309
328
  NULL /* default */);
310
329
 
311
 
static DRIZZLE_SYSVAR_BOOL(
312
 
  enable,
313
 
  logging_query_enable,
314
 
  PLUGIN_VAR_NOCMDARG,
315
 
  N_("Enable logging"),
316
 
  NULL, /* check func */
317
 
  NULL, /* update func */
318
 
  true /* default */);
319
 
 
320
330
static DRIZZLE_SYSVAR_ULONG(
321
331
  threshold_slow,
322
 
  logging_query_threshold_slow,
 
332
  sysvar_logging_query_threshold_slow,
323
333
  PLUGIN_VAR_OPCMDARG,
324
334
  N_("Threshold for logging slow queries, in microseconds"),
325
335
  NULL, /* check func */
331
341
 
332
342
static DRIZZLE_SYSVAR_ULONG(
333
343
  threshold_big_resultset,
334
 
  logging_query_threshold_big_resultset,
 
344
  sysvar_logging_query_threshold_big_resultset,
335
345
  PLUGIN_VAR_OPCMDARG,
336
346
  N_("Threshold for logging big queries, for rows returned"),
337
347
  NULL, /* check func */
343
353
 
344
354
static DRIZZLE_SYSVAR_ULONG(
345
355
  threshold_big_examined,
346
 
  logging_query_threshold_big_examined,
 
356
  sysvar_logging_query_threshold_big_examined,
347
357
  PLUGIN_VAR_OPCMDARG,
348
358
  N_("Threshold for logging big queries, for rows examined"),
349
359
  NULL, /* check func */
354
364
  0 /* blksiz */);
355
365
 
356
366
static struct st_mysql_sys_var* logging_query_system_variables[]= {
 
367
  DRIZZLE_SYSVAR(enable),
357
368
  DRIZZLE_SYSVAR(filename),
358
 
  DRIZZLE_SYSVAR(enable),
359
369
  DRIZZLE_SYSVAR(threshold_slow),
360
370
  DRIZZLE_SYSVAR(threshold_big_resultset),
361
371
  DRIZZLE_SYSVAR(threshold_big_examined),
366
376
{
367
377
  DRIZZLE_LOGGER_PLUGIN,
368
378
  "logging_query",
369
 
  "0.1",
 
379
  "0.2",
370
380
  "Mark Atwood <mark@fallenpegasus.com>",
371
 
  N_("Log queries to a file"),
 
381
  N_("Log queries to a CSV file"),
372
382
  PLUGIN_LICENSE_GPL,
373
383
  logging_query_plugin_init,
374
384
  logging_query_plugin_deinit,