~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/logging_stats/logging_stats.cc

  • Committer: Joe Daly
  • Date: 2010-06-06 18:08:00 UTC
  • mto: This revision was merged to the branch mainline in revision 1614.
  • Revision ID: skinny.moey@gmail.com-20100606180800-414svjbgxc9wz1z3
fix compiler warning (hopefully) change lu to PRIu64

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
/**
31
31
 * @details
32
32
 *
33
 
 * This plugin tracks session and global statistics, as well as user statistics. 
34
 
 * The commands are logged using the post() and postEnd() logging APIs. 
35
 
 * The statistics are stored in a Scoreboard where each active session owns a 
36
 
 * ScoreboardSlot during the sessions active lifetime. 
37
 
 * 
 
33
 * This plugin tracks the current user commands for a session, and copies
 
34
 * them into a cumulative vector of all commands run by a user over time. 
 
35
 * The commands are logged using the post() and postEnd() logging APIs.
 
36
 * User commands are stored in a Scoreboard where each active session
 
37
 * owns a ScoreboardSlot.  
 
38
 *
38
39
 * Scoreboard
39
40
 *
40
 
 * The scoreboard is a pre-allocated vector of vectors of ScoreboardSlots. It 
41
 
 * can be thought of as a vector of buckets where each bucket contains 
42
 
 * pre-allocated ScoreboardSlots. To determine which bucket gets used for 
43
 
 * recording statistics the modulus operator is used on the session_id. This 
44
 
 * will result in a bucket to search for a unused ScoreboardSlot. Once a 
45
 
 * ScoreboardSlot is found the index of the slot is stored in the Session 
46
 
 * for later use. 
 
41
 * The scoreboard is a pre-allocated vector of vectors of ScoreboardSlots. It
 
42
 * can be thought of as a vector of buckets where each bucket contains
 
43
 * pre-allocated ScoreboardSlots. To determine which bucket gets used for
 
44
 * recording statistics the modulus operator is used on the session_id. This
 
45
 * will result in a bucket to search for a unused ScoreboardSlot.
47
46
 *
48
47
 * Locking  
49
48
 * 
50
49
 * Each vector in the Scoreboard has its own lock. This allows session 2 
51
50
 * to not have to wait for session 1 to locate a slot to use, as they
52
51
 * will be in different buckets.  A lock is taken to locate a open slot
53
 
 * in the scoreboard. Subsequent queries by the session will not take
54
 
 * a lock.  
 
52
 * in the scoreboard.
55
53
 *
56
54
 * A read lock is taken on the scoreboard vector when the table is queried 
57
 
 * in the data_dictionary. The "show status" and "show global status" do
58
 
 * not take a read lock when the data_dictionary table is queried, the 
59
 
 * user is not displayed in these results so it is not necessary. 
 
55
 * in the data_dictionary.
60
56
 *
61
57
 * Atomics
62
58
 *
82
78
 *
83
79
 * Allow expansion of Scoreboard and cumulative vector 
84
80
 * 
 
81
 * Possibly add a scoreboard_slot_index variable onto the Session class
 
82
 * this would avoid having to relocate the Scoreboard slot for each Session
 
83
 * doing multiple statements. 
 
84
 * 
85
85
 */
86
86
 
87
87
#include "config.h"
91
91
#include "logging_stats.h"
92
92
#include "status_tool.h"
93
93
#include "stats_schema.h"
94
 
#include <boost/program_options.hpp>
95
 
#include <drizzled/module/option_map.h>
 
94
 
96
95
#include <drizzled/session.h>
97
96
 
98
 
namespace po= boost::program_options;
99
97
using namespace drizzled;
100
98
using namespace plugin;
101
99
using namespace std;
102
100
 
103
101
static bool sysvar_logging_stats_enabled= true;
104
102
 
105
 
typedef constrained_check<uint32_t, 50000, 10> scoreboard_size_constraint;
106
 
static scoreboard_size_constraint sysvar_logging_stats_scoreboard_size;
107
 
 
108
 
typedef constrained_check<uint32_t, 50000, 100> max_user_count_constraint;
109
 
static max_user_count_constraint sysvar_logging_stats_max_user_count;
110
 
 
111
 
typedef constrained_check<uint32_t, 500, 5> bucket_count_constraint;
112
 
static bucket_count_constraint sysvar_logging_stats_bucket_count;
 
103
static uint32_t sysvar_logging_stats_scoreboard_size= 2000;
 
104
 
 
105
static uint32_t sysvar_logging_stats_max_user_count= 1000;
 
106
 
 
107
static uint32_t sysvar_logging_stats_bucket_count= 10;
113
108
 
114
109
LoggingStats::LoggingStats(string name_arg) : Logging(name_arg)
115
110
{
140
135
  scoreboard_slot->getStatusVars()->logStatusVar(session);
141
136
}
142
137
 
143
 
bool LoggingStats::resetGlobalScoreboard()
144
 
{
145
 
  cumulative_stats->getGlobalStatusVars()->reset();
146
 
  cumulative_stats->getGlobalStats()->getUserCommands()->reset();
147
 
 
148
 
  ScoreBoardVectors *vector_of_scoreboard_vectors=
149
 
    current_scoreboard->getVectorOfScoreboardVectors();
150
 
 
151
 
  ScoreBoardVectors::iterator v_of_scoreboard_v_begin_it= vector_of_scoreboard_vectors->begin();
152
 
 
153
 
  ScoreBoardVectors::iterator v_of_scoreboard_v_end_it= vector_of_scoreboard_vectors->end();
154
 
 
155
 
  for (; v_of_scoreboard_v_begin_it != v_of_scoreboard_v_end_it; ++v_of_scoreboard_v_begin_it)
156
 
  {
157
 
    std::vector<ScoreboardSlot* > *scoreboard_vector= *v_of_scoreboard_v_begin_it;
158
 
 
159
 
    std::vector<ScoreboardSlot* >::iterator scoreboard_vector_it= scoreboard_vector->begin();
160
 
    std::vector<ScoreboardSlot* >::iterator scoreboard_vector_end= scoreboard_vector->end();
161
 
    for (; scoreboard_vector_it != scoreboard_vector_end; ++scoreboard_vector_it)
162
 
    {
163
 
      ScoreboardSlot *scoreboard_slot= *scoreboard_vector_it;
164
 
      scoreboard_slot->getStatusVars()->reset();
165
 
      scoreboard_slot->getUserCommands()->reset();
166
 
    }
167
 
  }
168
 
 
169
 
  return false;
170
 
}
171
 
 
172
138
bool LoggingStats::post(Session *session)
173
139
{
174
140
  if (! isEnabled() || (session->getSessionId() == 0))
194
160
    return false;
195
161
  }
196
162
 
197
 
  bool isInScoreboard= false;
198
 
  ScoreboardSlot *scoreboard_slot= current_scoreboard->findOurScoreboardSlot(session);
 
163
  ScoreboardSlot *scoreboard_slot= current_scoreboard->findAndResetScoreboardSlot(session);
199
164
 
200
165
  if (scoreboard_slot)
201
166
  {
202
 
    isInScoreboard= true;
203
 
  } 
204
 
  else 
205
 
  { 
206
 
    /* the session did not have a slot reserved, that could be because the scoreboard was
207
 
       full, but most likely its a failed authentication so post() is never called where
208
 
       the slot is assigned. Log the global status values below, and if the user has a slot
209
 
       log to it, but do not reserve a new slot for a user. If it was a failed authentication
210
 
       the scoreboard would be filled up quickly with invalid users. 
211
 
    */
212
 
    scoreboard_slot= new ScoreboardSlot();
213
 
    scoreboard_slot->setUser(session->getSecurityContext().getUser());
214
 
    scoreboard_slot->setIp(session->getSecurityContext().getIp());
215
 
  }
216
 
 
217
 
  scoreboard_slot->getStatusVars()->logStatusVar(session);
218
 
  scoreboard_slot->getStatusVars()->getStatusVarCounters()->connection_time= time(NULL) - session->start_time; 
219
 
 
220
 
  cumulative_stats->logUserStats(scoreboard_slot, isInScoreboard);
221
 
  cumulative_stats->logGlobalStats(scoreboard_slot);
222
 
  cumulative_stats->logGlobalStatusVars(scoreboard_slot);
223
 
 
224
 
  if (isInScoreboard)
225
 
  {
226
 
    scoreboard_slot->reset();
227
 
  } 
228
 
  else 
229
 
  {
 
167
    cumulative_stats->logUserStats(scoreboard_slot);
 
168
    cumulative_stats->logGlobalStats(scoreboard_slot);
 
169
    cumulative_stats->logGlobalStatusVars(scoreboard_slot);
230
170
    delete scoreboard_slot;
231
 
  } 
 
171
  }
232
172
 
233
173
  return false;
234
174
}
245
185
 
246
186
static SessionStatementsTool *session_statements_tool= NULL;
247
187
 
 
188
static StatusVarTool *status_var_tool= NULL;
 
189
 
248
190
static StatusTool *global_status_tool= NULL;
249
191
 
250
192
static StatusTool *session_status_tool= NULL;
251
193
 
252
 
static CumulativeUserStatsTool *cumulative_user_stats_tool= NULL;
253
 
 
254
 
static ScoreboardStatsTool *scoreboard_stats_tool= NULL;
255
 
 
256
 
static void enable(Session *, sql_var_t)
 
194
static void enable(Session *,
 
195
                   drizzle_sys_var *,
 
196
                   void *var_ptr,
 
197
                   const void *save)
257
198
{
258
199
  if (logging_stats)
259
200
  {
260
 
    if (sysvar_logging_stats_enabled)
 
201
    if (*(bool *)save != false)
261
202
    {
262
203
      logging_stats->enable();
 
204
      *(bool *) var_ptr= (bool) true;
263
205
    }
264
206
    else
265
207
    {
266
208
      logging_stats->disable();
 
209
      *(bool *) var_ptr= (bool) false;
267
210
    }
268
211
  }
269
212
}
298
241
    return true;
299
242
  }
300
243
 
 
244
  status_var_tool= new(nothrow)StatusVarTool(logging_stats);
 
245
 
 
246
  if (! status_var_tool)
 
247
  {
 
248
    return true;
 
249
  }
 
250
 
301
251
  session_status_tool= new(nothrow)StatusTool(logging_stats, true);
302
252
 
303
253
  if (! session_status_tool)
312
262
    return true;
313
263
  }
314
264
 
315
 
  cumulative_user_stats_tool= new(nothrow)CumulativeUserStatsTool(logging_stats);
316
 
 
317
 
  if (! cumulative_user_stats_tool)
318
 
  {
319
 
    return true;
320
 
  }
321
 
 
322
 
  scoreboard_stats_tool= new(nothrow)ScoreboardStatsTool(logging_stats);
323
 
  
324
 
  if (! scoreboard_stats_tool)
325
 
  {
326
 
    return true;
327
 
  }
328
 
 
329
265
  return false;
330
266
}
331
267
 
332
 
static int init(drizzled::module::Context &context)
 
268
static int init(module::Context &context)
333
269
{
334
 
  const module::option_map &vm= context.getOptions();
335
 
 
336
 
  sysvar_logging_stats_enabled= (vm.count("disable")) ? false : true;
337
 
 
338
270
  logging_stats= new LoggingStats("logging_stats");
339
271
 
340
272
  if (initTable())
347
279
  context.add(cumulative_commands_tool);
348
280
  context.add(global_statements_tool);
349
281
  context.add(session_statements_tool);
 
282
  context.add(status_var_tool);
350
283
  context.add(session_status_tool);
351
284
  context.add(global_status_tool);
352
 
  context.add(cumulative_user_stats_tool);
353
 
  context.add(scoreboard_stats_tool);
 
285
 
354
286
 
355
287
  if (sysvar_logging_stats_enabled)
356
288
  {
357
289
    logging_stats->enable();
358
290
  }
359
291
 
360
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("max_user_count", sysvar_logging_stats_max_user_count));
361
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("bucket_count", sysvar_logging_stats_bucket_count));
362
 
  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("scoreboard_size", sysvar_logging_stats_scoreboard_size));
363
 
  context.registerVariable(new sys_var_bool_ptr("enable", &sysvar_logging_stats_enabled, enable));
364
 
 
365
292
  return 0;
366
293
}
367
294
 
368
 
 
369
 
static void init_options(drizzled::module::option_context &context)
370
 
{
371
 
  context("max-user-count",
372
 
          po::value<max_user_count_constraint>(&sysvar_logging_stats_max_user_count)->default_value(500),
373
 
          N_("Max number of users that will be logged"));
374
 
  context("bucket-count",
375
 
          po::value<bucket_count_constraint>(&sysvar_logging_stats_bucket_count)->default_value(10),
376
 
          N_("Max number of range locks to use for Scoreboard"));
377
 
  context("scoreboard-size",
378
 
          po::value<scoreboard_size_constraint>(&sysvar_logging_stats_scoreboard_size)->default_value(2000),
379
 
          N_("Max number of concurrent sessions that will be logged"));
380
 
  context("disable", N_("Enable Logging Statistics Collection"));
381
 
}
 
295
static DRIZZLE_SYSVAR_UINT(max_user_count,
 
296
                           sysvar_logging_stats_max_user_count,
 
297
                           PLUGIN_VAR_RQCMDARG,
 
298
                           N_("Max number of users that will be logged"),
 
299
                           NULL, /* check func */
 
300
                           NULL, /* update func */
 
301
                           1000, /* default */
 
302
                           500, /* minimum */
 
303
                           50000,
 
304
                           0);
 
305
 
 
306
static DRIZZLE_SYSVAR_UINT(bucket_count,
 
307
                           sysvar_logging_stats_bucket_count,
 
308
                           PLUGIN_VAR_RQCMDARG,
 
309
                           N_("Max number of vector buckets to construct for logging"),
 
310
                           NULL, /* check func */
 
311
                           NULL, /* update func */
 
312
                           10, /* default */
 
313
                           5, /* minimum */
 
314
                           500,
 
315
                           0);
 
316
 
 
317
static DRIZZLE_SYSVAR_UINT(scoreboard_size,
 
318
                           sysvar_logging_stats_scoreboard_size,
 
319
                           PLUGIN_VAR_RQCMDARG,
 
320
                           N_("Max number of concurrent sessions that will be logged"),
 
321
                           NULL, /* check func */
 
322
                           NULL, /* update func */
 
323
                           2000, /* default */
 
324
                           10, /* minimum */
 
325
                           50000, 
 
326
                           0);
 
327
 
 
328
static DRIZZLE_SYSVAR_BOOL(enable,
 
329
                           sysvar_logging_stats_enabled,
 
330
                           PLUGIN_VAR_NOCMDARG,
 
331
                           N_("Enable Logging Statistics Collection"),
 
332
                           NULL, /* check func */
 
333
                           enable, /* update func */
 
334
                           true /* default */);
 
335
 
 
336
static drizzle_sys_var* system_var[]= {
 
337
  DRIZZLE_SYSVAR(max_user_count),
 
338
  DRIZZLE_SYSVAR(bucket_count),
 
339
  DRIZZLE_SYSVAR(scoreboard_size),
 
340
  DRIZZLE_SYSVAR(enable),
 
341
  NULL
 
342
};
382
343
 
383
344
DRIZZLE_DECLARE_PLUGIN
384
345
{
389
350
  N_("User Statistics as DATA_DICTIONARY tables"),
390
351
  PLUGIN_LICENSE_BSD,
391
352
  init,   /* Plugin Init      */
392
 
  NULL, /* system variables */
393
 
  init_options    /* config options   */
 
353
  system_var, /* system variables */
 
354
  NULL    /* config options   */
394
355
}
395
356
DRIZZLE_DECLARE_PLUGIN_END;