#include "../../uwsgi.h" extern struct uwsgi_server uwsgi; struct uwsgi_rrdtool { void *lib; int (*create)(int, char **); int (*update)(int, char **); struct uwsgi_string_list *rrd; int max_ds; int freq; char *update_area; } u_rrd; struct uwsgi_option rrdtool_options[] = { {"rrdtool", required_argument, 0, "collect requests data in the specified rrd file", uwsgi_opt_add_string_list, &u_rrd.rrd, UWSGI_OPT_MASTER}, {"rrdtool-freq", required_argument, 0, "set collect frequency", uwsgi_opt_set_int, &u_rrd.freq, 0}, {"rrdtool-max-ds", required_argument, 0, "set maximum number of data sources", uwsgi_opt_set_int, &u_rrd.max_ds, 0}, {0, 0, 0, 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_initial("*** RRDtool library available at %p ***\n", u_rrd.lib); 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); } } char *new_usl_value = uwsgi_malloc(PATH_MAX+1); if (!realpath(usl->value, new_usl_value)) { uwsgi_error("realpath()"); exit(1); } usl->value = new_usl_value; usl = usl->next; } // free DS for(i=0;i= u_rrd.freq) { ptr = u_rrd.update_area+1; rlen = snprintf(ptr, 1+sizeof(UMAX64_STR), ":%llu", (unsigned long long )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 = { .name = "rrdtool", .options = rrdtool_options, .master_cycle = rrdtool_master_cycle, .post_init = rrdtool_post_init, .init = rrdtool_init, };