~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/logging_query/logging_query.cc

  • Committer: Brian Aker
  • Date: 2010-12-18 10:14:05 UTC
  • mfrom: (2008.1.3 clean)
  • Revision ID: brian@tangent.org-20101218101405-qjbse29shi9coklg
Merge of user identifier work

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#define ESCAPE_CHAR      '\\'
42
42
#define SEPARATOR_CHAR   ','
43
43
 
 
44
namespace drizzle_plugin
 
45
{
 
46
 
44
47
static bool sysvar_logging_query_enable= false;
45
 
static char* sysvar_logging_query_filename= NULL;
46
 
static char* sysvar_logging_query_pcre= NULL;
47
48
/* TODO fix these to not be unsigned long once we have sensible sys_var system */
48
 
static unsigned long sysvar_logging_query_threshold_slow= 0;
49
 
static unsigned long sysvar_logging_query_threshold_big_resultset= 0;
50
 
static unsigned long sysvar_logging_query_threshold_big_examined= 0;
 
49
static uint32_constraint sysvar_logging_query_threshold_slow;
 
50
static uint32_constraint sysvar_logging_query_threshold_big_resultset;
 
51
static uint32_constraint sysvar_logging_query_threshold_big_examined;
51
52
 
52
53
/* quote a string to be safe to include in a CSV line
53
54
   that means backslash quoting all commas, doublequotes, backslashes,
142
143
 
143
144
class Logging_query: public drizzled::plugin::Logging
144
145
{
 
146
  const std::string _filename;
 
147
  const std::string _query_pcre;
145
148
  int fd;
146
149
  pcre *re;
147
150
  pcre_extra *pe;
151
154
 
152
155
public:
153
156
 
154
 
  Logging_query()
155
 
    : drizzled::plugin::Logging("Logging_query"),
156
 
      fd(-1), re(NULL), pe(NULL),
157
 
      formatter("%1%,%2%,%3%,\"%4%\",\"%5%\",\"%6%\",%7%,%8%,"
158
 
                "%9%,%10%,%11%,%12%,%13%,%14%,\"%15%\"\n")
 
157
  Logging_query(const std::string &filename,
 
158
                const std::string &query_pcre) :
 
159
    drizzled::plugin::Logging("Logging_query"),
 
160
    _filename(filename),
 
161
    _query_pcre(query_pcre),
 
162
    fd(-1), re(NULL), pe(NULL),
 
163
    formatter("%1%,%2%,%3%,\"%4%\",\"%5%\",\"%6%\",%7%,%8%,"
 
164
              "%9%,%10%,%11%,%12%,%13%,%14%,\"%15%\"\n")
159
165
  {
160
166
 
161
167
    /* if there is no destination filename, dont bother doing anything */
162
 
    if (sysvar_logging_query_filename == NULL)
 
168
    if (_filename.empty())
163
169
      return;
164
170
 
165
 
    fd= open(sysvar_logging_query_filename,
 
171
    fd= open(_filename.c_str(),
166
172
             O_WRONLY | O_APPEND | O_CREAT,
167
173
             S_IRUSR|S_IWUSR);
168
174
    if (fd < 0)
170
176
      char errmsg[STRERROR_MAX];
171
177
      strerror_r(errno, errmsg, sizeof(errmsg));
172
178
      errmsg_printf(ERRMSG_LVL_ERROR, _("fail open() fn=%s er=%s\n"),
173
 
                    sysvar_logging_query_filename,
 
179
                    _filename.c_str(),
174
180
                    errmsg);
175
181
      return;
176
182
    }
177
183
 
178
 
    if (sysvar_logging_query_pcre != NULL)
 
184
    if (not _query_pcre.empty())
179
185
    {
180
186
      const char *this_pcre_error;
181
187
      int this_pcre_erroffset;
182
 
      re= pcre_compile(sysvar_logging_query_pcre, 0, &this_pcre_error,
 
188
      re= pcre_compile(_query_pcre.c_str(), 0, &this_pcre_error,
183
189
                       &this_pcre_erroffset, NULL);
184
190
      pe= pcre_study(re, 0, &this_pcre_error);
185
191
      /* TODO emit error messages if there is a problem */
223
229
    // return if not enabled or query was too fast or resultset was too small
224
230
    if (sysvar_logging_query_enable == false)
225
231
      return false;
226
 
    if (session->sent_row_count < sysvar_logging_query_threshold_big_resultset)
 
232
    if (session->sent_row_count < sysvar_logging_query_threshold_big_resultset.get())
227
233
      return false;
228
 
    if (session->examined_row_count < sysvar_logging_query_threshold_big_examined)
 
234
    if (session->examined_row_count < sysvar_logging_query_threshold_big_examined.get())
229
235
      return false;
230
236
 
231
237
    /* TODO, the session object should have a "utime command completed"
236
242
    boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
237
243
    uint64_t t_mark= (mytime-epoch).total_microseconds();
238
244
 
239
 
    if ((t_mark - session->start_utime) < (sysvar_logging_query_threshold_slow))
 
245
    if ((t_mark - session->start_utime) < (sysvar_logging_query_threshold_slow.get()))
240
246
      return false;
241
247
 
242
248
    Session::QueryString query_string(session->getQueryString());
258
264
    quotify(*query_string, qs);
259
265
    
260
266
    // to avoid trying to printf %s something that is potentially NULL
261
 
    const char *dbs= session->db.empty() ? "" : session->db.c_str();
 
267
    util::string::const_shared_ptr schema(session->schema());
 
268
    const char *dbs= (schema and not schema->empty()) ? schema->c_str() : "";
262
269
 
263
270
    formatter % t_mark
264
271
              % session->thread_id
286
293
  }
287
294
};
288
295
 
289
 
static Logging_query *handler= NULL;
290
 
 
291
296
static int logging_query_plugin_init(drizzled::module::Context &context)
292
297
{
293
298
 
294
299
  const module::option_map &vm= context.getOptions();
295
 
  if (vm.count("threshold-slow"))
296
 
  {
297
 
    if (sysvar_logging_query_threshold_slow > UINT32_MAX)
298
 
    {
299
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for threshold-slow"));
300
 
      return 1;
301
 
    }
302
 
  }
303
 
 
304
 
  if (vm.count("threshold-big-resultset"))
305
 
  {
306
 
    if (sysvar_logging_query_threshold_big_resultset > UINT32_MAX)
307
 
    {
308
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for threshold-big-resultset"));
309
 
      return 1;
310
 
    }
311
 
  }
312
 
 
313
 
  if (vm.count("threshold-big-examined"))
314
 
  {
315
 
    if (sysvar_logging_query_threshold_big_examined > UINT32_MAX)
316
 
    {
317
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for threshold-big-examined"));
318
 
      return 1;
319
 
    }
320
 
  }
321
 
  handler= new Logging_query();
322
 
  context.add(handler);
 
300
 
 
301
  if (vm.count("filename") > 0)
 
302
  {
 
303
    context.add(new Logging_query(vm["filename"].as<string>(),
 
304
                                  vm["pcre"].as<string>()));
 
305
    context.registerVariable(new sys_var_bool_ptr("enable", &sysvar_logging_query_enable));
 
306
    context.registerVariable(new sys_var_const_string_val("filename", vm["filename"].as<string>()));
 
307
    context.registerVariable(new sys_var_const_string_val("pcre", vm["pcre"].as<string>()));
 
308
    context.registerVariable(new sys_var_constrained_value<uint32_t>("threshold_slow", sysvar_logging_query_threshold_slow));
 
309
    context.registerVariable(new sys_var_constrained_value<uint32_t>("threshold_big_resultset", sysvar_logging_query_threshold_big_resultset));
 
310
    context.registerVariable(new sys_var_constrained_value<uint32_t>("threshold_big_examined", sysvar_logging_query_threshold_big_examined));
 
311
  }
323
312
 
324
313
  return 0;
325
314
}
329
318
  context("enable",
330
319
          po::value<bool>(&sysvar_logging_query_enable)->default_value(false)->zero_tokens(),
331
320
          N_("Enable logging to CSV file"));
 
321
  context("filename",
 
322
          po::value<string>(),
 
323
          N_("File to log to"));
 
324
  context("pcre",
 
325
          po::value<string>()->default_value(""),
 
326
          N_("PCRE to match the query against"));
332
327
  context("threshold-slow",
333
 
          po::value<unsigned long>(&sysvar_logging_query_threshold_slow)->default_value(0),
 
328
          po::value<uint32_constraint>(&sysvar_logging_query_threshold_slow)->default_value(0),
334
329
          N_("Threshold for logging slow queries, in microseconds"));
335
330
  context("threshold-big-resultset",
336
 
          po::value<unsigned long>(&sysvar_logging_query_threshold_big_resultset)->default_value(0),
 
331
          po::value<uint32_constraint>(&sysvar_logging_query_threshold_big_resultset)->default_value(0),
337
332
          N_("Threshold for logging big queries, for rows returned"));
338
333
  context("threshold-big-examined",
339
 
          po::value<unsigned long>(&sysvar_logging_query_threshold_big_examined)->default_value(0),
 
334
          po::value<uint32_constraint>(&sysvar_logging_query_threshold_big_examined)->default_value(0),
340
335
          N_("Threshold for logging big queries, for rows examined"));
341
336
}
342
337
 
343
 
static DRIZZLE_SYSVAR_BOOL(
344
 
  enable,
345
 
  sysvar_logging_query_enable,
346
 
  PLUGIN_VAR_NOCMDARG,
347
 
  N_("Enable logging to CSV file"),
348
 
  NULL, /* check func */
349
 
  NULL, /* update func */
350
 
  false /* default */);
351
 
 
352
 
static DRIZZLE_SYSVAR_STR(
353
 
  filename,
354
 
  sysvar_logging_query_filename,
355
 
  PLUGIN_VAR_READONLY,
356
 
  N_("File to log to"),
357
 
  NULL, /* check func */
358
 
  NULL, /* update func*/
359
 
  NULL /* default */);
360
 
 
361
 
static DRIZZLE_SYSVAR_STR(
362
 
  pcre,
363
 
  sysvar_logging_query_pcre,
364
 
  PLUGIN_VAR_READONLY,
365
 
  N_("PCRE to match the query against"),
366
 
  NULL, /* check func */
367
 
  NULL, /* update func*/
368
 
  NULL /* default */);
369
 
 
370
 
static DRIZZLE_SYSVAR_ULONG(
371
 
  threshold_slow,
372
 
  sysvar_logging_query_threshold_slow,
373
 
  PLUGIN_VAR_OPCMDARG,
374
 
  N_("Threshold for logging slow queries, in microseconds"),
375
 
  NULL, /* check func */
376
 
  NULL, /* update func */
377
 
  0, /* default */
378
 
  0, /* min */
379
 
  UINT32_MAX, /* max */
380
 
  0 /* blksiz */);
381
 
 
382
 
static DRIZZLE_SYSVAR_ULONG(
383
 
  threshold_big_resultset,
384
 
  sysvar_logging_query_threshold_big_resultset,
385
 
  PLUGIN_VAR_OPCMDARG,
386
 
  N_("Threshold for logging big queries, for rows returned"),
387
 
  NULL, /* check func */
388
 
  NULL, /* update func */
389
 
  0, /* default */
390
 
  0, /* min */
391
 
  UINT32_MAX, /* max */
392
 
  0 /* blksiz */);
393
 
 
394
 
static DRIZZLE_SYSVAR_ULONG(
395
 
  threshold_big_examined,
396
 
  sysvar_logging_query_threshold_big_examined,
397
 
  PLUGIN_VAR_OPCMDARG,
398
 
  N_("Threshold for logging big queries, for rows examined"),
399
 
  NULL, /* check func */
400
 
  NULL, /* update func */
401
 
  0, /* default */
402
 
  0, /* min */
403
 
  UINT32_MAX, /* max */
404
 
  0 /* blksiz */);
405
 
 
406
 
static drizzle_sys_var* logging_query_system_variables[]= {
407
 
  DRIZZLE_SYSVAR(enable),
408
 
  DRIZZLE_SYSVAR(filename),
409
 
  DRIZZLE_SYSVAR(pcre),
410
 
  DRIZZLE_SYSVAR(threshold_slow),
411
 
  DRIZZLE_SYSVAR(threshold_big_resultset),
412
 
  DRIZZLE_SYSVAR(threshold_big_examined),
413
 
  NULL
414
 
};
 
338
} /* namespace drizzle_plugin */
415
339
 
416
340
DRIZZLE_DECLARE_PLUGIN
417
341
{
421
345
  "Mark Atwood <mark@fallenpegasus.com>",
422
346
  N_("Log queries to a CSV file"),
423
347
  PLUGIN_LICENSE_GPL,
424
 
  logging_query_plugin_init,
425
 
  logging_query_system_variables,
426
 
  init_options
 
348
  drizzle_plugin::logging_query_plugin_init,
 
349
  NULL,
 
350
  drizzle_plugin::init_options
427
351
}
428
352
DRIZZLE_DECLARE_PLUGIN_END;