diff --git a/buildconf/default.ini b/buildconf/default.ini index 90680c9e..c1f4f949 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -27,7 +27,7 @@ plugins = bin_name = uwsgi append_version = plugin_dir = . -embedded_plugins = python, ping, cache, nagios, rpc, fastrouter, http, ugreen +embedded_plugins = python, ping, cache, nagios, rrdtool, rpc, fastrouter, http, ugreen as_shared_library = false locking = auto diff --git a/master.c b/master.c index dc1e5b37..f8ada584 100644 --- a/master.c +++ b/master.c @@ -542,6 +542,17 @@ int master_loop(char **argv, char **environ) { for (;;) { //uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc); + for (i = 0; i < uwsgi.gp_cnt; i++) { + if (uwsgi.gp[i]->master_cycle) { + uwsgi.gp[i]->master_cycle(); + } + } + for (i = 0; i < 0xFF; i++) { + if (uwsgi.p[i]->master_cycle) { + uwsgi.p[i]->master_cycle(); + } + } + if (uwsgi.to_outworld) { //uwsgi_log("%d/%d\n", uwsgi.lazy_respawned, uwsgi.numproc); if (uwsgi.lazy_respawned >= uwsgi.numproc) { diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index cf332ad0..f7df7a09 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1162,6 +1162,9 @@ PyObject *py_uwsgi_mule_msg(PyObject * self, PyObject * args) { return NULL; } + if (uwsgi.mules_cnt < 1) + return PyErr_Format(PyExc_ValueError, "no mule configured"); + if (mule_obj == NULL) { len = write(uwsgi.shared->mule_queue_pipe[0], message, message_len); if (len <= 0) { diff --git a/plugins/rrdtool/rrdtool.c b/plugins/rrdtool/rrdtool.c new file mode 100644 index 00000000..9551c8aa --- /dev/null +++ b/plugins/rrdtool/rrdtool.c @@ -0,0 +1,188 @@ +#include "../../uwsgi.h" + +extern struct uwsgi_server uwsgi; + +#define RRDTOOL_OPT_BASE 177000 +#define RRDTOOL_OPT_RRDTOOL RRDTOOL_OPT_BASE+1 +#define RRDTOOL_OPT_RRDTOOL_MAX_DS RRDTOOL_OPT_BASE+2 + +struct uwsgi_rrdtool { + void *lib; + int (*create)(int, char **); + int (*update)(int, char **); + struct uwsgi_string_list *rrd; + int max_ds; + + char *update_area; +} u_rrd; + +struct option rrdtool_options[] = { + {"rrdtool", required_argument, 0, RRDTOOL_OPT_RRDTOOL}, + {"rrdtool-max-ds", required_argument, 0, RRDTOOL_OPT_RRDTOOL_MAX_DS}, + {0, 0, 0, 0}, + +}; + + +int rrdtool_init() { + + u_rrd.lib = dlopen("librrd.so", RTLD_LAZY); + if (!u_rrd.lib) return -1; + + u_rrd.create = dlsym(u_rrd.lib, "rrd_create"); + if (!u_rrd.create) { + dlclose(u_rrd.lib); + return -1; + } + + u_rrd.update = dlsym(u_rrd.lib, "rrd_update"); + if (!u_rrd.update) { + dlclose(u_rrd.lib); + return -1; + } + + if (!u_rrd.max_ds) u_rrd.max_ds = 30; + + uwsgi_log("*** RRDtool library available at %p ***\n", u_rrd.lib); + + return 0; +} + +int rrdtool_opt(int i, char *optarg) { + + switch(i) { + case RRDTOOL_OPT_RRDTOOL: + uwsgi.master_process = 1; + uwsgi_string_new_list(&u_rrd.rrd, optarg); + return 1; + case RRDTOOL_OPT_RRDTOOL_MAX_DS: + u_rrd.max_ds = atoi(optarg); + return 1; + } + + return 0; +} + +void rrdtool_post_init() { + + struct uwsgi_string_list *usl = u_rrd.rrd; + char **argv; + int i; + + if (!u_rrd.lib || !u_rrd.create) return; + + // do not waste time if no --rrdtool option is defiend + if (!u_rrd.rrd) return; + + if (uwsgi.numproc > u_rrd.max_ds) { + uwsgi_log("!!! NOT ENOUGH SLOTS IN RRDTOOL DS TO HOST WORKERS DATA (increase them with --rrdtool-max-ds) !!!\n"); + dlclose(u_rrd.lib); + return; + } + + // alloc space for DS_REQ + DS WORKER + RRA + create + filename + argv = uwsgi_malloc( sizeof(char *) * (1 + u_rrd.max_ds + 4 + 1 +1)); + + argv[0] = "create"; + + argv[2] = "DS:requests:DERIVE:600:0:U"; + + // create DS for workers + for(i=0;ivalue)) { + argv[1] = usl->value; + if (u_rrd.create((1 + u_rrd.max_ds + 4 + 1 +1), argv)) { + uwsgi_error("rrd_create()"); + exit(1); + } + } + usl->value = realpath(usl->value, NULL); + if (!usl->value) { + uwsgi_error("realpath()"); + exit(1); + } + usl = usl->next; + } + + // free DS + for(i=0;i= 300) { + ptr = u_rrd.update_area+1; + rlen = snprintf(ptr, 1+sizeof(UMAX64_STR), ":%llu", uwsgi.workers[0].requests); + if (rlen < 2) return; + ptr+=rlen; + for(i=0;ivalue; + if (u_rrd.update(3, argv)) { + uwsgi_log_verbose("ERROR: rrd_update(\"%s\", \"%s\")\n", argv[1], argv[2]); + } + usl = usl->next; + } + } +} + +struct uwsgi_plugin rrdtool_plugin = { + + .options = rrdtool_options, + .manage_opt = rrdtool_opt, + + .master_cycle = rrdtool_master_cycle, + + .post_init = rrdtool_post_init, + .init = rrdtool_init, +}; diff --git a/plugins/rrdtool/uwsgiplugin.py b/plugins/rrdtool/uwsgiplugin.py new file mode 100644 index 00000000..de73f6ff --- /dev/null +++ b/plugins/rrdtool/uwsgiplugin.py @@ -0,0 +1,7 @@ + +NAME='rrdtool' +CFLAGS = [] +LDFLAGS = [] +LIBS = [] + +GCC_LIST = ['rrdtool'] diff --git a/uwsgi.h b/uwsgi.h index a43bebf2..d0af4600 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -8,6 +8,8 @@ extern "C" { #define UMAX16 65536 +#define UMAX64_STR "18446744073709551616" + #define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__); #define uwsgi_fatal_error(x) uwsgi_error(x); exit(1); #define uwsgi_error_open(x) uwsgi_log("open(\"%s\"): %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__); @@ -657,6 +659,7 @@ struct uwsgi_plugin { void (*init_apps) (void); void (*fixup) (void); void (*master_fixup) (int); + void (*master_cycle) (void); int (*mount_app) (char *, char *, int); int (*manage_udp) (char *, int, char *, int); int (*manage_xml) (char *, char *); diff --git a/welcome.py b/welcome.py index ce09c2cd..8d1d3b42 100644 --- a/welcome.py +++ b/welcome.py @@ -50,7 +50,10 @@ def setprocname(): def application(env, start_response): - uwsgi.mule_msg(env['REQUEST_URI'], 1) + try: + uwsgi.mule_msg(env['REQUEST_URI'], 1) + except: + pass req = uwsgi.workers()[uwsgi.worker_id()-1]['requests']