예제 #1
0
xmlNodePtr
noit_check_state_as_xml(noit_check_t *check, int full) {
  xmlNodePtr state, tmp, metrics;
  struct timeval now, *whence;
  stats_t *c = noit_check_get_stats_current(check);

  gettimeofday(&now, NULL);
  state = xmlNewNode(NULL, (xmlChar *)"state");
  NODE_CONTENT(state, "running", NOIT_CHECK_RUNNING(check)?"true":"false");
  NODE_CONTENT(state, "killed", NOIT_CHECK_KILLED(check)?"true":"false");
  NODE_CONTENT(state, "configured",
               NOIT_CHECK_CONFIGURED(check)?"true":"false");
  NODE_CONTENT(state, "disabled", NOIT_CHECK_DISABLED(check)?"true":"false");
  NODE_CONTENT(state, "target_ip", check->target_ip);
  xmlAddChild(state, (tmp = xmlNewNode(NULL, (xmlChar *)"last_run")));
  whence = noit_check_stats_whence(c, NULL);
  if(whence->tv_sec) {
    char timestr[20];
    snprintf(timestr, sizeof(timestr), "%0.3f",
             now.tv_sec + (now.tv_usec / 1000000.0));
    xmlSetProp(tmp, (xmlChar *)"now", (xmlChar *)timestr);
    snprintf(timestr, sizeof(timestr), "%0.3f",
             whence->tv_sec + (whence->tv_usec / 1000000.0));
    xmlNodeAddContent(tmp, (xmlChar *)timestr);
  }
  if(full) {
    stats_t *previous;
    struct timeval *whence;
    uint8_t available = noit_check_stats_available(c, NULL);
    if(available) { /* truth here means the check has been run */
      char buff[20], *compiler_warning;
      snprintf(buff, sizeof(buff), "%0.3f",
               (float)noit_check_stats_duration(c, NULL)/1000.0);
      compiler_warning = buff;
      NODE_CONTENT(state, "runtime", compiler_warning);
    }
    NODE_CONTENT(state, "availability",
                 noit_check_available_string(available));
    NODE_CONTENT(state, "state", noit_check_state_string(noit_check_stats_state(c, NULL)));
    NODE_CONTENT(state, "status", noit_check_stats_status(c, NULL));
    xmlAddChild(state, (metrics = xmlNewNode(NULL, (xmlChar *)"metrics")));

    add_metrics_to_node(noit_check_get_stats_inprogress(check), metrics, "inprogress", 0);
    whence = noit_check_stats_whence(c, NULL);
    if(whence->tv_sec) {
      xmlAddChild(state, (metrics = xmlNewNode(NULL, (xmlChar *)"metrics")));
      add_metrics_to_node(c, metrics, "current", 1);
    }
    previous = noit_check_get_stats_previous(check);
    whence = noit_check_stats_whence(previous, NULL);
    if(whence->tv_sec) {
      xmlAddChild(state, (metrics = xmlNewNode(NULL, (xmlChar *)"metrics")));
      add_metrics_to_node(previous, metrics, "previous", 1);
    }
  }
  return state;
}
예제 #2
0
static int
noit_lua_get_available(lua_State *L) {
  char av[2] = { '\0', '\0' };
  noit_check_t *check;
  stats_t *current;
  if(lua_gettop(L)) luaL_error(L, "wrong number of arguments");
  check = lua_touserdata(L, lua_upvalueindex(1));
  current = noit_check_get_stats_current(check);
  av[0] = (char)noit_check_stats_available(current, NULL);
  lua_pushstring(L, av);
  return 1;
}
예제 #3
0
struct json_object *
noit_check_state_as_json(noit_check_t *check, int full) {
  stats_t *c;
  char seq_str[64];
  char id_str[UUID_STR_LEN+1];
  struct json_object *j_last_run, *j_next_run;
  struct timeval *t;
  u_int64_t ms = 0;
  struct json_object *doc;
  uuid_unparse_lower(check->checkid, id_str);

  doc = json_object_new_object();
  json_object_object_add(doc, "id", json_object_new_string(id_str));
  json_object_object_add(doc, "name", json_object_new_string(check->name));
  json_object_object_add(doc, "module", json_object_new_string(check->module));
  json_object_object_add(doc, "target", json_object_new_string(check->target));
  json_object_object_add(doc, "target_ip", json_object_new_string(check->target_ip));
  json_object_object_add(doc, "filterset", json_object_new_string(check->filterset));
  snprintf(seq_str, sizeof(seq_str), "%lld", (long long)check->config_seq);
  json_object_object_add(doc, "seq", json_object_new_string(seq_str));
  json_object_object_add(doc, "period", json_object_new_int(check->period));
  json_object_object_add(doc, "timeout", json_object_new_int(check->timeout));
  json_object_object_add(doc, "flags", json_object_new_int(check->flags));

  c = noit_check_get_stats_current(check);
  t = noit_check_stats_whence(c, NULL);
  j_last_run = json_object_new_int(ms);
  json_object_set_int_overflow(j_last_run, json_overflow_uint64);
  ms = t->tv_sec;
  ms *= 1000ULL;
  ms += t->tv_usec/1000;
  json_object_set_uint64(j_last_run, ms);
  json_object_object_add(doc, "last_run", j_last_run);

  t = check->fire_event ? &check->fire_event->whence : NULL;
  if(t) {
    j_next_run = json_object_new_int(ms);
    json_object_set_int_overflow(j_next_run, json_overflow_uint64);
    ms = t->tv_sec;
    ms *= 1000ULL;
    ms += t->tv_usec/1000;
    json_object_set_uint64(j_next_run, ms);
    json_object_object_add(doc, "next_run", j_next_run);
  }

  if(full) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *k;
    int klen;
    void *data;
    mtev_hash_table *configh;
    char timestr[20];
    struct json_object *status, *metrics, *config;

    /* config */
    config = json_object_new_object();
    configh = check->config;
    while(mtev_hash_next(configh, &iter, &k, &klen, &data))
      json_object_object_add(config, k, json_object_new_string(data));
    json_object_object_add(doc, "config", config);

    /* status */
    status = json_object_new_object();
    switch(noit_check_stats_available(c, NULL)) {
      case NP_UNKNOWN: break;
      case NP_AVAILABLE:
        json_object_object_add(status, "available", json_object_new_boolean(1));
        break;
      case NP_UNAVAILABLE:
        json_object_object_add(status, "available", json_object_new_boolean(0));
        break;
    }
    switch(noit_check_stats_state(c, NULL)) {
      case NP_UNKNOWN: break;
      case NP_GOOD:
        json_object_object_add(status, "good", json_object_new_boolean(1));
        break;
      case NP_BAD:
        json_object_object_add(status, "good", json_object_new_boolean(0));
        break;
    }
    json_object_object_add(doc, "status", status);
    metrics = json_object_new_object();

    t = noit_check_stats_whence(c, NULL);
    if(t->tv_sec) {
      json_object_object_add(metrics, "current", stats_to_json(c));
      snprintf(timestr, sizeof(timestr), "%llu%03d",
               (unsigned long long int)t->tv_sec, (int)(t->tv_usec / 1000));
      json_object_object_add(metrics, "current_timestamp", json_object_new_string(timestr));
    }

    c = noit_check_get_stats_inprogress(check);
    t = noit_check_stats_whence(c, NULL);
    if(t->tv_sec) {
      json_object_object_add(metrics, "inprogress", stats_to_json(c));
      snprintf(timestr, sizeof(timestr), "%llu%03d",
               (unsigned long long int)t->tv_sec, (int)(t->tv_usec / 1000));
      json_object_object_add(metrics, "inprogress_timestamp", json_object_new_string(timestr));
    }

    c = noit_check_get_stats_previous(check);
    t = noit_check_stats_whence(c, NULL);
    if(t->tv_sec) {
      json_object_object_add(metrics, "previous", stats_to_json(c));
      snprintf(timestr, sizeof(timestr), "%llu%03d",
               (unsigned long long int)t->tv_sec, (int)(t->tv_usec / 1000));
      json_object_object_add(metrics, "previous_timestamp", json_object_new_string(timestr));
    }

    json_object_object_add(doc, "metrics", metrics);
  }
  return doc;
}
예제 #4
0
static int
noit_console_show_check(mtev_console_closure_t ncct,
                        int argc, char **argv,
                        mtev_console_state_t *state, void *closure) {
  int i, cnt;
  mtev_conf_t_userdata_t *info;
  char xpath[1024];
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL;

  mtev_conf_xml_xpath(NULL, &xpath_ctxt);
  if(argc > 1) {
    nc_printf(ncct, "requires zero or one arguments\n");
    return -1;
  }

  info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA);
  /* We many not be in conf-t mode -- that's fine */
  if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info,
                                argc ? argv[0] : NULL)) {
    nc_printf(ncct, "could not find check '%s'\n", argv[0]);
    return -1;
  }

  pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET ||
     xmlXPathNodeSetIsEmpty(pobj->nodesetval)) {
    nc_printf(ncct, "no checks found\n");
    goto out;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  if(info && cnt != 1) {
    nc_printf(ncct, "Ambiguous check specified\n");
    goto out;
  }
  for(i=0; i<cnt; i++) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *k;
    int klen;
    void *data;
    uuid_t checkid;
    noit_check_t *check;
    mtev_hash_table *config;
    xmlNodePtr node, anode, mnode = NULL;
    char *uuid_conf;
    char *module, *value;

    node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid");
    if(!uuid_conf || uuid_parse(uuid_conf, checkid)) {
      nc_printf(ncct, "%s has invalid or missing UUID!\n",
                (char *)xmlGetNodePath(node) + strlen("/noit"));
      continue;
    }
    nc_printf(ncct, "==== %s ====\n", uuid_conf);
    xmlFree(uuid_conf);

#define MYATTR(a,n,b) _mtev_conf_get_string(node, &(n), "@" #a, &(b))
#define INHERIT(a,n,b) \
  _mtev_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b))
#define SHOW_ATTR(a) do { \
  anode = NULL; \
  value = NULL; \
  INHERIT(a, anode, value); \
  nc_attr_show(ncct, #a, node, anode, value); \
  if(value != NULL) free(value); \
} while(0)

    if(!INHERIT(module, mnode, module)) module = NULL;
    if(MYATTR(name, anode, value)) {
      nc_printf(ncct, " name: %s\n", value);
      free(value);
    }
    else
      nc_printf(ncct, " name: %s [from module]\n", module ? module : "[undef]");
    nc_attr_show(ncct, "module", node, mnode, module);
    if(module) free(module);
    SHOW_ATTR(target);
    SHOW_ATTR(seq);
    SHOW_ATTR(resolve_rtype);
    SHOW_ATTR(period);
    SHOW_ATTR(timeout);
    SHOW_ATTR(oncheck);
    SHOW_ATTR(filterset);
    SHOW_ATTR(disable);
    /* Print out all the config settings */
    config = mtev_conf_get_hash(node, "config");
    while(mtev_hash_next(config, &iter, &k, &klen, &data)) {
      nc_printf(ncct, " config::%s: %s\n", k, (const char *)data);
    }
    mtev_hash_destroy(config, free, free);
    free(config);

    check = noit_poller_lookup(checkid);
    if(!check) {
      nc_printf(ncct, " ERROR: not in running system\n");
    }
    else {
      int idx = 0;
      stats_t *c;
      struct timeval *whence;
      mtev_hash_table *metrics;
      nc_printf(ncct, " target_ip: %s\n", check->target_ip);
      nc_printf(ncct, " currently: %08x ", check->flags);
      if(NOIT_CHECK_RUNNING(check)) { nc_printf(ncct, "running"); idx++; }
      if(NOIT_CHECK_KILLED(check)) nc_printf(ncct, "%skilled", idx++?",":"");
      if(!NOIT_CHECK_CONFIGURED(check)) nc_printf(ncct, "%sunconfig", idx++?",":"");
      if(NOIT_CHECK_DISABLED(check)) nc_printf(ncct, "%sdisabled", idx++?",":"");
      if(!idx) nc_printf(ncct, "idle");
      nc_write(ncct, "\n", 1);
      if (check->fire_event != NULL) {
        struct timeval now, diff;
        mtev_gettimeofday(&now, NULL);
        sub_timeval(check->fire_event->whence, now, &diff);
        nc_printf(ncct, " next run: %0.3f seconds\n",
                diff.tv_sec + (diff.tv_usec / 1000000.0));
      }
      else {
        nc_printf(ncct, " next run: unscheduled\n");
      }

      c = noit_check_get_stats_current(check);
      whence = noit_check_stats_whence(c, NULL);
      if(whence->tv_sec == 0) {
        nc_printf(ncct, " last run: never\n");
      }
      else {
        const char *status;
        struct timeval now, *then, diff;
        mtev_gettimeofday(&now, NULL);
        then = noit_check_stats_whence(c, NULL);
        sub_timeval(now, *then, &diff);
        nc_printf(ncct, " last run: %0.3f seconds ago\n",
                  diff.tv_sec + (diff.tv_usec / 1000000.0));
        nc_printf(ncct, " availability/state: %s/%s\n",
                  noit_check_available_string(noit_check_stats_available(c, NULL)),
                  noit_check_state_string(noit_check_stats_state(c, NULL)));
        status = noit_check_stats_status(c, NULL);
        nc_printf(ncct, " status: %s\n", status);
        nc_printf(ncct, " feeds: %d\n", check->feeds ? check->feeds->size : 0);
      }

      c = noit_check_get_stats_inprogress(check);
      metrics = noit_check_stats_metrics(c);
      if(mtev_hash_size(metrics) > 0) {
        nc_printf(ncct, " metrics (inprogress):\n");
        nc_print_stat_metrics(ncct, check, c);
      }
      c = noit_check_get_stats_current(check);
      metrics = noit_check_stats_metrics(c);
      if(mtev_hash_size(metrics)) {
        nc_printf(ncct, " metrics (current):\n");
        nc_print_stat_metrics(ncct, check, c);
      }
      c = noit_check_get_stats_previous(check);
      metrics = noit_check_stats_metrics(c);
      if(mtev_hash_size(metrics) > 0) {
        nc_printf(ncct, " metrics (previous):\n");
        nc_print_stat_metrics(ncct, check, c);
      }
    }
  }
 out:
  if(pobj) xmlXPathFreeObject(pobj);
  return 0;
}