diff --git a/plugins/emperor_mongodb/emperor_mongodb.cc b/plugins/emperor_mongodb/emperor_mongodb.cc index bb41fc36..b629ec86 100644 --- a/plugins/emperor_mongodb/emperor_mongodb.cc +++ b/plugins/emperor_mongodb/emperor_mongodb.cc @@ -2,6 +2,8 @@ #include "client/dbclient.h" +#include + extern struct uwsgi_server uwsgi; extern struct uwsgi_instance *ui; @@ -10,6 +12,7 @@ struct uwsgi_emperor_mongodb_state { char *address; char *collection; char *json; + char *defaults; char *database; char *username; char *password; @@ -25,7 +28,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues // requested fields mongo::BSONObjBuilder builder; - builder.appendElements(BSON("name" << 1 << "config" << 1 << "ts" << 1 << "uid" << 1 << "gid" << 1 << "socket" << 1 )); + builder.appendElements(BSON("name" << 1 << "config" << 1 << "ts" << 1 << "uid" << 1 << "gid" << 1 << "socket" << 1 )); struct uwsgi_string_list *e_attrs = uwsgi.emperor_collect_attributes; while(e_attrs) { builder.appendElements(BSON(e_attrs->value << 1)); @@ -33,6 +36,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues } mongo::BSONObj p = builder.obj(); mongo::BSONObj q = mongo::fromjson(uems->json); + mongo::BSONObj d = mongo::fromjson(uems->defaults); // the connection object (will be automatically destroyed at each cycle) mongo::DBClientConnection c; // set the socket timeout @@ -51,7 +55,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues // run the query std::auto_ptr cursor = c.query(uems->collection, q, 0, 0, &p); while(cursor.get() && cursor->more() ) { - mongo::BSONObj p = cursor->next(); + mongo::BSONObj p = cursor->next(); // checking for an empty string is not required, but we reduce the load // in case of badly strctured databases @@ -88,7 +92,24 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues while(e_attrs) { const char *attr_value = p.getStringField(e_attrs->value); if (strlen(attr_value) == 0) attr_value = NULL; - if (attr_value) { + + if (!attr_value) { + mongo::BSONElement tmp = d.getField(e_attrs->value); + + if (tmp.type() == mongo::Array) { + std::vector< mongo::BSONElement > v = tmp.Array(); + + for(std::vector< mongo::BSONElement >::size_type i = 0; i != v.size(); i++) { + char *value = uwsgi_str((char *)v[i].valuestr()); + uwsgi_dyn_dict_new(&attrs, e_attrs->value, e_attrs->len, value, strlen(value)); + } + } + else if(tmp.type() == mongo::String){ + char *value = uwsgi_str((char *)tmp.valuestr()); + uwsgi_dyn_dict_new(&attrs, e_attrs->value, e_attrs->len, value, strlen(value)); + } + } + else { // the value memory is always reallocated char *value = uwsgi_str((char *)attr_value); uwsgi_dyn_dict_new(&attrs, e_attrs->value, e_attrs->len, value, strlen(value)); @@ -107,10 +128,10 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues // now check for removed instances - struct uwsgi_instance *c_ui = ui->ui_next; + struct uwsgi_instance *c_ui = ui->ui_next; - while (c_ui) { - if (c_ui->scanner == ues) { + while (c_ui) { + if (c_ui->scanner == ues) { mongo::BSONObjBuilder b; b.appendElements(q); b.append("name", c_ui->name); @@ -121,11 +142,11 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues uwsgi_log("JSON: %s\n", q2.toString().c_str()); #endif if (!cursor->more()) { - emperor_stop(c_ui); + emperor_stop(c_ui); } - } - c_ui = c_ui->ui_next; - } + } + c_ui = c_ui->ui_next; + } } @@ -139,7 +160,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues extern "C" void uwsgi_imperial_monitor_mongodb_init(struct uwsgi_emperor_scanner *ues) { // allocate a new state - ues->data = uwsgi_calloc(sizeof(struct uwsgi_emperor_mongodb_state)); + ues->data = uwsgi_calloc(sizeof(struct uwsgi_emperor_mongodb_state)); size_t arg_len = strlen(ues->arg); struct uwsgi_emperor_mongodb_state *uems = (struct uwsgi_emperor_mongodb_state *) ues->data; @@ -164,18 +185,18 @@ done: // setup a new mongodb imperial monitor (keyval based) extern "C" void uwsgi_imperial_monitor_mongodb_init2(struct uwsgi_emperor_scanner *ues) { + mongo::client::initialize(); + // allocate a new state + ues->data = uwsgi_calloc(sizeof(struct uwsgi_emperor_mongodb_state)); + size_t arg_len = strlen(ues->arg); + struct uwsgi_emperor_mongodb_state *uems = (struct uwsgi_emperor_mongodb_state *) ues->data; - // allocate a new state - ues->data = uwsgi_calloc(sizeof(struct uwsgi_emperor_mongodb_state)); - size_t arg_len = strlen(ues->arg); - struct uwsgi_emperor_mongodb_state *uems = (struct uwsgi_emperor_mongodb_state *) ues->data; - - // parse args/ set defaults - uems->address = (char *) "127.0.0.1:27017"; - uems->collection = (char *) "uwsgi.emperor.vassals"; - uems->json = (char *) ""; + // parse args/ set defaults + uems->address = (char *) "127.0.0.1:27017"; + uems->collection = (char *) "uwsgi.emperor.vassals"; + uems->json = (char *) ""; char *args = NULL; - if (arg_len <= 11) goto done; + if (arg_len <= 11) goto done; args = ues->arg+11; if (uwsgi_kvlist_parse(args, strlen(args), ',', '=', "addr", &uems->address, @@ -184,6 +205,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb_init2(struct uwsgi_emperor_scanne "collection", &uems->collection, "coll", &uems->collection, "json", &uems->json, + "defaults", &uems->defaults, "database", &uems->database, "db", &uems->database, "username", &uems->username, @@ -195,7 +217,7 @@ extern "C" void uwsgi_imperial_monitor_mongodb_init2(struct uwsgi_emperor_scanne exit(1); } done: - uwsgi_log("[emperor] enabled emperor MongoDB monitor for %s on collection %s\n", uems->address, uems->collection); + uwsgi_log("[emperor] enabled emperor MongoDB monitor for %s on collection %s\n", uems->address, uems->collection); } diff --git a/plugins/emperor_mongodb/uwsgiplugin.py b/plugins/emperor_mongodb/uwsgiplugin.py index 2206fbc5..208eaafc 100644 --- a/plugins/emperor_mongodb/uwsgiplugin.py +++ b/plugins/emperor_mongodb/uwsgiplugin.py @@ -13,5 +13,7 @@ if 'UWSGI_MONGODB_NOLIB' not in os.environ: LIBS.append('-lmongoclient') LIBS.append('-lboost_thread') LIBS.append('-lboost_filesystem') + LIBS.append('-lboost_regex') + GCC_LIST = ['plugin', 'emperor_mongodb.cc']