Added get_stats function.

Thanks to M0shTH8 for inspiration.
This commit is contained in:
lericson 2009-10-19 14:09:08 +02:00
parent 9df4f749fb
commit 0984a270db
4 changed files with 111 additions and 1 deletions

View File

@ -742,6 +742,98 @@ error:
return NULL; return NULL;
} }
static PyObject *PylibMC_Client_get_stats(PylibMC_Client *self, PyObject *args) {
memcached_stat_st *stats;
memcached_return rc;
char *mc_args;
PyObject *retval;
Py_ssize_t nservers, serveridx;
memcached_server_st *servers;
mc_args = NULL;
if (!PyArg_ParseTuple(args, "|s", &mc_args))
return NULL;
stats = memcached_stat(self->mc, mc_args, &rc);
if (rc != MEMCACHED_SUCCESS)
return PylibMC_ErrFromMemcached(self, "get_stats", rc);
nservers = (Py_ssize_t)memcached_server_count(self->mc);
servers = memcached_server_list(self->mc);
retval = PyList_New(nservers);
/** retval contents:
* [('<addr, 127.0.0.1:11211> (<num, 1>),
* {stat: stat, stat: stat}),
* (str, dict),
* (str, dict)]
*/
for (serveridx = 0; serveridx < nservers; serveridx++) {
memcached_server_st *server;
memcached_stat_st *stat;
memcached_return rc;
PyObject *desc, *val;
char **stat_keys = NULL;
char **curr_key;
server = servers + serveridx;
stat = stats + serveridx;
val = PyDict_New();
if (val == NULL)
goto error;
stat_keys = memcached_stat_get_keys(self->mc, stat, &rc);
if (rc != MEMCACHED_SUCCESS)
goto loop_error;
for (curr_key = stat_keys; *curr_key; curr_key++) {
PyObject *curr_value;
char *mc_val;
memcached_return get_val_rc;
int fail;
mc_val = memcached_stat_get_value(self->mc, stat, *curr_key,
&get_val_rc);
if (get_val_rc != MEMCACHED_SUCCESS) {
PylibMC_ErrFromMemcached(self, "get_stats val", get_val_rc);
goto loop_error;
}
curr_value = PyString_FromString(mc_val);
free(mc_val);
if (curr_value == NULL)
goto loop_error;
fail = PyDict_SetItemString(val, *curr_key, curr_value);
Py_DECREF(curr_value);
if (fail)
goto loop_error;
}
free(stat_keys);
desc = PyString_FromFormat("%s:%d (%u)",
server->hostname, server->port,
(unsigned int)serveridx);
PyList_SET_ITEM(retval, serveridx, Py_BuildValue("NN", desc, val));
continue;
loop_error:
free(stat_keys);
Py_DECREF(val);
goto error;
}
free(stats);
return retval;
error:
Py_DECREF(retval);
free(stats);
return NULL;
}
static PyObject *PylibMC_Client_flush_all(PylibMC_Client *self, static PyObject *PylibMC_Client_flush_all(PylibMC_Client *self,
PyObject *args, PyObject *kwds) { PyObject *args, PyObject *kwds) {
memcached_return rc; memcached_return rc;
@ -915,6 +1007,8 @@ Oh, and: plankton.\n");
PylibMCExc_MemcachedError = PyErr_NewException( PylibMCExc_MemcachedError = PyErr_NewException(
"_pylibmc.MemcachedError", NULL, NULL); "_pylibmc.MemcachedError", NULL, NULL);
PyModule_AddObject(module, "MemcachedError",
(PyObject *)PylibMCExc_MemcachedError);
PyModule_AddStringConstant(module, "__version__", PYLIBMC_VERSION); PyModule_AddStringConstant(module, "__version__", PYLIBMC_VERSION);

View File

@ -153,6 +153,7 @@ static PyObject *PylibMC_Client_set_multi(PylibMC_Client *, PyObject *, PyObject
static PyObject *PylibMC_Client_delete_multi(PylibMC_Client *, PyObject *, PyObject *); static PyObject *PylibMC_Client_delete_multi(PylibMC_Client *, PyObject *, PyObject *);
static PyObject *PylibMC_Client_get_behaviors(PylibMC_Client *); static PyObject *PylibMC_Client_get_behaviors(PylibMC_Client *);
static PyObject *PylibMC_Client_set_behaviors(PylibMC_Client *, PyObject *); static PyObject *PylibMC_Client_set_behaviors(PylibMC_Client *, PyObject *);
static PyObject *PylibMC_Client_get_stats(PylibMC_Client *, PyObject *);
static PyObject *PylibMC_Client_flush_all(PylibMC_Client *, PyObject *, PyObject *); static PyObject *PylibMC_Client_flush_all(PylibMC_Client *, PyObject *, PyObject *);
static PyObject *PylibMC_Client_disconnect_all(PylibMC_Client *); static PyObject *PylibMC_Client_disconnect_all(PylibMC_Client *);
static PyObject *PylibMC_Client_clone(PylibMC_Client *); static PyObject *PylibMC_Client_clone(PylibMC_Client *);
@ -194,6 +195,8 @@ static PyMethodDef PylibMC_ClientType_methods[] = {
"Get behaviors dict."}, "Get behaviors dict."},
{"set_behaviors", (PyCFunction)PylibMC_Client_set_behaviors, METH_O, {"set_behaviors", (PyCFunction)PylibMC_Client_set_behaviors, METH_O,
"Set behaviors dict."}, "Set behaviors dict."},
{"get_stats", (PyCFunction)PylibMC_Client_get_stats,
METH_VARARGS, "Retrieve statistics from all memcached servers."},
{"flush_all", (PyCFunction)PylibMC_Client_flush_all, {"flush_all", (PyCFunction)PylibMC_Client_flush_all,
METH_VARARGS|METH_KEYWORDS, "Flush all data on all servers."}, METH_VARARGS|METH_KEYWORDS, "Flush all data on all servers."},
{"disconnect_all", (PyCFunction)PylibMC_Client_disconnect_all, METH_NOARGS, {"disconnect_all", (PyCFunction)PylibMC_Client_disconnect_all, METH_NOARGS,

View File

@ -184,7 +184,7 @@ class ThreadMappedPool(dict):
Creates a new client based on the master client if none exists for the Creates a new client based on the master client if none exists for the
current thread. current thread.
""" """
key = threading.current_thread().name key = threading.current_thread().ident
mc = self.pop(key, None) mc = self.pop(key, None)
if mc is None: if mc is None:
mc = self.master.clone() mc = self.master.clone()

View File

@ -86,6 +86,19 @@ Traceback (most recent call last):
... ...
TypeError: key must be an instance of str TypeError: key must be an instance of str
Getting stats is fun!
>>> for (svr, stats) in c.get_stats():
... print svr
... ks = stats.keys()
... while ks:
... cks, ks = ks[:6], ks[6:]
... print ", ".join(cks)
localhost:11211 (0)
pid, total_items, uptime, version, limit_maxbytes, rusage_user
bytes_read, rusage_system, cmd_get, curr_connections, threads, total_connections
cmd_set, curr_items, get_misses, evictions, bytes, connection_structures
bytes_written, time, pointer_size, get_hits
Also test some flush all. Also test some flush all.
>>> c.set("hi", "guys") >>> c.set("hi", "guys")
True True