[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