mongodb plugin: Use the error strings provided by libmongoc.
[collectd.git] / src / mongodb.c
index b696c38..090b2a4 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * collectd - src/mongo.c
- * Copyright (C) 2010 Ryan Cox 
+ * Copyright (C) 2010 Ryan Cox
+ * Copyright (C) 2012 Florian Forster
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Authors:
- *   Ryan Cox <ryan.a.cox@gmail.com> 
+ *   Ryan Cox <ryan.a.cox at gmail.com>
+ *   Florian Forster <octo at collectd.org>
  **/
 
 #include "collectd.h"
-#include "common.h" 
-#include "plugin.h" 
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
+#include "common.h"
+#include "plugin.h"
 
 #if HAVE_STDINT_H
 # define MONGO_HAVE_STDINT 1
 #endif
 #include <mongo.h>
 
-#define MC_PLUGIN_NAME "mongo"
 #define MC_MONGO_DEF_HOST "127.0.0.1"
-#define MC_MONGO_DEF_PORT 27017 
 #define MC_MONGO_DEF_DB "admin"
-#define MC_MIN_PORT 1
-#define MC_MAX_PORT 65535 
-#define SUCCESS 0 
-#define FAILURE -1 
 
-static char *mc_user = NULL;
+static char *mc_user     = NULL;
 static char *mc_password = NULL;
-static char *mc_db = NULL; 
-static char *mc_host = NULL;
-static int  mc_port = MC_MONGO_DEF_PORT;
+static char *mc_db       = NULL;
+static char *mc_host     = NULL;
+static int   mc_port     = 0;
 
-static mongo_connection mc_connection;
+static mongo mc_connection;
 static _Bool mc_have_connection = 0;
 
 static const char *config_keys[] = {
-       "User",
-       "Password",
-       "Database",
-       "Host",
-       "Port"
+    "User",
+    "Password",
+    "Database",
+    "Host",
+    "Port"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
-static void submit (const char *type, const char *instance,
+static void submit (const char *type, const char *instance, /* {{{ */
         value_t *values, size_t values_len)
 {
     value_list_t v = VALUE_LIST_INIT;
@@ -71,314 +62,338 @@ static void submit (const char *type, const char *instance,
     v.values_len = values_len;
 
     sstrncpy (v.host, hostname_g, sizeof(v.host));
-    sstrncpy (v.plugin, MC_PLUGIN_NAME, sizeof(v.plugin));
+    sstrncpy (v.plugin, "mongodb", sizeof(v.plugin));
     ssnprintf (v.plugin_instance, sizeof (v.plugin_instance), "%i", mc_port);
     sstrncpy (v.type, type, sizeof(v.type));
 
     if (instance != NULL)
-        sstrncpy (v.type_instance, instance, sizeof (v.type_instance)); 
+        sstrncpy (v.type_instance, instance, sizeof (v.type_instance));
 
     plugin_dispatch_values (&v);
-}
+} /* }}} void submit */
 
-static void submit_gauge(const char *type, const char *instance, gauge_t gauge ) {
-       value_t v[1];
-       v[0].gauge = gauge;
-       submit(type, instance, v, STATIC_ARRAY_SIZE (v));
-}
+static void submit_gauge (const char *type, const char *instance, /* {{{ */
+        gauge_t gauge)
+{
+    value_t v;
 
+    v.gauge = gauge;
+    submit(type, instance, &v, /* values_len = */ 1);
+} /* }}} void submit_gauge */
 
-static void handle_opcounters(bson* obj) {
-    INFO("handle op counters");
-    bson_iterator it;
-    if(bson_find(&it, obj, "opcounters")) {
-        bson subobj;
-        bson_iterator_subobject(&it, &subobj);
-        bson_iterator it2;
-        bson_iterator_init(&it2, subobj.data);
-
-        int64_t insert = 0;
-        int64_t query = 0;
-        int64_t delete = 0;
-        int64_t getmore = 0;
-        int64_t command = 0;
-
-        while(bson_iterator_next(&it2)){
-            if(strcmp(bson_iterator_key(&it2),"insert") == 0) {
-                insert = bson_iterator_long(&it2);
-            }
-            if(strcmp(bson_iterator_key(&it2),"query") == 0) {
-                query = bson_iterator_long(&it2);
-            }
-            if(strcmp(bson_iterator_key(&it2),"delete") == 0) {
-                delete = bson_iterator_long(&it2);
-            }
-            if(strcmp(bson_iterator_key(&it2),"getmore") == 0) {
-                getmore = bson_iterator_long(&it2);
-            }
-            if(strcmp(bson_iterator_key(&it2),"command") == 0) {
-                command = bson_iterator_long(&it2);
-            }
-        }
+static void submit_derive (const char *type, const char *instance, /* {{{ */
+        derive_t derive)
+{
+    value_t v;
 
-        bson_destroy(&subobj);
+    v.derive = derive;
+    submit(type, instance, &v, /* values_len = */ 1);
+} /* }}} void submit_derive */
 
-        submit_gauge("mongo_counter", "indert", insert );
-        submit_gauge("mongo_counter", "query", query );
-        submit_gauge("mongo_counter", "delete", delete );
-        submit_gauge("mongo_counter", "getmore", getmore );
-        submit_gauge("mongo_counter", "command", command );
-        submit_gauge("mongo_counter", "insert", insert );
-    }
-}
+static int handle_field (bson *obj, const char *field, /* {{{ */
+        int (*func) (bson_iterator *))
+{
+    bson_type type;
+    bson_iterator iter;
+    bson_iterator subiter;
+    int status = 0;
 
-static void handle_mem(bson* obj) {
-    INFO("handle mem");
-    bson_iterator it;
-    if(bson_find(&it, obj, "mem")) {
-        bson subobj;
-        bson_iterator_subobject(&it, &subobj);
-        bson_iterator it2;
-        bson_iterator_init(&it2, subobj.data);
-        int64_t resident = 0;
-        int64_t virtual = 0;
-        int64_t mapped = 0;
-        while(bson_iterator_next(&it2)) {
-            if(strcmp(bson_iterator_key(&it2),"resident") == 0) {
-                resident = bson_iterator_long(&it2);
-            }
-            if(strcmp(bson_iterator_key(&it2),"virtual") == 0) {
-                virtual = bson_iterator_long(&it2);
-            }
-            if(strcmp(bson_iterator_key(&it2),"mapped") == 0) {
-                mapped = bson_iterator_long(&it2);
-            }
-        }
-        value_t values[3];
-        values[0].gauge = resident;
-        values[1].gauge = virtual;
-        values[2].gauge = mapped;
-        submit_gauge("memory", "resident", resident );
-        submit_gauge("memory", "virtual", virtual );
-        submit_gauge("memory", "mapped", mapped );
-        bson_destroy(&subobj);
-    }
-}
+    type = bson_find (&iter, obj, field);
+    if (type != BSON_OBJECT)
+        return (EINVAL);
 
-static void handle_connections(bson* obj) {
-    INFO("handle connections");
-    bson_iterator it;
-    if(bson_find(&it, obj, "connections")) {
-    bson subobj;
-        bson_iterator_subobject(&it, &subobj);
-        bson_iterator it2;
-        bson_iterator_init(&it2, subobj.data);
-        while(bson_iterator_next(&it2)) {
-            if(strcmp(bson_iterator_key(&it2),"current") == 0) {
-                submit_gauge("connections", "connections", bson_iterator_int(&it2));
-                break;
-            }
-        }
-        bson_destroy(&subobj);
+    bson_iterator_subiterator (&iter, &subiter);
+    while (bson_iterator_more (&subiter))
+    {
+        (void) bson_iterator_next (&subiter);
+        status = (*func) (&subiter);
+        if (status != 0)
+            break;
     }
-}
 
-static void handle_lock(bson* obj) {
-    INFO("handle lock");
-    bson_iterator it;
-    if(bson_find(&it, obj, "globalLock")) {
-        bson subobj;
-        bson_iterator_subobject(&it, &subobj);
-        bson_iterator it2;
-        bson_iterator_init(&it2, subobj.data);
-        while(bson_iterator_next(&it2)) {
-            if(strcmp(bson_iterator_key(&it2),"ratio") == 0) {
-                submit_gauge("percent", "lock_ratio", bson_iterator_double(&it2));
-            }
-        }
-        bson_destroy(&subobj);
-    }
-}
+    return (status);
+} /* }}} int handle_field */
 
-static void handle_index_counters(bson* obj) {
-    INFO("handle index counters");
-    bson_iterator icit;
-    if(bson_find(&icit, obj, "indexCounters")) {
-        bson oic;
-        bson_iterator_subobject(&icit, &oic);
-        if(bson_find(&icit, &oic, "btree")) {
-            bson obt;
-            bson_iterator_subobject(&icit, &obt);
-            bson_iterator bit;
-            bson_iterator_init(&bit, oic.data);
-            int accesses; 
-            int misses;
-            double ratio;
-
-            while(bson_iterator_next(&bit)) {
-                if(strcmp(bson_iterator_key(&bit),"accesses") == 0) {
-                    accesses = bson_iterator_int(&bit); 
-                }
-                if(strcmp(bson_iterator_key(&bit),"misses") == 0) {
-                    misses = bson_iterator_int(&bit); 
-                }
-            }
-
-            ratio = NAN;
-            if (misses <= accesses)
-                ratio = ((double) misses) / ((double) accesses);
-            submit_gauge("cache_ratio", "cache_misses", ratio );
-
-            bson_destroy(&obt);
-        }
-        bson_destroy(&oic);
-    }
-}
+static int handle_opcounters (bson_iterator *iter) /* {{{ */
+{
+    bson_type type;
+    const char *key;
+    derive_t value;
 
-static void handle_stats_counts(bson* obj) {
+    type = bson_iterator_type (iter);
+    if ((type != BSON_INT) && (type != BSON_LONG))
+        return (0);
 
-    INFO("handle stats counts");
-    bson_iterator it;
-    bson_iterator_init(&it, obj->data);
-    int64_t collections = 0;
-    int64_t objects = 0;
-    int64_t numExtents = 0;
-    int64_t indexes = 0;
+    key = bson_iterator_key (iter);
+    if (key == NULL)
+        return (0);
 
-    while(bson_iterator_next(&it)) {
-        if(strcmp(bson_iterator_key(&it),"collections") == 0) {
-            collections = bson_iterator_long(&it); 
-        }
-        if(strcmp(bson_iterator_key(&it),"objects") == 0) {
-            objects = bson_iterator_long(&it); 
-        }
-        if(strcmp(bson_iterator_key(&it),"numExtents") == 0) {
-            numExtents = bson_iterator_long(&it); 
-        }
-        if(strcmp(bson_iterator_key(&it),"indexes") == 0) {
-            indexes = bson_iterator_long(&it); 
-        }
-    }
+    value = (derive_t) bson_iterator_long (iter);
+
+    submit_derive ("total_operations", key, value);
+    return (0);
+} /* }}} int handle_opcounters */
 
-    submit_gauge("counter","object_count",objects);
+static int handle_mem (bson_iterator *iter) /* {{{ */
+{
+    bson_type type;
+    const char *key;
+    gauge_t value;
 
-    submit_gauge("counter", "collections",collections); 
-    submit_gauge("counter", "num_extents",numExtents); 
-    submit_gauge("counter", "indexes",indexes); 
-}
+    type = bson_iterator_type (iter);
+    if ((type != BSON_DOUBLE) && (type != BSON_LONG) && (type != BSON_INT))
+        return (0);
 
-static void handle_stats_sizes(bson* obj) {
-    bson_iterator it;
-    bson_iterator_init(&it, obj->data);
-    int64_t storageSize = 0;
-    int64_t dataSize = 0;
-    int64_t indexSize = 0;
-    while(bson_iterator_next(&it)) {
-        if(strcmp(bson_iterator_key(&it),"storageSize") == 0) {
-            storageSize = bson_iterator_long(&it); 
-        }
-        if(strcmp(bson_iterator_key(&it),"dataSize") == 0) {
-            dataSize = bson_iterator_long(&it); 
-        }
-        if(strcmp(bson_iterator_key(&it),"indexSize") == 0) {
-            indexSize = bson_iterator_long(&it); 
-        }
-    }
+    key = bson_iterator_key (iter);
+    if (key == NULL)
+        return (0);
 
-    submit_gauge ("file_size", "storage", storageSize);
-    submit_gauge ("file_size", "index", indexSize);
-    submit_gauge ("file_size", "data", dataSize);
-}
+    /* Is "virtual" really interesting?
+     * What exactly does "mapped" mean? */
+    if ((strcasecmp ("mapped", key) != 0)
+            && (strcasecmp ("resident", key) != 0)
+            && (strcasecmp ("virtual", key) != 0))
+        return (0);
 
-static int do_stats(void) {
-    bson obj;
+    value = (gauge_t) bson_iterator_double (iter);
+    /* All values are in MByte */
+    value *= 1048576.0;
 
-    /* TODO: 
+    submit_gauge ("memory", key, value);
+    return (0);
+} /* }}} int handle_mem */
 
-        change this to raw runCommand
-             db.runCommand( { dbstats : 1 } ); 
-             succeeds but is getting back all zeros !?!
-        modify bson_print to print type 18
-        repro problem w/o db name - show dbs doesn't work again
-        why does db.admin.dbstats() work fine in shell?
-        implement retries ? noticed that if db is unavailable, collectd dies
-    */
+static int handle_connections (bson_iterator *iter) /* {{{ */
+{
+    bson_type type;
+    const char *key;
+    gauge_t value;
 
-    if( !mongo_simple_int_command(&mc_connection, mc_db, "dbstats", 1, &obj) ) {
-        ERROR("Mongo: failed to call stats Host [%s] Port [%d] User [%s]", 
-            mc_host, mc_port, mc_user);
-        return FAILURE;
-    }
-    
-    bson_print(&obj);
-    
-    handle_stats_sizes(&obj);
-    handle_stats_counts(&obj);
+    type = bson_iterator_type (iter);
+    if ((type != BSON_DOUBLE) && (type != BSON_LONG) && (type != BSON_INT))
+        return (0);
 
+    key = bson_iterator_key (iter);
+    if (key == NULL)
+        return (0);
 
-    bson_destroy(&obj);
+    if (strcmp ("current", key) != 0)
+        return (0);
 
-    return SUCCESS;
-}
+    value = (gauge_t) bson_iterator_double (iter);
 
+    submit_gauge ("current_connections", NULL, value);
+    return (0);
+} /* }}} int handle_connections */
 
-static int do_server_status(void) {
-    bson obj;
+static int handle_lock (bson_iterator *iter) /* {{{ */
+{
+    bson_type type;
+    const char *key;
+    derive_t value;
 
-    if( !mongo_simple_int_command(&mc_connection, mc_db, "serverStatus", 1, &obj) ) {
-        ERROR("Mongo: failed to call serverStatus Host [%s] Port [%d] User [%s]", 
-            mc_host, mc_port, mc_user);
-        return FAILURE;
-    }
+    type = bson_iterator_type (iter);
+    if ((type != BSON_DOUBLE) && (type != BSON_LONG) && (type != BSON_INT))
+        return (0);
 
-    bson_print(&obj);
+    key = bson_iterator_key (iter);
+    if (key == NULL)
+        return (0);
 
-    handle_opcounters(&obj);
-    handle_mem(&obj);
-    handle_connections(&obj);
-    handle_index_counters(&obj);
-    handle_lock(&obj);
+    if (strcmp ("lockTime", key) != 0)
+        return (0);
 
-    bson_destroy(&obj);
-    return SUCCESS;
-}
+    value = (derive_t) bson_iterator_long (iter);
+    /* The time is measured in microseconds (us). We convert it to
+     * milliseconds (ms). */
+    value = value / 1000;
+
+    submit_derive ("total_time_in_ms", "lock_held", value);
+    return (0);
+} /* }}} int handle_lock */
+
+static int handle_btree (const bson *obj) /* {{{ */
+{
+    bson_iterator i;
+
+    bson_iterator_init (&i, obj);
+    while (bson_iterator_next (&i))
+    {
+        bson_type type;
+        const char *key;
+        gauge_t value;
 
-static int mc_read(void) {
-    DEBUG("Mongo: mongo driver read"); 
+        type = bson_iterator_type (&i);
+        if ((type != BSON_DOUBLE) && (type != BSON_LONG) && (type != BSON_INT))
+            continue;
 
-    if(do_server_status() != SUCCESS) {
-        ERROR("Mongo: do server status failed"); 
-        return FAILURE;
+        key = bson_iterator_key (&i);
+        if (key == NULL)
+            continue;
+
+        value = (gauge_t) bson_iterator_double (&i);
+
+        if (strcmp ("hits", key) == 0)
+            submit_gauge ("cache_result", "hit", value);
+        else if (strcmp ("misses", key) != 0)
+            submit_gauge ("cache_result", "miss", value);
     }
 
-    if(do_stats() != SUCCESS) {
-        ERROR("Mongo: do stats status failed"); 
-        return FAILURE;
+    return (0);
+} /* }}} int handle_btree */
+
+static int handle_index_counters (bson_iterator *iter) /* {{{ */
+{
+    bson_type type;
+    const char *key;
+    bson subobj;
+    int status;
+
+    type = bson_iterator_type (iter);
+    if (type != BSON_OBJECT)
+        return (0);
+
+    key = bson_iterator_key (iter);
+    if (key == NULL)
+        return (0);
+
+    if (strcmp ("btree", key) != 0)
+        return (0);
+
+    bson_iterator_subobject (iter, &subobj);
+    status = handle_btree (&subobj);
+    bson_destroy (&subobj);
+
+    return (status);
+} /* }}} int handle_index_counters */
+
+static int query_server_status (void) /* {{{ */
+{
+    bson result;
+    int status;
+
+    status = mongo_simple_int_command (&mc_connection,
+            (mc_db != NULL) ? mc_db : MC_MONGO_DEF_DB,
+            /* cmd = */ "serverStatus", /* arg = */ 1,
+            &result);
+    if (status != MONGO_OK)
+    {
+        ERROR ("mongodb plugin: Calling {\"serverStatus\": 1} failed: %s",
+                mc_connection.errstr);
+        return (-1);
     }
 
-    return SUCCESS;
-}
+    handle_field (&result, "opcounters",    handle_opcounters);
+    handle_field (&result, "mem",           handle_mem);
+    handle_field (&result, "connections",   handle_connections);
+    handle_field (&result, "globalLock",    handle_lock);
+    handle_field (&result, "indexCounters", handle_index_counters);
 
+    bson_destroy(&result);
+    return (0);
+} /* }}} int query_server_status */
 
-static void config_set(char** dest, const char* src ) {
-        if( *dest ) {
-            sfree(*dest);
-        }
-               *dest= malloc(strlen(src)+1);
-        sstrncpy(*dest,src,strlen(src)+1);
-}
+static int handle_dbstats (const bson *obj) /* {{{ */
+{
+    bson_iterator i;
 
-static int mc_config(const char *key, const char *value)
-{ 
-    DEBUG("Mongo: config key [%s] value [%s]", key, value); 
+    bson_iterator_init (&i, obj);
+    while (bson_iterator_next (&i))
+    {
+        bson_type type;
+        const char *key;
+        gauge_t value;
+
+        type = bson_iterator_type (&i);
+        if ((type != BSON_DOUBLE) && (type != BSON_LONG) && (type != BSON_INT))
+            return (0);
+
+        key = bson_iterator_key (&i);
+        if (key == NULL)
+            return (0);
+
+        value = (gauge_t) bson_iterator_double (&i);
+
+        /* counts */
+        if (strcmp ("collections", key) == 0)
+            submit_gauge ("gauge", "collections", value);
+        else if (strcmp ("objects", key) == 0)
+            submit_gauge ("gauge", "objects", value);
+        else if (strcmp ("numExtents", key) == 0)
+            submit_gauge ("gauge", "num_extents", value);
+        else if (strcmp ("indexes", key) == 0)
+            submit_gauge ("gauge", "indexes", value);
+        /* sizes */
+        else if (strcmp ("dataSize", key) == 0)
+            submit_gauge ("bytes", "data", value);
+        else if (strcmp ("storageSize", key) == 0)
+            submit_gauge ("bytes", "storage", value);
+        else if (strcmp ("indexSize", key) == 0)
+            submit_gauge ("bytes", "index", value);
+    }
+
+    return (0);
+} /* }}} int handle_dbstats */
 
-    if(strcasecmp("Host", key) == 0) {
-        config_set(&mc_host,value);
+static int query_dbstats (void) /* {{{ */
+{
+    bson result;
+    int status;
+
+    /* TODO:
+     *
+     *  change this to raw runCommand
+     *       db.runCommand( { dbstats : 1 } );
+     *       succeeds but is getting back all zeros !?!
+     *  modify bson_print to print type 18
+     *  repro problem w/o db name - show dbs doesn't work again
+     *  why does db.admin.dbstats() work fine in shell?
+     *  implement retries ? noticed that if db is unavailable, collectd dies
+     */
+
+    memset (&result, 0, sizeof (result));
+    status = mongo_simple_int_command (&mc_connection,
+            (mc_db != NULL) ? mc_db : MC_MONGO_DEF_DB,
+            /* cmd = */ "dbstats", /* arg = */ 1,
+            &result);
+    if (status != MONGO_OK)
+    {
+        ERROR ("mongodb plugin: Calling {\"dbstats\": 1} failed: %s",
+                mc_connection.errstr);
+        return (-1);
     }
-    else if(strcasecmp("Port", key) == 0)
+
+    handle_dbstats (&result);
+
+    bson_destroy (&result);
+    return (0);
+} /* }}} int query_dbstats */
+
+static int mc_read(void) /* {{{ */
+{
+    if (query_server_status () != 0)
+        return (-1);
+
+    if (query_dbstats () != 0)
+        return (-1);
+
+    return (0);
+} /* }}} int mc_read */
+
+static void mc_config_set (char **dest, const char *src ) /* {{{ */
+{
+    sfree(*dest);
+    *dest = strdup (src);
+} /* }}} void mc_config_set */
+
+static int mc_config (const char *key, const char *value) /* {{{ */
+{
+    if (strcasecmp("Host", key) == 0)
+        mc_config_set(&mc_host,value);
+    else if (strcasecmp("Port", key) == 0)
     {
         int tmp;
-        
+
         tmp = service_name_to_port_number (value);
         if (tmp > 0)
             mc_port = tmp;
@@ -388,79 +403,69 @@ static int mc_config(const char *key, const char *value)
             return (-1);
         }
     }
-    else if(strcasecmp("User", key) == 0) {
-        config_set(&mc_user,value);
-    }
-    else if(strcasecmp("Password", key) == 0) {
-        config_set(&mc_password,value);
-    }
-    else if(strcasecmp("Database", key) == 0) {
-        config_set(&mc_db,value);
-    }
+    else if(strcasecmp("User", key) == 0)
+        mc_config_set(&mc_user,value);
+    else if(strcasecmp("Password", key) == 0)
+        mc_config_set(&mc_password,value);
+    else if(strcasecmp("Database", key) == 0)
+        mc_config_set(&mc_db,value);
     else
     {
         ERROR ("mongodb plugin: Unknown config option: %s", key);
         return (-1);
     }
 
-    return SUCCESS;
-} 
+    return (0);
+} /* }}} int mc_config */
 
-static int mc_init(void)
+static int mc_init (void) /* {{{ */
 {
+    int status;
+
     if (mc_have_connection)
         return (0);
 
-    DEBUG("mongo driver initializing"); 
-    if( !mc_host) {
-        DEBUG("Mongo: Host not specified. Using default [%s]",MC_MONGO_DEF_HOST); 
-        config_set(&mc_host, MC_MONGO_DEF_HOST);
-    }
-
-    if( !mc_db) {
-        DEBUG("Mongo: Database not specified. Using default [%s]",MC_MONGO_DEF_DB); 
-        config_set(&mc_db, MC_MONGO_DEF_DB);
-    }
-
-    mongo_connection_options opts;
-    sstrncpy(opts.host, mc_host, sizeof(opts.host));
-    opts.port = mc_port; 
+    mongo_init (&mc_connection);
 
-    if(mongo_connect(&mc_connection, &opts )){
-        ERROR("Mongo: driver failed to connect. Host [%s] Port [%d] User [%s]", 
-                mc_host, mc_port, mc_user);
-        return FAILURE;     
+    status = mongo_connect (&mc_connection,
+            (mc_host != NULL) ? mc_host : MC_MONGO_DEF_HOST,
+            (mc_port > 0) ? mc_port : MONGO_DEFAULT_PORT);
+    if (status != MONGO_OK)
+    {
+        ERROR ("mongo plugin: Connecting to %s:%i failed: %s",
+                (mc_host != NULL) ? mc_host : MC_MONGO_DEF_HOST,
+                (mc_port > 0) ? mc_port : MONGO_DEFAULT_PORT,
+                mc_connection.errstr);
+        return (-1);
     }
 
     mc_have_connection = 1;
-    return SUCCESS;
-} 
+    return (0);
+} /* }}} int mc_init */
 
-static int mc_shutdown(void)
+static int mc_shutdown(void) /* {{{ */
 {
-    DEBUG("Mongo: driver shutting down"); 
-
     if (mc_have_connection) {
         mongo_disconnect (&mc_connection);
         mongo_destroy (&mc_connection);
         mc_have_connection = 0;
     }
 
-    sfree(mc_user);
-    sfree(mc_password);
-    sfree(mc_db);
-    sfree(mc_host);
+    sfree (mc_user);
+    sfree (mc_password);
+    sfree (mc_db);
+    sfree (mc_host);
 
     return (0);
-}
-
+} /* }}} int mc_shutdown */
 
-void module_register(void)  {       
-    plugin_register_config (MC_PLUGIN_NAME, mc_config,
+void module_register(void)
+{
+    plugin_register_config ("mongodb", mc_config,
             config_keys, config_keys_num);
-    plugin_register_read (MC_PLUGIN_NAME, mc_read);
-    plugin_register_init (MC_PLUGIN_NAME, mc_init);
-    plugin_register_shutdown (MC_PLUGIN_NAME, mc_shutdown);
+    plugin_register_read ("mongodb", mc_read);
+    plugin_register_init ("mongodb", mc_init);
+    plugin_register_shutdown ("mongodb", mc_shutdown);
 }
 
 /* vim: set sw=4 sts=4 et fdm=marker : */