~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/memcached_stats/stats_table.cc

  • Committer: Monty Taylor
  • Date: 2010-01-02 05:11:55 UTC
  • mto: (1259.3.1 build)
  • mto: This revision was merged to the branch mainline in revision 1262.
  • Revision ID: mordred@inaugust.com-20100102051155-akdm8w5rr6xwzayu
pandora-build - proper detection of memcached.

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