Added get_stats function.
Thanks to M0shTH8 for inspiration.
This commit is contained in:
parent
9df4f749fb
commit
0984a270db
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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()
|
||||||
|
13
tests.py
13
tests.py
@ -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
|
||||||
|
Reference in New Issue
Block a user