Drizzled Public API Documentation

stats_table.cc

00001 /*
00002  * Copyright (C) 2009, Padraig O'Sullivan
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *   * Redistributions of source code must retain the above copyright notice,
00009  *     this list of conditions and the following disclaimer.
00010  *   * Redistributions in binary form must reproduce the above copyright notice,
00011  *     this list of conditions and the following disclaimer in the documentation
00012  *     and/or other materials provided with the distribution.
00013  *   * Neither the name of Padraig O'Sullivan nor the names of its contributors
00014  *     may be used to endorse or promote products derived from this software
00015  *     without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00027  * THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <config.h>
00031 
00032 #include "stats_table.h"
00033 
00034 #include <drizzled/error.h>
00035 #include <libmemcached/server.h>
00036 
00037 #if !defined(HAVE_MEMCACHED_SERVER_FN)
00038 typedef memcached_server_function memcached_server_fn;
00039 #endif
00040 
00041 namespace drizzle_plugin
00042 {
00043 
00044 extern "C"
00045 memcached_return  server_function(const memcached_st *ptr,
00046                                   memcached_server_st *server,
00047                                   void *context);
00048 
00049 struct server_function_context
00050 {
00051   StatsTableTool::Generator* generator; 
00052   server_function_context(StatsTableTool::Generator *generator_arg)
00053     : generator(generator_arg)
00054   {}
00055 };
00056 
00057 
00058 extern "C"
00059 memcached_return  server_function(const memcached_st *memc,
00060                                   memcached_server_st *server,
00061                                   void *context)
00062 {
00063   server_function_context *ctx= static_cast<server_function_context *>(context);
00064 
00065   const char *server_name= memcached_server_name(*memc, *server);
00066   in_port_t server_port= memcached_server_port(*memc, *server);
00067 
00068   memcached_stat_st stats;
00069   memcached_return ret= memcached_stat_servername(&stats, NULL,
00070                                                   server_name, server_port);
00071 
00072   if (ret != MEMCACHED_SUCCESS)
00073   {
00074     my_printf_error(ER_UNKNOWN_ERROR, _("Unable get stats from memcached server %s.  Got error from memcached_stat_servername()."), MYF(0), server_name);
00075     return ret;
00076   }
00077 
00078   char **list= memcached_stat_get_keys((memcached_st *)memc, &stats, &ret);
00079   char **ptr= NULL;
00080  
00081   ctx->generator->push(server_name);
00082   ctx->generator->push(static_cast<uint64_t>(server_port));
00083 
00084   for (ptr= list; *ptr; ptr++)
00085   {
00086     char *value= memcached_stat_get_value((memcached_st *)memc, &stats, *ptr, &ret);
00087     ctx->generator->push(value);
00088     free(value);
00089   }
00090   free(list);
00091 
00092   return MEMCACHED_SUCCESS;
00093 }
00094 
00095 
00096 StatsTableTool::StatsTableTool() :
00097   plugin::TableFunction("DATA_DICTIONARY", "MEMCACHED_STATS")
00098 {
00099   add_field("NAME");
00100   add_field("PORT_NUMBER", plugin::TableFunction::NUMBER);
00101   add_field("PROCESS_ID", plugin::TableFunction::NUMBER);
00102   add_field("UPTIME", plugin::TableFunction::NUMBER);
00103   add_field("TIME", plugin::TableFunction::NUMBER);
00104   add_field("VERSION");
00105   add_field("POINTER_SIZE", plugin::TableFunction::NUMBER);
00106   add_field("RUSAGE_USER", plugin::TableFunction::NUMBER);
00107   add_field("RUSAGE_SYSTEM", plugin::TableFunction::NUMBER);
00108   add_field("CURRENT_ITEMS", plugin::TableFunction::NUMBER);
00109   add_field("TOTAL_ITEMS", plugin::TableFunction::NUMBER);
00110   add_field("BYTES",  plugin::TableFunction::NUMBER);
00111   add_field("CURRENT_CONNECTIONS", plugin::TableFunction::NUMBER);
00112   add_field("TOTAL_CONNECTIONS", plugin::TableFunction::NUMBER);
00113   add_field("CONNECTION_STRUCTURES", plugin::TableFunction::NUMBER);
00114   add_field("GETS", plugin::TableFunction::NUMBER);
00115   add_field("SETS", plugin::TableFunction::NUMBER);
00116   add_field("HITS", plugin::TableFunction::NUMBER);
00117   add_field("MISSES", plugin::TableFunction::NUMBER); 
00118   add_field("EVICTIONS", plugin::TableFunction::NUMBER);
00119   add_field("BYTES_READ", plugin::TableFunction::NUMBER);
00120   add_field("BYTES_WRITTEN", plugin::TableFunction::NUMBER);
00121   add_field("LIMIT_MAXBYTES", plugin::TableFunction::NUMBER);
00122   add_field("THREADS", plugin::TableFunction::NUMBER);
00123 }
00124 
00125 
00126 StatsTableTool::Generator::Generator(drizzled::Field **arg) :
00127   plugin::TableFunction::Generator(arg)
00128 {
00129   /* This will be set to the real number if we initialize properly below */
00130   number_of_hosts= 0;
00131   
00132   host_number= 0;
00133 
00134   /* set to NULL if we are not able to init we dont want to call delete on this */
00135   memc= NULL;
00136 
00137   drizzled::sys_var *servers_var= drizzled::find_sys_var("memcached_stats_servers");
00138   assert(servers_var != NULL);
00139 
00140   const string servers_string(static_cast<char *>(servers_var.value_ptr(NULL, 0, NULL)));
00141 
00142   if (servers_string.empty())
00143   {
00144     my_printf_error(ER_UNKNOWN_ERROR, _("No value in MEMCACHED_STATS_SERVERS variable."), MYF(0));
00145     return; 
00146   }
00147 
00148   memc= memcached_create(NULL);
00149   if (memc == NULL)
00150   {
00151     my_printf_error(ER_UNKNOWN_ERROR, _("Unable to create memcached struct.  Got error from memcached_create()."), MYF(0));
00152     return;
00153   }
00154 
00155   memcached_server_st *tmp_serv=
00156     memcached_servers_parse(servers_string.c_str());
00157   if (tmp_serv == NULL)
00158   {
00159     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());
00160     return;
00161   }
00162 
00163   memcached_server_push(memc, tmp_serv);
00164   memcached_server_list_free(tmp_serv);
00165 
00166   number_of_hosts= memc->number_of_hosts;  
00167 }
00168 
00169 
00170 StatsTableTool::Generator::~Generator()
00171 {
00172   if (memc != NULL)
00173   {
00174     memcached_free(memc);
00175   }
00176 }
00177 
00178 
00179 bool StatsTableTool::Generator::populate()
00180 {
00181   if (host_number == number_of_hosts)
00182   {
00183     return false;
00184   }
00185 
00186   server_function_context context(this);
00187 
00188   memcached_server_function callbacks[1];
00189   callbacks[0]= server_function;
00190 
00191   unsigned int iferror; 
00192   iferror= (*callbacks[0])(memc, &memc->servers[host_number], (void *)&context); 
00193 
00194   if (iferror)
00195   {
00196     return false;
00197   }
00198 
00199   host_number++;
00200  
00201   return true;
00202 }
00203 
00204 } /* namespace drizzle_plugin */