[Reconnoiter-devel] [reconnoiter commit] Reconnoiter branch, master, updated. 899f2d2b74c6a8e1d8fc9a0ede60f226f83d551d

git at labs.omniti.com git at labs.omniti.com
Sat Nov 19 20:11:58 EST 2011


Pushed by: jesus
The branch, master has been updated
       via  899f2d2b74c6a8e1d8fc9a0ede60f226f83d551d (commit)
      from  c149f8ad1d420218a0016f2b672b26236b8b3033 (commit)

Summary of changes:
 src/modules-lua/noit/module/resmon.lua |   22 +++---
 src/modules/lua.c                      |   21 ++++++
 src/noit_check.c                       |   64 ++++++++++++++++-
 src/noit_check.h                       |    6 ++-
 src/noit_check_tools.c                 |  124 ++++++++++++++++++++++++++++++++
 src/noit_check_tools.h                 |    3 +
 6 files changed, 225 insertions(+), 15 deletions(-)

Log:
commit 899f2d2b74c6a8e1d8fc9a0ede60f226f83d551d
Author: Theo Schlossnagle <jesus at omniti.com>
Date:   Sat Nov 19 20:11:20 2011 -0500

    Performance enhancement populating check metrics from json in lua.
    (as in, don't do it in lua, do it all in C). 1.6x speedup.

diff --git a/src/modules-lua/noit/module/resmon.lua b/src/modules-lua/noit/module/resmon.lua
index bb4c9ec..ac20534 100644
--- a/src/modules-lua/noit/module/resmon.lua
+++ b/src/modules-lua/noit/module/resmon.lua
@@ -248,17 +248,17 @@ function initiate(module, check)
     local jsondoc = nil
     if string.find(hdrs_in["content-type"] or '', 'json') ~= nil or
        string.find(hdrs_in["content-type"] or '', 'javascript') ~= nil then
-        jsondoc = noit.parsejson(output)
-        if jsondoc == nil then
-            noit.log("debug", "bad json: %s", output)
-            check.status("json parse error")
-            return
-        end
-    end
-
-    if jsondoc ~= nil then
-        json_to_metrics(check, jsondoc)
-        return
+      services = check.metric_json(output)
+      if(services >= 0) then
+        check.available()
+        check.metric_uint32("services", services)
+        if services > 0 then check.good() else check.bad() end
+        check.status("services=" .. services)
+      else
+        noit.log("debug", "bad json: %s", output)
+        check.status("json parse error")
+      end
+      return
     end
 
     -- try xml by "default" (assuming no json-specific content header)
diff --git a/src/modules/lua.c b/src/modules/lua.c
index e43e5e6..bb8df5d 100644
--- a/src/modules/lua.c
+++ b/src/modules/lua.c
@@ -304,6 +304,23 @@ noit_lua_set_status(lua_State *L) {
   return 0;
 }
 static int
+noit_lua_set_metric_json(lua_State *L) {
+  noit_check_t *check;
+  noit_lua_check_info_t *ci;
+  const char *json;
+  size_t jsonlen;
+  int rv;
+
+  if(lua_gettop(L) != 1) luaL_error(L, "wrong number of arguments");
+  check = lua_touserdata(L, lua_upvalueindex(1));
+  ci = check->closure;
+  if(!lua_isstring(L, 1)) luaL_error(L, "argument #1 must be a string");
+  json = lua_tolstring(L, 1, &jsonlen);
+  rv = noit_check_stats_from_json_str(&ci->current, json, (int)jsonlen);
+  lua_pushinteger(L, rv);
+  return 1;
+}
+static int
 noit_lua_set_metric(lua_State *L) {
   noit_check_t *check;
   noit_lua_check_info_t *ci;
@@ -437,6 +454,10 @@ noit_check_index_func(lua_State *L) {
       else IF_METRIC_BLOCK("metric_int64", METRIC_INT64)
       else IF_METRIC_BLOCK("metric_uint64", METRIC_UINT64)
       else IF_METRIC_BLOCK("metric_double", METRIC_DOUBLE)
+      else if(!strcmp(k, "metric_json")) {
+        lua_pushlightuserdata(L, check);
+        lua_pushcclosure(L, noit_lua_set_metric_json, 1);
+      }
       else break;
       return 1;
     case 'n':
diff --git a/src/noit_check.c b/src/noit_check.c
index 2e744c9..b3286f3 100644
--- a/src/noit_check.c
+++ b/src/noit_check.c
@@ -939,7 +939,7 @@ __stats_add_metric(stats_t *newstate, metric_t *m) {
 }
 
 static size_t
-noit_metric_sizes(metric_type_t type, void *value) {
+noit_metric_sizes(metric_type_t type, const void *value) {
   switch(type) {
     case METRIC_INT32:
     case METRIC_UINT32:
@@ -1075,7 +1075,7 @@ noit_metric_guess_type(const char *s, void **replacement) {
 }
 int
 noit_stats_populate_metric(metric_t *m, const char *name, metric_type_t type,
-                           void *value) {
+                           const void *value) {
   void *replacement = NULL;
   if(type == METRIC_GUESS)
     type = noit_metric_guess_type((char *)value, &replacement);
@@ -1095,7 +1095,7 @@ noit_stats_populate_metric(metric_t *m, const char *name, metric_type_t type,
 }
 void
 noit_stats_set_metric(stats_t *newstate, const char *name, metric_type_t type,
-                      void *value) {
+                      const void *value) {
   metric_t *m = calloc(1, sizeof(*m));
   if(noit_stats_populate_metric(m, name, type, value)) {
     free_metric(m);
@@ -1104,6 +1104,64 @@ noit_stats_set_metric(stats_t *newstate, const char *name, metric_type_t type,
   __stats_add_metric(newstate, m);
 }
 void
+noit_stats_set_metric_coerce(stats_t *stat, const char *name, metric_type_t t,
+                             const char *v) {
+  char *endptr;
+  if(v == NULL) {
+   bogus:
+    noit_stats_set_metric(stat, name, t, NULL);
+    return;
+  }
+  switch(t) {
+    case METRIC_STRING:
+      noit_stats_set_metric(stat, name, t, v);
+      break;
+    case METRIC_INT32:
+    {
+      int32_t val;
+      val = strtol(v, &endptr, 10);
+      if(endptr == v) goto bogus;
+      noit_stats_set_metric(stat, name, t, &val);
+      break;
+    }
+    case METRIC_UINT32:
+    {
+      u_int32_t val;
+      val = strtoul(v, &endptr, 10);
+      if(endptr == v) goto bogus;
+      noit_stats_set_metric(stat, name, t, &val);
+      break;
+    }
+    case METRIC_INT64:
+    {
+      int64_t val;
+      val = strtoll(v, &endptr, 10);
+      if(endptr == v) goto bogus;
+      noit_stats_set_metric(stat, name, t, &val);
+      break;
+    }
+    case METRIC_UINT64:
+    {
+      u_int64_t val;
+      val = strtoull(v, &endptr, 10);
+      if(endptr == v) goto bogus;
+      noit_stats_set_metric(stat, name, t, &val);
+      break;
+    }
+    case METRIC_DOUBLE:
+    {
+      double val;
+      val = strtod(v, &endptr);
+      if(endptr == v) goto bogus;
+      noit_stats_set_metric(stat, name, t, &val);
+      break;
+    }
+    case METRIC_GUESS:
+      noit_stats_set_metric(stat, name, t, v);
+      break;
+  }
+}
+void
 noit_stats_log_immediate_metric(noit_check_t *check,
                                 const char *name, metric_type_t type,
                                 void *value) {
diff --git a/src/noit_check.h b/src/noit_check.h
index c70881b..395c3a6 100644
--- a/src/noit_check.h
+++ b/src/noit_check.h
@@ -243,7 +243,11 @@ API_EXPORT(void)
                         stats_t *newstate);
 
 API_EXPORT(void)
-  noit_stats_set_metric(stats_t *, const char *, metric_type_t, void *);
+  noit_stats_set_metric(stats_t *, const char *, metric_type_t, const void *);
+
+API_EXPORT(void)
+  noit_stats_set_metric_coerce(stats_t *, const char *, metric_type_t,
+                               const char *);
 
 API_EXPORT(void)
   noit_stats_log_immediate_metric(noit_check_t *check,
diff --git a/src/noit_check_tools.c b/src/noit_check_tools.c
index 7a57901..a0c17e5 100644
--- a/src/noit_check_tools.c
+++ b/src/noit_check_tools.c
@@ -35,6 +35,7 @@
 #include "noit_check_tools.h"
 #include "noit_check_tools_shared.h"
 #include "utils/noit_str.h"
+#include "json-lib/json.h"
 
 #include <assert.h>
 
@@ -152,3 +153,126 @@ noit_check_tools_init() {
   eventer_name_callback("noit_check_recur_handler", noit_check_recur_handler);
 }
 
+static int
+populate_stats_from_resmon_formatted_json(stats_t *s, struct json_object *o,
+                                          const char *prefix) {
+  int count = 0;
+  char keybuff[256];
+#define MKKEY(fmt, arg) do { \
+  if(prefix) snprintf(keybuff, sizeof(keybuff), "%s`" fmt, prefix, arg); \
+  else snprintf(keybuff, sizeof(keybuff), fmt, arg); \
+} while(0)
+  switch(json_object_get_type(o)) {
+    /* sub callers */
+    case json_type_array:
+    {
+      int i, alen = json_object_array_length(o);
+      for(i=0;i<alen;i++) {
+        struct json_object *item = json_object_array_get_idx(o, i);
+        MKKEY("%d", i);
+        count += populate_stats_from_resmon_formatted_json(s, item, keybuff);
+      }
+    }
+    break;
+    case json_type_object:
+    {
+      struct lh_table *lh;
+      struct lh_entry *el;
+      struct json_object *has_type = NULL, *has_value = NULL;
+      lh = json_object_get_object(o);
+      lh_foreach(lh, el) {
+        if(!strcmp(el->k, "_type")) has_type = (struct json_object *)el->v;
+        else if(!strcmp(el->k, "_value")) has_value = (struct json_object *)el->v;
+        else {
+          struct json_object *item = (struct json_object *)el->v;
+          MKKEY("%s", (const char *)el->k);
+          count += populate_stats_from_resmon_formatted_json(s, item, keybuff);
+        }
+      }
+      if(prefix && has_type && has_value &&
+         json_object_is_type(has_type, json_type_string) &&
+         json_object_is_type(has_value, json_type_string)) {
+        const char *type_str = json_object_get_string(has_type);
+        const char *value_str = json_object_get_string(has_value);
+        switch(*type_str) {
+          case METRIC_INT32:
+          case METRIC_UINT32:
+          case METRIC_INT64:
+          case METRIC_UINT64:
+          case METRIC_DOUBLE:
+          case METRIC_STRING:
+            noit_stats_set_metric_coerce(s, prefix,
+                                         (metric_type_t)*type_str, value_str);
+            count++;
+          default:
+            break;
+        }
+      }
+      break;
+    }
+
+    /* directs */
+    case json_type_string:
+      if(prefix) {
+        noit_stats_set_metric(s, prefix, METRIC_GUESS,
+                              (char *)json_object_get_string(o));
+        count++;
+      }
+      break;
+    case json_type_boolean:
+      if(prefix) {
+        int val = json_object_get_boolean(o) ? 1 : 0;
+        noit_stats_set_metric(s, prefix, METRIC_INT32, &val);
+        count++;
+      }
+      break;
+    case json_type_null:
+      if(prefix) {
+        noit_stats_set_metric(s, prefix, METRIC_STRING, NULL);
+        count++;
+      }
+      break;
+    case json_type_double:
+      if(prefix) {
+        double val = json_object_get_double(o);
+        noit_stats_set_metric(s, prefix, METRIC_DOUBLE, &val);
+        count++;
+      }
+      break;
+    case json_type_int:
+      if(prefix) {
+        int64_t i64;
+        uint64_t u64;
+        switch(json_object_get_int_overflow(o)) {
+          case json_overflow_int:
+            i64 = json_object_get_int(o);
+            noit_stats_set_metric(s, prefix, METRIC_INT64, &i64);
+            count++;
+            break;
+          case json_overflow_int64:
+            i64 = json_object_get_int64(o);
+            noit_stats_set_metric(s, prefix, METRIC_INT64, &i64);
+            count++;
+            break;
+          case json_overflow_uint64:
+            u64 = json_object_get_uint64(o);
+            noit_stats_set_metric(s, prefix, METRIC_UINT64, &u64);
+            count++;
+            break;
+        }
+      }
+  }
+  return count;
+}
+int
+noit_check_stats_from_json_str(stats_t *s, const char *json_str, int len) {
+  int rv = -1;
+  struct json_tokener *tok = NULL;
+  struct json_object *root = NULL;
+  tok = json_tokener_new();
+  root = json_tokener_parse_ex(tok, json_str, len);
+  if(root) rv = populate_stats_from_resmon_formatted_json(s, root, NULL);
+  if(tok) json_tokener_free(tok);
+  if(root) json_object_put(root);
+  return rv;
+}
diff --git a/src/noit_check_tools.h b/src/noit_check_tools.h
index 5a6066a..6230c6f 100644
--- a/src/noit_check_tools.h
+++ b/src/noit_check_tools.h
@@ -58,6 +58,9 @@ API_EXPORT(void)
 API_EXPORT(void)
   noit_check_run_full_asynch(noit_check_t *check, eventer_func_t callback);
 
+API_EXPORT(int)
+  noit_check_stats_from_json_str(stats_t *s, const char *json_str, int len);
+
 #define INITIATE_CHECK(func, self, check, cause) do { \
   if(once) { \
     func(self, check, cause); \




hooks/post-receive
-- 
Reconnoiter


More information about the Reconnoiter-devel mailing list