~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-03-08 04:23:54 UTC
  • mto: This revision was merged to the branch mainline in revision 1380.
  • Revision ID: skinny.moey@gmail.com-20100308042354-7k0jibdqaxkhac7o
scoreboardĀ implementationĀ forĀ statistics

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2010, Joseph Daly <skinny.moey@gmail.com>
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *
 
8
 *   * Redistributions of source code must retain the above copyright notice,
 
9
 *     this list of conditions and the following disclaimer.
 
10
 *   * Redistributions in binary form must reproduce the above copyright notice,
 
11
 *     this list of conditions and the following disclaimer in the documentation
 
12
 *     and/or other materials provided with the distribution.
 
13
 *   * Neither the name of Joseph Daly nor the names of its contributors
 
14
 *     may be used to endorse or promote products derived from this software
 
15
 *     without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
27
 * THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
/**
 
31
 * @details
 
32
 *
 
33
 *
 
34
 *
 
35
 *
 
36
 */
 
37
 
 
38
#include "config.h"
 
39
#include "logging_stats.h"
 
40
#include "stats_schema.h"
 
41
#include <drizzled/session.h>
 
42
 
 
43
using namespace drizzled;
 
44
using namespace plugin;
 
45
using namespace std;
 
46
 
 
47
static bool sysvar_logging_stats_enabled= false;
 
48
 
 
49
static uint32_t sysvar_logging_stats_scoreboard_size= 1500;
 
50
 
 
51
pthread_rwlock_t LOCK_scoreboard;
 
52
 
 
53
LoggingStats::LoggingStats(std::string name_arg) : drizzled::plugin::Logging(name_arg)
 
54
{
 
55
  scoreboard_size= sysvar_logging_stats_scoreboard_size;
 
56
  score_board_slots= new ScoreBoardSlot[scoreboard_size];
 
57
  for (uint32_t j=0; j < scoreboard_size; j++)
 
58
  { 
 
59
    UserCommands *user_commands= new UserCommands();
 
60
    ScoreBoardSlot *score_board_slot= &score_board_slots[j];
 
61
    score_board_slot->setUserCommands(user_commands); 
 
62
  } 
 
63
}
 
64
 
 
65
LoggingStats::~LoggingStats()
 
66
{
 
67
  delete[] score_board_slots;
 
68
}
 
69
 
 
70
bool LoggingStats::isBeingLogged(Session *session)
 
71
{
 
72
  enum_sql_command sql_command= session->lex->sql_command;
 
73
 
 
74
  switch(sql_command)
 
75
  {
 
76
    case SQLCOM_UPDATE:
 
77
    case SQLCOM_DELETE:
 
78
    case SQLCOM_INSERT:
 
79
    case SQLCOM_ROLLBACK:
 
80
    case SQLCOM_COMMIT:
 
81
    case SQLCOM_CREATE_TABLE:
 
82
    case SQLCOM_ALTER_TABLE:
 
83
    case SQLCOM_DROP_TABLE:
 
84
    case SQLCOM_SELECT:
 
85
      return true;
 
86
    default:
 
87
      return false;
 
88
  }
 
89
 
90
 
 
91
void LoggingStats::updateScoreBoard(ScoreBoardSlot *score_board_slot,
 
92
                                    Session *session)
 
93
{
 
94
  enum_sql_command sql_command= session->lex->sql_command;
 
95
 
 
96
  UserCommands *user_commands= score_board_slot->getUserCommands();
 
97
 
 
98
  switch(sql_command)
 
99
  {
 
100
    case SQLCOM_UPDATE:
 
101
      user_commands->incrementUpdateCount();
 
102
      break;
 
103
    case SQLCOM_DELETE:
 
104
      user_commands->incrementDeleteCount();
 
105
      break;
 
106
    case SQLCOM_INSERT:
 
107
      user_commands->incrementInsertCount();
 
108
      break;
 
109
    case SQLCOM_ROLLBACK:
 
110
      user_commands->incrementRollbackCount();
 
111
      break;
 
112
    case SQLCOM_COMMIT:
 
113
      user_commands->incrementCommitCount();
 
114
      break;
 
115
    case SQLCOM_CREATE_TABLE:
 
116
      user_commands->incrementCreateCount();
 
117
      break;
 
118
    case SQLCOM_ALTER_TABLE:
 
119
      user_commands->incrementAlterCount();
 
120
      break;
 
121
    case SQLCOM_DROP_TABLE:
 
122
      user_commands->incrementDropCount();
 
123
      break;
 
124
    case SQLCOM_SELECT:
 
125
      user_commands->incrementSelectCount();
 
126
      break;
 
127
    default:
 
128
      return;
 
129
  }
 
130
}
 
131
 
 
132
bool LoggingStats::post(Session *session)
 
133
{
 
134
  if (! isEnabled())
 
135
  {
 
136
    return false;
 
137
  }
 
138
 
 
139
  /* exit early if we are not logging this type of command */
 
140
  if (isBeingLogged(session) == false)
 
141
  {
 
142
    return false;
 
143
  }
 
144
 
 
145
  /* Find a slot that is unused */
 
146
 
 
147
  pthread_rwlock_wrlock(&LOCK_scoreboard);
 
148
  ScoreBoardSlot *score_board_slot;
 
149
  int our_slot= -1; 
 
150
 
 
151
  for (uint32_t j=0; j < scoreboard_size; j++)
 
152
  {
 
153
    score_board_slot= &score_board_slots[j];
 
154
 
 
155
    if (score_board_slot->isInUse() == true)
 
156
    {
 
157
      /* Check if this session is the one using this slot */
 
158
      if (score_board_slot->getSessionId() == session->getSessionId())
 
159
      {
 
160
        our_slot= j;
 
161
        break; 
 
162
      } 
 
163
      else 
 
164
      {
 
165
        continue; 
 
166
      }
 
167
    }
 
168
    else 
 
169
    {
 
170
      /* save off the open slot */ 
 
171
      our_slot= j;
 
172
      continue;
 
173
    }
 
174
  }
 
175
 
 
176
  if (our_slot != -1)
 
177
  {
 
178
    score_board_slot->setInUse(true);
 
179
    score_board_slot->setSessionId(session->getSessionId());
 
180
    score_board_slot->setUser(session->getSecurityContext().getUser());
 
181
    score_board_slot->setIp(session->getSecurityContext().getIp());
 
182
    pthread_rwlock_unlock(&LOCK_scoreboard); 
 
183
  }
 
184
  else 
 
185
  {
 
186
    pthread_rwlock_unlock(&LOCK_scoreboard);
 
187
    /* there was no available slot for this session */
 
188
    return false;
 
189
  }
 
190
 
 
191
  updateScoreBoard(score_board_slot, session);
 
192
 
 
193
  return false;
 
194
}
 
195
 
 
196
bool LoggingStats::postEnd(Session *session)
 
197
{
 
198
  if (! isEnabled())
 
199
  {
 
200
    return false;
 
201
  }
 
202
 
 
203
  /* do not pull a lock when we write this is the only thread that
 
204
     can write to a particular sessions slot. */
 
205
 
 
206
  ScoreBoardSlot *score_board_slot;
 
207
 
 
208
  for (uint32_t j=0; j < scoreboard_size; j++)
 
209
  {
 
210
    score_board_slot= &score_board_slots[j];
 
211
 
 
212
    if (score_board_slot->getSessionId() == session->getSessionId())
 
213
    {
 
214
      score_board_slot->reset();
 
215
      break;
 
216
    }
 
217
  }
 
218
  return false;
 
219
}
 
220
 
 
221
/* Plugin initialization and system variables */
 
222
 
 
223
static LoggingStats *logging_stats= NULL;
 
224
 
 
225
static CommandsTool *commands_tool= NULL;
 
226
 
 
227
static void enable(Session *,
 
228
                   drizzle_sys_var *,
 
229
                   void *var_ptr,
 
230
                   const void *save)
 
231
{
 
232
  if (logging_stats)
 
233
  {
 
234
    if (*(bool *)save != false)
 
235
    {
 
236
      logging_stats->enable();
 
237
      *(bool *) var_ptr= (bool) true;
 
238
    }
 
239
    else
 
240
    {
 
241
      logging_stats->disable();
 
242
      *(bool *) var_ptr= (bool) false;
 
243
    }
 
244
  }
 
245
}
 
246
 
 
247
static bool initTable()
 
248
{
 
249
  commands_tool= new(std::nothrow)CommandsTool(logging_stats);
 
250
 
 
251
  if (! commands_tool)
 
252
  {
 
253
    return true;
 
254
  }
 
255
 
 
256
  return false;
 
257
}
 
258
 
 
259
static int init(drizzled::plugin::Registry &registry)
 
260
{
 
261
  logging_stats= new LoggingStats("logging_stats");
 
262
 
 
263
  if (initTable())
 
264
  {
 
265
    return 1;
 
266
  }
 
267
 
 
268
  registry.add(logging_stats);
 
269
  registry.add(commands_tool);
 
270
 
 
271
  if (sysvar_logging_stats_enabled)
 
272
  {
 
273
    logging_stats->enable();
 
274
  }
 
275
 
 
276
  return 0;
 
277
}
 
278
 
 
279
static int deinit(drizzled::plugin::Registry &registry)
 
280
{
 
281
  if (logging_stats)
 
282
  {
 
283
    registry.remove(commands_tool);
 
284
    registry.remove(logging_stats);
 
285
 
 
286
    delete commands_tool;
 
287
    delete logging_stats;
 
288
  }
 
289
  return 0;
 
290
}
 
291
 
 
292
static DRIZZLE_SYSVAR_BOOL(enable,
 
293
                           sysvar_logging_stats_enabled,
 
294
                           PLUGIN_VAR_NOCMDARG,
 
295
                           N_("Enable Logging Statistics Collection"),
 
296
                           NULL, /* check func */
 
297
                           enable, /* update func */
 
298
                           false /* default */);
 
299
 
 
300
static drizzle_sys_var* system_var[]= {
 
301
  DRIZZLE_SYSVAR(enable),
 
302
  NULL
 
303
};
 
304
 
 
305
DRIZZLE_DECLARE_PLUGIN
 
306
{
 
307
  DRIZZLE_VERSION_ID,
 
308
  "logging_stats",
 
309
  "0.1",
 
310
  "Joseph Daly",
 
311
  N_("User Statistics as DATA_DICTIONARY tables"),
 
312
  PLUGIN_LICENSE_BSD,
 
313
  init,   /* Plugin Init      */
 
314
  deinit, /* Plugin Deinit    */
 
315
  system_var, /* system variables */
 
316
  NULL    /* config options   */
 
317
}
 
318
DRIZZLE_DECLARE_PLUGIN_END;