redis plugin: Report query errors
[collectd.git] / src / redis.c
index 47fa28d..ca17e29 100644 (file)
@@ -35,7 +35,7 @@
 #define REDIS_DEF_HOST "localhost"
 #define REDIS_DEF_PASSWD ""
 #define REDIS_DEF_PORT 6379
-#define REDIS_DEF_TIMEOUT 2000
+#define REDIS_DEF_TIMEOUT_SEC 2
 #define REDIS_DEF_DB_COUNT 256
 #define MAX_REDIS_NODE_NAME 64
 #define MAX_REDIS_PASSWD_LENGTH 512
@@ -176,7 +176,7 @@ static int redis_config_node(oconfig_item_t *ci) /* {{{ */
   int timeout;
 
   redis_node_t rn = {.port = REDIS_DEF_PORT,
-                     .timeout.tv_usec = REDIS_DEF_TIMEOUT};
+                     .timeout.tv_sec = REDIS_DEF_TIMEOUT_SEC};
 
   sstrncpy(rn.host, REDIS_DEF_HOST, sizeof(rn.host));
 
@@ -205,8 +205,11 @@ static int redis_config_node(oconfig_item_t *ci) /* {{{ */
       }
     } else if (strcasecmp("Timeout", option->key) == 0) {
       status = cf_util_get_int(option, &timeout);
-      if (status == 0)
-        rn.timeout.tv_usec = timeout;
+      if (status == 0) {
+        rn.timeout.tv_usec = timeout * 1000;
+        rn.timeout.tv_sec = rn.timeout.tv_usec / 1000000L;
+        rn.timeout.tv_usec %= 1000000L;
+      }
     } else if (strcasecmp("Password", option->key) == 0)
       status = cf_util_get_string_buffer(option, rn.passwd, sizeof(rn.passwd));
     else
@@ -268,8 +271,7 @@ static int redis_init(void) /* {{{ */
   redis_node_t rn = {.name = "default",
                      .host = REDIS_DEF_HOST,
                      .port = REDIS_DEF_PORT,
-                     .timeout.tv_sec = 0,
-                     .timeout.tv_usec = REDIS_DEF_TIMEOUT,
+                     .timeout.tv_sec = REDIS_DEF_TIMEOUT_SEC,
                      .next = NULL};
 
   if (nodes_head == NULL)
@@ -315,12 +317,14 @@ static int redis_handle_query(redisContext *rh, redis_node_t *rn,
 
   ds = plugin_get_ds(rq->type);
   if (!ds) {
-    ERROR("redis plugin: DataSet `%s' not defined.", rq->type);
+    ERROR("redis plugin: DS type `%s' not defined.", rq->type);
     return -1;
   }
 
   if (ds->ds_num != 1) {
-    ERROR("redis plugin: DS `%s' has too many types.", rq->type);
+    ERROR("redis plugin: DS type `%s' has too many datasources. This is not "
+          "supported currently.",
+          rq->type);
     return -1;
   }
 
@@ -354,13 +358,24 @@ static int redis_handle_query(redisContext *rh, redis_node_t *rn,
     break;
   case REDIS_REPLY_STRING:
     if (parse_value(rr->str, &val, ds->ds[0].type) == -1) {
-      WARNING("redis plugin: Unable to parse field `%s'.", rq->type);
+      WARNING("redis plugin: Query `%s': Unable to parse value.", rq->query);
       freeReplyObject(rr);
       return -1;
     }
     break;
+  case REDIS_REPLY_ERROR:
+    WARNING("redis plugin: Query `%s' failed: %s.", rq->query, rr->str);
+    freeReplyObject(rr);
+    return -1;
+  case REDIS_REPLY_ARRAY:
+    WARNING("redis plugin: Query `%s' should return string or integer. Arrays "
+            "are not supported.",
+            rq->query);
+    freeReplyObject(rr);
+    return -1;
   default:
-    WARNING("redis plugin: Cannot coerce redis type.");
+    WARNING("redis plugin: Query `%s': Cannot coerce redis type (%i).",
+            rq->query, rr->type);
     freeReplyObject(rr);
     return -1;
   }
@@ -381,8 +396,8 @@ static int redis_db_stats(char *node, char const *info_line) /* {{{ */
 
   for (int db = 0; db < REDIS_DEF_DB_COUNT; db++) {
     static char buf[MAX_REDIS_VAL_SIZE];
-    static char field_name[11];
-    static char db_id[3];
+    static char field_name[12];
+    static char db_id[4];
     value_t val;
     char *str;
     int i;
@@ -421,8 +436,13 @@ static int redis_read(void) /* {{{ */
 
     rh = redisConnectWithTimeout((char *)rn->host, rn->port, rn->timeout);
     if (rh == NULL) {
-      ERROR("redis plugin: unable to connect to node `%s' (%s:%d).", rn->name,
-            rn->host, rn->port);
+      ERROR("redis plugin: can't allocate redis context");
+      continue;
+    }
+    if (rh->err) {
+      ERROR("redis plugin: unable to connect to node `%s' (%s:%d): %s.",
+            rn->name, rn->host, rn->port, rh->errstr);
+      redisFree(rh);
       continue;
     }