diff --git a/core/snmp.c b/core/snmp.c index 5f1aa905..fd3d861f 100644 --- a/core/snmp.c +++ b/core/snmp.c @@ -249,11 +249,14 @@ static uint64_t get_uwsgi_snmp_value(uint64_t val, uint8_t * oid_t) { static uint64_t get_uwsgi_custom_snmp_value(uint64_t val, uint8_t * oid_t) { val--; + uwsgi_wlock(uwsgi.snmp_lock); if (uwsgi.shared->snmp_value[val].type) { *oid_t = uwsgi.shared->snmp_value[val].type; + uwsgi_rwunlock(uwsgi.snmp_lock); return uwsgi.shared->snmp_value[val].val; } + uwsgi_rwunlock(uwsgi.snmp_lock); *oid_t = SNMP_NULL; return 0; } diff --git a/core/uwsgi.c b/core/uwsgi.c index df778296..0d3fe442 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -2172,6 +2172,10 @@ int uwsgi_start(void *v_argv) { uwsgi.sa_lock = uwsgi_rwlock_init("sharedarea"); } +#ifdef UWSGI_SNMP + uwsgi.snmp_lock = uwsgi_lock_init("snmp"); +#endif + // setup queue if (uwsgi.queue_size > 0) { uwsgi_init_queue(); diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 644aba1a..bd48bca0 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -3924,7 +3924,7 @@ void init_uwsgi_module_sharedarea(PyObject * current_uwsgi_module) { } #ifdef UWSGI_SNMP -PyObject *py_snmp_counter32(PyObject * self, PyObject * args) { +PyObject *py_snmp_set_counter32(PyObject * self, PyObject * args) { uint8_t oid_num; uint32_t oid_val = 0; @@ -3936,9 +3936,15 @@ PyObject *py_snmp_counter32(PyObject * self, PyObject * args) { if (oid_num > 100 || oid_num < 1) goto clear; + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32; uwsgi.shared->snmp_value[oid_num - 1].val = oid_val; + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + Py_INCREF(Py_True); return Py_True; @@ -3948,7 +3954,7 @@ clear: return Py_None; } -PyObject *py_snmp_counter64(PyObject * self, PyObject * args) { +PyObject *py_snmp_set_counter64(PyObject * self, PyObject * args) { uint8_t oid_num; uint64_t oid_val = 0; @@ -3960,9 +3966,15 @@ PyObject *py_snmp_counter64(PyObject * self, PyObject * args) { if (oid_num > 100 || oid_num < 1) goto clear; + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64; uwsgi.shared->snmp_value[oid_num - 1].val = oid_val; + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + Py_INCREF(Py_True); return Py_True; @@ -3972,7 +3984,7 @@ clear: return Py_None; } -PyObject *py_snmp_gauge(PyObject * self, PyObject * args) { +PyObject *py_snmp_set_gauge(PyObject * self, PyObject * args) { uint8_t oid_num; uint32_t oid_val = 0; @@ -3984,9 +3996,15 @@ PyObject *py_snmp_gauge(PyObject * self, PyObject * args) { if (oid_num > 100 || oid_num < 1) goto clear; + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE; uwsgi.shared->snmp_value[oid_num - 1].val = oid_val; + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + Py_INCREF(Py_True); return Py_True; @@ -3996,7 +4014,205 @@ clear: return Py_None; } -PyObject *py_snmp_community(PyObject * self, PyObject * args) { +PyObject *py_snmp_incr_counter32(PyObject * self, PyObject * args) { + + uint8_t oid_num; + uint32_t oid_val = 1; + + if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter32", &oid_num, &oid_val)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "b:snmp_incr_counter32", &oid_num)) { + return NULL; + } + } + + if (oid_num > 100 || oid_num < 1) + goto clear; + + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32; + uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val; + + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + + Py_INCREF(Py_True); + return Py_True; + +clear: + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_snmp_incr_counter64(PyObject * self, PyObject * args) { + + uint8_t oid_num; + uint64_t oid_val = 1; + + if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter64", &oid_num, &oid_val)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "b:snmp_incr_counter64", &oid_num)) { + return NULL; + } + } + + if (oid_num > 100 || oid_num < 1) + goto clear; + + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64; + uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val; + + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + + Py_INCREF(Py_True); + return Py_True; + +clear: + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_snmp_incr_gauge(PyObject * self, PyObject * args) { + + uint8_t oid_num; + uint64_t oid_val = 1; + + if (!PyArg_ParseTuple(args, "bI:snmp_incr_gauge", &oid_num, &oid_val)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "b:snmp_incr_gauge", &oid_num)) { + return NULL; + } + } + + if (oid_num > 100 || oid_num < 1) + goto clear; + + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE; + uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val + oid_val; + + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + + Py_INCREF(Py_True); + return Py_True; + +clear: + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_snmp_decr_counter32(PyObject * self, PyObject * args) { + + uint8_t oid_num; + uint32_t oid_val = 1; + + if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter32", &oid_num, &oid_val)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "b:snmp_incr_counter32", &oid_num)) { + return NULL; + } + } + + if (oid_num > 100 || oid_num < 1) + goto clear; + + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER32; + uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val; + + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + + Py_INCREF(Py_True); + return Py_True; + +clear: + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_snmp_decr_counter64(PyObject * self, PyObject * args) { + + uint8_t oid_num; + uint64_t oid_val = 1; + + if (!PyArg_ParseTuple(args, "bI:snmp_incr_counter64", &oid_num, &oid_val)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "b:snmp_incr_counter64", &oid_num)) { + return NULL; + } + } + + if (oid_num > 100 || oid_num < 1) + goto clear; + + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_COUNTER64; + uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val; + + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + + Py_INCREF(Py_True); + return Py_True; + +clear: + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_snmp_decr_gauge(PyObject * self, PyObject * args) { + + uint8_t oid_num; + uint64_t oid_val = 1; + + if (!PyArg_ParseTuple(args, "bI:snmp_incr_gauge", &oid_num, &oid_val)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "b:snmp_incr_gauge", &oid_num)) { + return NULL; + } + } + + if (oid_num > 100 || oid_num < 1) + goto clear; + + UWSGI_RELEASE_GIL + uwsgi_wlock(uwsgi.snmp_lock); + + uwsgi.shared->snmp_value[oid_num - 1].type = SNMP_GAUGE; + uwsgi.shared->snmp_value[oid_num - 1].val = uwsgi.shared->snmp_value[oid_num - 1].val - oid_val; + + uwsgi_rwunlock(uwsgi.snmp_lock); + UWSGI_GET_GIL + + Py_INCREF(Py_True); + return Py_True; + +clear: + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject *py_snmp_set_community(PyObject * self, PyObject * args) { char *snmp_community; @@ -4019,10 +4235,16 @@ PyObject *py_snmp_community(PyObject * self, PyObject * args) { static PyMethodDef uwsgi_snmp_methods[] = { - {"snmp_set_counter32", py_snmp_counter32, METH_VARARGS, ""}, - {"snmp_set_counter64", py_snmp_counter64, METH_VARARGS, ""}, - {"snmp_set_gauge", py_snmp_gauge, METH_VARARGS, ""}, - {"snmp_set_community", py_snmp_community, METH_VARARGS, ""}, + {"snmp_set_counter32", py_snmp_set_counter32, METH_VARARGS, ""}, + {"snmp_set_counter64", py_snmp_set_counter64, METH_VARARGS, ""}, + {"snmp_set_gauge", py_snmp_set_gauge, METH_VARARGS, ""}, + {"snmp_incr_counter32", py_snmp_incr_counter32, METH_VARARGS, ""}, + {"snmp_incr_counter64", py_snmp_incr_counter64, METH_VARARGS, ""}, + {"snmp_incr_gauge", py_snmp_incr_gauge, METH_VARARGS, ""}, + {"snmp_decr_counter32", py_snmp_decr_counter32, METH_VARARGS, ""}, + {"snmp_decr_counter64", py_snmp_decr_counter64, METH_VARARGS, ""}, + {"snmp_decr_gauge", py_snmp_decr_gauge, METH_VARARGS, ""}, + {"snmp_set_community", py_snmp_set_community, METH_VARARGS, ""}, {NULL, NULL}, }; diff --git a/staticfilesnmp.py b/staticfilesnmp.py index 06dc6bf4..315e85c9 100644 --- a/staticfilesnmp.py +++ b/staticfilesnmp.py @@ -1,13 +1,13 @@ import uwsgi +from os import path -counter = 0 -uwsgi.snmp_set_counter64(1, counter) +uwsgi.snmp_set_counter64(1, 0) # Number of requests +uwsgi.snmp_set_counter64(2, 0) # Number of bytes def application(environ, start_response): - global counter - - start_response('200 OK', [('Content-Type', 'image/png')]) + size = path.getsize('logo_uWSGI.png') + start_response('200 OK', [('Content-Type', 'image/png'), ('Content-Length', str(size))] ) fd = open('logo_uWSGI.png','r') - counter = counter+1 - uwsgi.snmp_set_counter64(1, counter) + uwsgi.snmp_incr_counter64(1) + uwsgi.snmp_incr_counter64(2, size) return environ['wsgi.file_wrapper'](fd, 4096) diff --git a/uwsgi.h b/uwsgi.h index c75168da..b240c449 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1600,6 +1600,7 @@ struct uwsgi_server { int snmp; char *snmp_addr; char *snmp_community; + struct uwsgi_lock_item *snmp_lock; #endif