Drizzled Public API Documentation

logging_stats.cc
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 
87 #include <config.h>
88 #include "user_commands.h"
89 #include "status_vars.h"
90 #include "global_stats.h"
91 #include "logging_stats.h"
92 #include "status_tool.h"
93 #include "stats_schema.h"
94 #include <boost/program_options.hpp>
96 #include <drizzled/session.h>
97 #include <drizzled/session/times.h>
98 #include <drizzled/sql_lex.h>
99 #include <drizzled/statistics_variables.h>
100 
101 namespace po= boost::program_options;
102 using namespace drizzled;
103 using namespace plugin;
104 using namespace std;
105 
106 static bool sysvar_logging_stats_enabled= true;
107 
109 static scoreboard_size_constraint sysvar_logging_stats_scoreboard_size;
110 
112 static max_user_count_constraint sysvar_logging_stats_max_user_count;
113 
115 static bucket_count_constraint sysvar_logging_stats_bucket_count;
116 
117 LoggingStats::LoggingStats(string name_arg) : Logging(name_arg)
118 {
119  current_scoreboard= new Scoreboard(sysvar_logging_stats_scoreboard_size,
120  sysvar_logging_stats_bucket_count);
121 
122  cumulative_stats= new CumulativeStats(sysvar_logging_stats_max_user_count);
123 }
124 
125 LoggingStats::~LoggingStats()
126 {
127  delete current_scoreboard;
128  delete cumulative_stats;
129 }
130 
131 void LoggingStats::updateCurrentScoreboard(ScoreboardSlot *scoreboard_slot,
132  Session *session)
133 {
134  enum_sql_command sql_command= session->lex().sql_command;
135 
136  scoreboard_slot->getUserCommands()->logCommand(sql_command);
137 
138  /* If a flush occurred copy over values before setting new values */
139  if (scoreboard_slot->getStatusVars()->hasBeenFlushed(session))
140  {
141  cumulative_stats->logGlobalStatusVars(scoreboard_slot);
142  }
143  scoreboard_slot->getStatusVars()->logStatusVar(session);
144 }
145 
146 bool LoggingStats::resetGlobalScoreboard()
147 {
148  cumulative_stats->getGlobalStatusVars()->reset();
149  cumulative_stats->getGlobalStats()->getUserCommands()->reset();
150 
151  ScoreBoardVectors *vector_of_scoreboard_vectors=
152  current_scoreboard->getVectorOfScoreboardVectors();
153 
154  ScoreBoardVectors::iterator v_of_scoreboard_v_begin_it= vector_of_scoreboard_vectors->begin();
155 
156  ScoreBoardVectors::iterator v_of_scoreboard_v_end_it= vector_of_scoreboard_vectors->end();
157 
158  for (; v_of_scoreboard_v_begin_it != v_of_scoreboard_v_end_it; ++v_of_scoreboard_v_begin_it)
159  {
160  std::vector<ScoreboardSlot* > *scoreboard_vector= *v_of_scoreboard_v_begin_it;
161 
162  std::vector<ScoreboardSlot* >::iterator scoreboard_vector_it= scoreboard_vector->begin();
163  std::vector<ScoreboardSlot* >::iterator scoreboard_vector_end= scoreboard_vector->end();
164  for (; scoreboard_vector_it != scoreboard_vector_end; ++scoreboard_vector_it)
165  {
166  ScoreboardSlot *scoreboard_slot= *scoreboard_vector_it;
167  scoreboard_slot->getStatusVars()->reset();
168  scoreboard_slot->getUserCommands()->reset();
169  }
170  }
171 
172  return false;
173 }
174 
175 bool LoggingStats::post(Session *session)
176 {
177  if (! isEnabled() || (session->getSessionId() == 0))
178  {
179  return false;
180  }
181 
182  ScoreboardSlot *scoreboard_slot= current_scoreboard->findScoreboardSlotToLog(session);
183 
184  /* Its possible that the scoreboard is full with active sessions in which case
185  this could be null */
186  if (scoreboard_slot)
187  {
188  updateCurrentScoreboard(scoreboard_slot, session);
189  }
190  return false;
191 }
192 
193 bool LoggingStats::postEnd(Session *session)
194 {
195  if (! isEnabled() || (session->getSessionId() == 0))
196  {
197  return false;
198  }
199 
200  bool isInScoreboard= false;
201  ScoreboardSlot *scoreboard_slot= current_scoreboard->findOurScoreboardSlot(session);
202 
203  if (scoreboard_slot)
204  {
205  isInScoreboard= true;
206  }
207  else
208  {
209  /* the session did not have a slot reserved, that could be because the scoreboard was
210  full, but most likely its a failed authentication so post() is never called where
211  the slot is assigned. Log the global status values below, and if the user has a slot
212  log to it, but do not reserve a new slot for a user. If it was a failed authentication
213  the scoreboard would be filled up quickly with invalid users.
214  */
215  scoreboard_slot= new ScoreboardSlot();
216  scoreboard_slot->setUser(session->user()->username());
217  scoreboard_slot->setIp(session->user()->address());
218  }
219 
220  scoreboard_slot->getStatusVars()->logStatusVar(session);
221  boost::posix_time::ptime end(boost::posix_time::microsec_clock::universal_time());
222  uint64_t end_time= (end - session->times.epoch()).total_seconds();
223  scoreboard_slot->getStatusVars()->getStatusVarCounters()->connection_time= end_time - session->times.getConnectSeconds();
224 
225  cumulative_stats->logUserStats(scoreboard_slot, isInScoreboard);
226  cumulative_stats->logGlobalStats(scoreboard_slot);
227  cumulative_stats->logGlobalStatusVars(scoreboard_slot);
228 
229  if (isInScoreboard)
230  {
231  scoreboard_slot->reset();
232  }
233  else
234  {
235  delete scoreboard_slot;
236  }
237 
238  return false;
239 }
240 
241 /* Plugin initialization and system variables */
242 
243 static LoggingStats *logging_stats= NULL;
244 
245 static CurrentCommandsTool *current_commands_tool= NULL;
246 
247 static CumulativeCommandsTool *cumulative_commands_tool= NULL;
248 
249 static GlobalStatementsTool *global_statements_tool= NULL;
250 
251 static SessionStatementsTool *session_statements_tool= NULL;
252 
253 static StatusTool *global_status_tool= NULL;
254 
255 static StatusTool *session_status_tool= NULL;
256 
257 static CumulativeUserStatsTool *cumulative_user_stats_tool= NULL;
258 
259 static ScoreboardStatsTool *scoreboard_stats_tool= NULL;
260 
261 static void enable(Session *, sql_var_t)
262 {
263  if (logging_stats)
264  {
265  if (sysvar_logging_stats_enabled)
266  {
267  logging_stats->enable();
268  }
269  else
270  {
271  logging_stats->disable();
272  }
273  }
274 }
275 
276 static int init(drizzled::module::Context &context)
277 {
278  const module::option_map &vm= context.getOptions();
279  sysvar_logging_stats_enabled= not vm.count("disable");
280 
281  logging_stats= new LoggingStats("logging_stats");
282  current_commands_tool= new CurrentCommandsTool(logging_stats);
283  cumulative_commands_tool= new CumulativeCommandsTool(logging_stats);
284  global_statements_tool= new GlobalStatementsTool(logging_stats);
285  session_statements_tool= new SessionStatementsTool(logging_stats);
286  session_status_tool= new StatusTool(logging_stats, true);
287  global_status_tool= new StatusTool(logging_stats, false);
288  cumulative_user_stats_tool= new CumulativeUserStatsTool(logging_stats);
289  scoreboard_stats_tool= new ScoreboardStatsTool(logging_stats);
290 
291  context.add(logging_stats);
292  context.add(current_commands_tool);
293  context.add(cumulative_commands_tool);
294  context.add(global_statements_tool);
295  context.add(session_statements_tool);
296  context.add(session_status_tool);
297  context.add(global_status_tool);
298  context.add(cumulative_user_stats_tool);
299  context.add(scoreboard_stats_tool);
300 
301  if (sysvar_logging_stats_enabled)
302  logging_stats->enable();
303 
304  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("max_user_count", sysvar_logging_stats_max_user_count));
305  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("bucket_count", sysvar_logging_stats_bucket_count));
306  context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("scoreboard_size", sysvar_logging_stats_scoreboard_size));
307  context.registerVariable(new sys_var_bool_ptr("enable", &sysvar_logging_stats_enabled, enable));
308 
309  return 0;
310 }
311 
312 
313 static void init_options(drizzled::module::option_context &context)
314 {
315  context("max-user-count",
316  po::value<max_user_count_constraint>(&sysvar_logging_stats_max_user_count)->default_value(500),
317  _("Max number of users that will be logged"));
318  context("bucket-count",
319  po::value<bucket_count_constraint>(&sysvar_logging_stats_bucket_count)->default_value(10),
320  _("Max number of range locks to use for Scoreboard"));
321  context("scoreboard-size",
322  po::value<scoreboard_size_constraint>(&sysvar_logging_stats_scoreboard_size)->default_value(2000),
323  _("Max number of concurrent sessions that will be logged"));
324  context("disable", _("Enable Logging Statistics Collection"));
325 }
326 
327 DRIZZLE_DECLARE_PLUGIN
328 {
329  DRIZZLE_VERSION_ID,
330  "logging_stats",
331  "0.1",
332  "Joseph Daly",
333  N_("Dictionaries for user statistics"),
334  PLUGIN_LICENSE_BSD,
335  init,
336  NULL,
337  init_options
338 }
339 DRIZZLE_DECLARE_PLUGIN_END;
ScoreboardSlot * findScoreboardSlotToLog(drizzled::Session *session)
Definition: scoreboard.cc:110
session_id_t getSessionId() const
Definition: session.h:644
TODO: Rename this file - func.h is stupid.
An Proxy Wrapper around boost::program_options::variables_map.
Definition: engine.cc:41
ScoreboardSlot * findOurScoreboardSlot(drizzled::Session *session)
Definition: scoreboard.cc:149