~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/memcached_stats/stats_table.cc

  • Committer: Stewart Smith
  • Date: 2010-02-15 01:56:32 UTC
  • mto: (1273.13.96 build)
  • mto: This revision was merged to the branch mainline in revision 1308.
  • Revision ID: stewart@flamingspork.com-20100215015632-pm7lnxfq5j5uh8kj
move DATABASE() to function plugin. modify parser so that it looks for a function named 'database' when DATABASE() is called. Special case still needed in parser due to hilarity of not-really-reserved words.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
 
1
/* 
2
2
 * Copyright (c) 2009, Padraig O'Sullivan
3
3
 * All rights reserved.
4
4
 *
28
28
 */
29
29
 
30
30
#include "config.h"
 
31
#include "drizzled/session.h"
 
32
#include "drizzled/show.h"
 
33
#include "drizzled/error.h"
31
34
 
32
35
#include "stats_table.h"
33
 
 
34
 
#include "drizzled/error.h"
35
 
#include <libmemcached/server.h>
 
36
#include "sysvar_holder.h"
 
37
 
 
38
#include <libmemcached/memcached.h>
 
39
 
 
40
#include <string>
 
41
#include <vector>
 
42
 
 
43
using namespace std;
 
44
using namespace drizzled;
36
45
 
37
46
#if !defined(HAVE_MEMCACHED_SERVER_FN)
38
47
typedef memcached_server_function memcached_server_fn;
39
48
#endif
40
49
 
41
 
namespace drizzle_plugin
42
 
{
43
 
 
44
50
extern "C"
45
51
memcached_return  server_function(const memcached_st *ptr,
46
52
                                  memcached_server_st *server,
48
54
 
49
55
struct server_function_context
50
56
{
51
 
  StatsTableTool::Generator* generator; 
52
 
  server_function_context(StatsTableTool::Generator *generator_arg)
53
 
    : generator(generator_arg)
 
57
  Table* table;
 
58
  plugin::InfoSchemaTable *schema_table;
 
59
  server_function_context(Table *table_arg,
 
60
                          plugin::InfoSchemaTable *schema_table_arg)
 
61
    : table(table_arg), schema_table(schema_table_arg)
54
62
  {}
55
63
};
56
64
 
57
 
 
58
65
extern "C"
59
 
memcached_return  server_function(const memcached_st *memc,
 
66
memcached_return  server_function(const memcached_st *const_memc,
60
67
                                  memcached_server_st *server,
61
68
                                  void *context)
62
69
{
63
70
  server_function_context *ctx= static_cast<server_function_context *>(context);
64
 
 
65
 
  const char *server_name= memcached_server_name(*memc, *server);
66
 
  in_port_t server_port= memcached_server_port(*memc, *server);
 
71
  const CHARSET_INFO * const scs= system_charset_info;
 
72
  memcached_st memc_stack;
 
73
  memcached_st *memc;
 
74
 
 
75
  memc= memcached_clone(&memc_stack, const_memc);
 
76
 
 
77
  if (not memc)
 
78
  {
 
79
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable to allocate memory for memcached_clone()."), MYF(0));
 
80
    return MEMCACHED_FAILURE;
 
81
  }
 
82
    
 
83
  char *server_name= memcached_server_name(memc, *server);
 
84
  in_port_t server_port= memcached_server_port(memc, *server);
67
85
 
68
86
  memcached_stat_st stats;
69
87
  memcached_return ret= memcached_stat_servername(&stats, NULL,
70
88
                                                  server_name, server_port);
71
 
 
72
89
  if (ret != MEMCACHED_SUCCESS)
73
90
  {
74
91
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable get stats from memcached server %s.  Got error from memcached_stat_servername()."), MYF(0), server_name);
 
92
    memcached_free(memc);
75
93
    return ret;
76
94
  }
77
95
 
78
 
  char **list= memcached_stat_get_keys((memcached_st *)memc, &stats, &ret);
 
96
  char **list= memcached_stat_get_keys(memc, &stats, &ret);
79
97
  char **ptr= NULL;
80
 
 
81
 
  ctx->generator->push(server_name);
82
 
  ctx->generator->push(static_cast<uint64_t>(server_port));
83
 
 
 
98
 
 
99
  ctx->table->setWriteSet(0);
 
100
  ctx->table->setWriteSet(1);
 
101
 
 
102
  ctx->table->field[0]->store(server_name, strlen(server_name), scs);
 
103
  ctx->table->field[1]->store(server_port);
 
104
 
 
105
  uint32_t col= 2;
84
106
  for (ptr= list; *ptr; ptr++)
85
107
  {
86
 
    char *value= memcached_stat_get_value((memcached_st *)memc, &stats, *ptr, &ret);
87
 
    ctx->generator->push(value);
 
108
    char *value= memcached_stat_get_value(memc, &stats, *ptr, &ret);
 
109
 
 
110
    ctx->table->setWriteSet(col);
 
111
    ctx->table->field[col]->store(value,
 
112
                                  strlen(value),
 
113
                                  scs);
 
114
    col++;
88
115
    free(value);
89
116
  }
90
117
  free(list);
 
118
  /* store the actual record now */
 
119
  ctx->schema_table->addRow(ctx->table->record[0], ctx->table->s->reclength);
 
120
  memcached_free(memc);
91
121
 
92
122
  return MEMCACHED_SUCCESS;
93
123
}
94
124
 
95
 
 
96
 
StatsTableTool::StatsTableTool() :
97
 
  plugin::TableFunction("DATA_DICTIONARY", "MEMCACHED_STATS")
98
 
{
99
 
  add_field("NAME");
100
 
  add_field("PORT_NUMBER", plugin::TableFunction::NUMBER);
101
 
  add_field("PROCESS_ID", plugin::TableFunction::NUMBER);
102
 
  add_field("UPTIME", plugin::TableFunction::NUMBER);
103
 
  add_field("TIME", plugin::TableFunction::NUMBER);
104
 
  add_field("VERSION");
105
 
  add_field("POINTER_SIZE", plugin::TableFunction::NUMBER);
106
 
  add_field("RUSAGE_USER", plugin::TableFunction::NUMBER);
107
 
  add_field("RUSAGE_SYSTEM", plugin::TableFunction::NUMBER);
108
 
  add_field("CURRENT_ITEMS", plugin::TableFunction::NUMBER);
109
 
  add_field("TOTAL_ITEMS", plugin::TableFunction::NUMBER);
110
 
  add_field("BYTES",  plugin::TableFunction::NUMBER);
111
 
  add_field("CURRENT_CONNECTIONS", plugin::TableFunction::NUMBER);
112
 
  add_field("TOTAL_CONNECTIONS", plugin::TableFunction::NUMBER);
113
 
  add_field("CONNECTION_STRUCTURES", plugin::TableFunction::NUMBER);
114
 
  add_field("GETS", plugin::TableFunction::NUMBER);
115
 
  add_field("SETS", plugin::TableFunction::NUMBER);
116
 
  add_field("HITS", plugin::TableFunction::NUMBER);
117
 
  add_field("MISSES", plugin::TableFunction::NUMBER); 
118
 
  add_field("EVICTIONS", plugin::TableFunction::NUMBER);
119
 
  add_field("BYTES_READ", plugin::TableFunction::NUMBER);
120
 
  add_field("BYTES_WRITTEN", plugin::TableFunction::NUMBER);
121
 
  add_field("LIMIT_MAXBYTES", plugin::TableFunction::NUMBER);
122
 
  add_field("THREADS", plugin::TableFunction::NUMBER);
123
 
}
124
 
 
125
 
 
126
 
StatsTableTool::Generator::Generator(drizzled::Field **arg) :
127
 
  plugin::TableFunction::Generator(arg)
128
 
{
129
 
  /* This will be set to the real number if we initialize properly below */
130
 
  number_of_hosts= 0;
131
 
  
132
 
  host_number= 0;
133
 
 
134
 
  /* set to NULL if we are not able to init we dont want to call delete on this */
135
 
  memc= NULL;
136
 
 
137
 
  drizzled::sys_var *servers_var= drizzled::find_sys_var("memcached_stats_servers");
138
 
  assert(servers_var != NULL);
139
 
 
140
 
  const string servers_string(static_cast<char *>(servers_var.value_ptr(NULL, 0, NULL)));
141
 
 
 
125
int MemcachedStatsISMethods::fillTable(Session *,
 
126
                                       Table *table,
 
127
                                       plugin::InfoSchemaTable *schema_table)
 
128
{
 
129
  SysvarHolder &sysvar_holder= SysvarHolder::singleton();
 
130
  const string servers_string= sysvar_holder.getServersString();
 
131
 
 
132
  table->restoreRecordAsDefault();
142
133
  if (servers_string.empty())
143
134
  {
144
135
    my_printf_error(ER_UNKNOWN_ERROR, _("No value in MEMCACHED_STATS_SERVERS variable."), MYF(0));
145
 
    return; 
146
 
  }
 
136
    return 1;
 
137
  } 
 
138
 
147
139
 
148
 
  memc= memcached_create(NULL);
 
140
  memcached_st *memc= memcached_create(NULL);
149
141
  if (memc == NULL)
150
142
  {
151
143
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable to create memcached struct.  Got error from memcached_create()."), MYF(0));
152
 
    return;
 
144
    return 1;
153
145
  }
154
146
 
155
147
  memcached_server_st *tmp_serv=
157
149
  if (tmp_serv == NULL)
158
150
  {
159
151
    my_printf_error(ER_UNKNOWN_ERROR, _("Unable to create memcached server list.  Got error from memcached_servers_parse(%s)."), MYF(0), servers_string.c_str());
160
 
    return;
 
152
    memcached_free(memc);
 
153
    return 1; 
161
154
  }
162
155
 
163
156
  memcached_server_push(memc, tmp_serv);
164
157
  memcached_server_list_free(tmp_serv);
165
158
 
166
 
  number_of_hosts= memc->number_of_hosts;  
167
 
}
168
 
 
169
 
 
170
 
StatsTableTool::Generator::~Generator()
171
 
{
172
 
  if (memc != NULL)
173
 
  {
174
 
    memcached_free(memc);
175
 
  }
176
 
}
177
 
 
178
 
 
179
 
bool StatsTableTool::Generator::populate()
180
 
{
181
 
  if (host_number == number_of_hosts)
182
 
  {
183
 
    return false;
184
 
  }
185
 
 
186
 
  server_function_context context(this);
187
 
 
188
 
  memcached_server_function callbacks[1];
 
159
  memcached_server_fn callbacks[1];
 
160
 
189
161
  callbacks[0]= server_function;
190
 
 
191
 
  unsigned int iferror; 
192
 
  iferror= (*callbacks[0])(memc, &memc->servers[host_number], (void *)&context); 
193
 
 
194
 
  if (iferror)
195
 
  {
196
 
    return false;
197
 
  }
198
 
 
199
 
  host_number++;
200
 
 
201
 
  return true;
202
 
}
203
 
 
204
 
} /* namespace drizzle_plugin */
 
162
  server_function_context context(table, schema_table);
 
163
 
 
164
  memcached_server_cursor(memc, callbacks, &context, 1);
 
165
 
 
166
  memcached_free(memc);
 
167
 
 
168
  return 0;
 
169
}
 
170
 
 
171
bool createMemcachedStatsColumns(vector<const plugin::ColumnInfo *> &cols)
 
172
{
 
173
  /*
 
174
   * Create each column for the memcached stats table.
 
175
   */
 
176
  const plugin::ColumnInfo *name_col= new(std::nothrow) plugin::ColumnInfo("NAME",
 
177
                                                           32,
 
178
                                                           DRIZZLE_TYPE_VARCHAR,
 
179
                                                           0,
 
180
                                                           0,
 
181
                                                           "Name");
 
182
  if (! name_col)
 
183
  {
 
184
    return true;
 
185
  }
 
186
 
 
187
  const plugin::ColumnInfo *port= new(std::nothrow) plugin::ColumnInfo("PORT_NUMBER",
 
188
                                                       4,
 
189
                                                       DRIZZLE_TYPE_LONGLONG,
 
190
                                                       0,
 
191
                                                       0, 
 
192
                                                       "Port Number");
 
193
  if (! port)
 
194
  {
 
195
    return true;
 
196
  }
 
197
 
 
198
  const plugin::ColumnInfo *pid= new(std::nothrow) plugin::ColumnInfo("PROCESS_ID",
 
199
                                                      4,
 
200
                                                      DRIZZLE_TYPE_LONGLONG,
 
201
                                                      0,
 
202
                                                      0, 
 
203
                                                      "Process ID");
 
204
  if (! pid)
 
205
  {
 
206
    return true;
 
207
  }
 
208
 
 
209
  const plugin::ColumnInfo *uptime= new(std::nothrow) plugin::ColumnInfo("UPTIME",
 
210
                                                         4,
 
211
                                                         DRIZZLE_TYPE_LONGLONG,
 
212
                                                         0,
 
213
                                                         0, 
 
214
                                                         "Uptime");
 
215
  if (! uptime)
 
216
  {
 
217
    return true;
 
218
  }
 
219
 
 
220
  const plugin::ColumnInfo *time= new(std::nothrow) plugin::ColumnInfo("TIME",
 
221
                                                       4,
 
222
                                                       DRIZZLE_TYPE_LONGLONG,
 
223
                                                       0,
 
224
                                                       0, 
 
225
                                                       "Time");
 
226
  if (! time)
 
227
  {
 
228
    return true;
 
229
  }
 
230
 
 
231
  const plugin::ColumnInfo *version= new(std::nothrow) plugin::ColumnInfo("VERSION",
 
232
                                                          8,
 
233
                                                          DRIZZLE_TYPE_VARCHAR,
 
234
                                                          0,
 
235
                                                          0,
 
236
                                                          "Version");
 
237
  if (! version)
 
238
  {
 
239
    return true;
 
240
  }
 
241
 
 
242
  const plugin::ColumnInfo *ptr_size= new(std::nothrow) plugin::ColumnInfo("POINTER_SIZE",
 
243
                                                           4,
 
244
                                                           DRIZZLE_TYPE_LONGLONG,
 
245
                                                           0,
 
246
                                                           0, 
 
247
                                                           "Pointer Size");
 
248
  if (! ptr_size)
 
249
  {
 
250
    return true;
 
251
  }
 
252
 
 
253
  const plugin::ColumnInfo *r_user= new(std::nothrow) plugin::ColumnInfo("RUSAGE_USER",
 
254
                                                         4,
 
255
                                                         DRIZZLE_TYPE_LONGLONG,
 
256
                                                         0,
 
257
                                                         0, 
 
258
                                                         "rusage user");
 
259
  if (! r_user)
 
260
  {
 
261
    return true;
 
262
  }
 
263
 
 
264
  const plugin::ColumnInfo *r_sys= new(std::nothrow) plugin::ColumnInfo("RUSAGE_SYSTEM",
 
265
                                                        4,
 
266
                                                        DRIZZLE_TYPE_LONGLONG,
 
267
                                                        0,
 
268
                                                        0, 
 
269
                                                        "rusage system");
 
270
  if (! r_sys)
 
271
  {
 
272
    return true;
 
273
  }
 
274
  const plugin::ColumnInfo *curr_items= new(std::nothrow) plugin::ColumnInfo("CURRENT_ITEMS",
 
275
                                                             4,
 
276
                                                             DRIZZLE_TYPE_LONGLONG,
 
277
                                                             0,
 
278
                                                             0, 
 
279
                                                             "Current Items");
 
280
  if (! curr_items)
 
281
  {
 
282
    return true;
 
283
  }
 
284
 
 
285
  const plugin::ColumnInfo *total_items= new(std::nothrow) plugin::ColumnInfo("TOTAL_ITEMS",
 
286
                                                              4,
 
287
                                                              DRIZZLE_TYPE_LONGLONG,
 
288
                                                              0,
 
289
                                                              0,
 
290
                                                              "Total Items");
 
291
  if (! total_items)
 
292
  {
 
293
    return true;
 
294
  }
 
295
 
 
296
  const plugin::ColumnInfo *bytes= new(std::nothrow) plugin::ColumnInfo("BYTES",
 
297
                                                        4,
 
298
                                                        DRIZZLE_TYPE_LONGLONG,
 
299
                                                        0,
 
300
                                                        0,
 
301
                                                        "Bytes");
 
302
  if (! bytes)
 
303
  {
 
304
    return true;
 
305
  }
 
306
 
 
307
  const plugin::ColumnInfo *curr_cons= new(std::nothrow) plugin::ColumnInfo("CURRENT_CONNECTIONS",
 
308
                                                            4,
 
309
                                                            DRIZZLE_TYPE_LONGLONG,
 
310
                                                            0,
 
311
                                                            0,
 
312
                                                            "Current Connections");
 
313
  if (! curr_cons)
 
314
  {
 
315
    return true;
 
316
  }
 
317
 
 
318
  const plugin::ColumnInfo *total_cons= new(std::nothrow) plugin::ColumnInfo("TOTAL_CONNECTIONS",
 
319
                                                             4,
 
320
                                                             DRIZZLE_TYPE_LONGLONG,
 
321
                                                             0,
 
322
                                                             0,
 
323
                                                             "Total Connections");
 
324
  if (! total_cons)
 
325
  {
 
326
    return true;
 
327
  }
 
328
 
 
329
  const plugin::ColumnInfo *con_structs= new(std::nothrow) plugin::ColumnInfo("CONNECTION_STRUCTURES",
 
330
                                                              4,
 
331
                                                              DRIZZLE_TYPE_LONGLONG,
 
332
                                                              0,
 
333
                                                              0,
 
334
                                                              "Connection Structures");
 
335
  if (! con_structs)
 
336
  {
 
337
    return true;
 
338
  }
 
339
 
 
340
  const plugin::ColumnInfo *cmd_gets= new(std::nothrow) plugin::ColumnInfo("GETS",
 
341
                                                           4,
 
342
                                                           DRIZZLE_TYPE_LONGLONG,
 
343
                                                           0,
 
344
                                                           0,
 
345
                                                           "Gets");
 
346
  if (! cmd_gets)
 
347
  {
 
348
    return true;
 
349
  }
 
350
 
 
351
  const plugin::ColumnInfo *cmd_sets= new(std::nothrow) plugin::ColumnInfo("SETS",
 
352
                                                           4,
 
353
                                                           DRIZZLE_TYPE_LONGLONG,
 
354
                                                           0,
 
355
                                                           0,
 
356
                                                           "Sets");
 
357
  if (! cmd_sets)
 
358
  {
 
359
    return true;
 
360
  }
 
361
 
 
362
  const plugin::ColumnInfo *hits= new(std::nothrow) plugin::ColumnInfo("HITS",
 
363
                                                       4,
 
364
                                                       DRIZZLE_TYPE_LONGLONG,
 
365
                                                       0,
 
366
                                                       0,
 
367
                                                       "Hits");
 
368
  if (! hits)
 
369
  {
 
370
    return true;
 
371
  }
 
372
 
 
373
  const plugin::ColumnInfo *misses= new(std::nothrow) plugin::ColumnInfo("MISSES",
 
374
                                                         4,
 
375
                                                         DRIZZLE_TYPE_LONGLONG,
 
376
                                                         0,
 
377
                                                         0,
 
378
                                                         "Misses");
 
379
  if (! misses)
 
380
  {
 
381
    return true;
 
382
  }
 
383
 
 
384
  const plugin::ColumnInfo *evicts= new(std::nothrow) plugin::ColumnInfo("EVICTIONS",
 
385
                                                         4,
 
386
                                                         DRIZZLE_TYPE_LONGLONG,
 
387
                                                         0,
 
388
                                                         0,
 
389
                                                         "Evictions");
 
390
  if (! evicts)
 
391
  {
 
392
    return true;
 
393
  }
 
394
 
 
395
  const plugin::ColumnInfo *bytes_read= new(std::nothrow) plugin::ColumnInfo("BYTES_READ",
 
396
                                                             4,
 
397
                                                             DRIZZLE_TYPE_LONGLONG,
 
398
                                                             0,
 
399
                                                             0,
 
400
                                                             "bytes read");
 
401
  if (! bytes_read)
 
402
  {
 
403
    return true;
 
404
  }
 
405
 
 
406
  const plugin::ColumnInfo *bytes_written= new(std::nothrow) plugin::ColumnInfo("BYTES_WRITTEN",
 
407
                                                                4,
 
408
                                                                DRIZZLE_TYPE_LONGLONG,
 
409
                                                                0,
 
410
                                                                0,
 
411
                                                                "bytes written");
 
412
  if (! bytes_written)
 
413
  {
 
414
    return true;
 
415
  }
 
416
 
 
417
  const plugin::ColumnInfo *lim_max_bytes= new(std::nothrow) plugin::ColumnInfo("LIMIT_MAXBYTES",
 
418
                                                                4,
 
419
                                                                DRIZZLE_TYPE_LONGLONG,
 
420
                                                                0,
 
421
                                                                0,
 
422
                                                                "limit maxbytes");
 
423
  if (! lim_max_bytes)
 
424
  {
 
425
    return true;
 
426
  }
 
427
 
 
428
  const plugin::ColumnInfo *threads= new(std::nothrow) plugin::ColumnInfo("THREADS",
 
429
                                                          4,
 
430
                                                          DRIZZLE_TYPE_LONGLONG,
 
431
                                                          0,
 
432
                                                          0,
 
433
                                                          "Threads");
 
434
  if (! threads)
 
435
  {
 
436
    return true;
 
437
  }
 
438
 
 
439
  cols.push_back(name_col);
 
440
  cols.push_back(port);
 
441
  cols.push_back(pid);
 
442
  cols.push_back(uptime);
 
443
  cols.push_back(time);
 
444
  cols.push_back(version);
 
445
  cols.push_back(ptr_size);
 
446
  cols.push_back(r_user);
 
447
  cols.push_back(r_sys);
 
448
  cols.push_back(curr_items);
 
449
  cols.push_back(total_items);
 
450
  cols.push_back(bytes);
 
451
  cols.push_back(curr_cons);
 
452
  cols.push_back(total_cons);
 
453
  cols.push_back(con_structs);
 
454
  cols.push_back(cmd_gets);
 
455
  cols.push_back(cmd_sets);
 
456
  cols.push_back(hits);
 
457
  cols.push_back(misses);
 
458
  cols.push_back(evicts);
 
459
  cols.push_back(bytes_read);
 
460
  cols.push_back(bytes_written);
 
461
  cols.push_back(lim_max_bytes);
 
462
  cols.push_back(threads);
 
463
 
 
464
  return false;
 
465
}
 
466
 
 
467
class DeleteMemcachedCols
 
468
{
 
469
public:
 
470
  template<typename T>
 
471
  inline void operator()(const T *ptr) const
 
472
  {
 
473
    delete ptr;
 
474
  }
 
475
};
 
476
 
 
477
void clearMemcachedColumns(vector<const plugin::ColumnInfo *> &cols)
 
478
{
 
479
  for_each(cols.begin(), cols.end(), DeleteMemcachedCols());
 
480
  cols.clear();
 
481
}