Example #1
0
static struct json_object *
stats_to_json(stats_t *c) {
  struct json_object *doc;
  doc = json_object_new_object();
  mtev_hash_table *metrics;
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;

  metrics = noit_check_stats_metrics(c);
  while(mtev_hash_next(metrics, &iter, &k, &klen, &data)) {
    char buff[256];
    metric_t *m = (metric_t *)data;
    struct json_object *metric = json_object_new_object();
    buff[0] = m->metric_type; buff[1] = '\0';
    json_object_object_add(metric, "_type", json_object_new_string(buff));
    if(m->metric_value.s) {
      int rv;
      rv = noit_stats_snprint_metric_value(buff, sizeof(buff), m);
      if(rv >= 0)
        json_object_object_add(metric, "_value", json_object_new_string(buff));
    }
    json_object_object_add(doc, m->metric_name, metric);
  }
  return doc;
}
Example #2
0
static int do_test(mtev_hash_lock_mode_t lock_mode) {
  mtev_hash_table hash;

  mtev_hash_init_locks(&hash, 400, lock_mode);

  pthread_t threads[THREAD_COUNT];
  for (int i = 0; i < THREAD_COUNT; i++) {
    pthread_create(&threads[i], NULL, thread_func, &hash);
  }

  for (int i = 0; i < THREAD_COUNT; i++) {
    pthread_join(threads[i], NULL);
  }

  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;

  const char *k;
  int klen;
  void *data;

  while(mtev_hash_next(&hash, &iter, &k, &klen, &data)) {
    printf("%s\n", k);
  }

  mtev_hash_destroy(&hash, free, NULL);
  return 0;
}
static void
nc_print_stat_metrics(mtev_console_closure_t ncct,
                      noit_check_t *check, stats_t *c) {
  int mcount=0, cnt=0;
  const char **sorted_keys;
  char buff[256];
  mtev_boolean filtered;
  mtev_hash_table *metrics;
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;

  metrics = noit_check_stats_metrics(c);
  memset(&iter, 0, sizeof(iter));
  while(mtev_hash_next(metrics, &iter, &k, &klen, &data)) cnt++;
  sorted_keys = malloc(cnt * sizeof(*sorted_keys));
  memset(&iter, 0, sizeof(iter));
  while(mtev_hash_next(metrics, &iter, &k, &klen, &data)) {
    if(sorted_keys && mcount < cnt) sorted_keys[mcount++] = k;
    else {
      noit_stats_snprint_metric(buff, sizeof(buff), (metric_t *)data);
      filtered = !noit_apply_filterset(check->filterset, check, (metric_t *)data);
      nc_printf(ncct, "  %c%s\n", filtered ? '*' : ' ', buff);
    }
  }
  if(sorted_keys) {
    int j;
    qsort(sorted_keys, mcount, sizeof(*sorted_keys),
          _qsort_string_compare);
    for(j=0;j<mcount;j++) {
      if(mtev_hash_retrieve(metrics,
                            sorted_keys[j], strlen(sorted_keys[j]),
                            &data)) {
        noit_stats_snprint_metric(buff, sizeof(buff), (metric_t *)data);
        filtered = !noit_apply_filterset(check->filterset, check, (metric_t *)data);
        nc_printf(ncct, "  %c%s\n", filtered ? '*' : ' ', buff);
      }
    }
    free(sorted_keys);
  }
}
Example #4
0
int mtev_hash_next_str(mtev_hash_table *h, mtev_hash_iter *iter,
                       const char **k, int *klen, const char **dstr) {
  void *data = NULL;
  int rv;
  /* Leave this hash_next for ABI safety.
   * (this mtev_hash_iter could be too small)
   */
  rv = mtev_hash_next(h,iter,k,klen,&data);
  *dstr = data;
  return rv;
}
int
noit_jlog_foreach_feed_stats(int (*f)(jlog_feed_stats_t *, void *),
                             void *c) {
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *key;
  int klen, cnt = 0;
  void *vs;
  while(mtev_hash_next(&feed_stats, &iter, &key, &klen, &vs)) {
    cnt += f((jlog_feed_stats_t *)vs, c);
  }
  return cnt;
}
Example #6
0
static void
heartbeat_all_metrics(struct histogram_config *conf,
                      noit_check_t *check, mtev_hash_table *metrics) {
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  u_int64_t s = time(NULL);
  while(mtev_hash_next(metrics, &iter, &k, &klen, &data)) {
    histotier *ht = data;
    update_histotier(ht, s, conf, check, k, 0, 0);
  }
}
static int
prune_old_dedupe_hashes(eventer_t e, int mask, void *unused,
    struct timeval *now) {

  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  uint64_t now_hrtime = mtev_gethrtime() / 1000000000;
  const char *k;
  int klen;
  void *data;
  struct hash_and_time *hash_with_time;

  struct removable_hashes {
    uint64_t key;
    struct hash_and_time *data;
    struct removable_hashes *next;
  };

  struct removable_hashes *head = NULL;
  struct removable_hashes *tail = NULL;

  /* build a list of expirable items */
  while(mtev_hash_next(&dedupe_hashes, &iter, &k, &klen, &data)) {
    hash_with_time = data;
    if (now_hrtime > hash_with_time->last_touched_s && now_hrtime - hash_with_time->last_touched_s > 10) {
      struct removable_hashes *h = calloc(1, sizeof(struct removable_hashes));
      h->key = *(uint64_t *)k;
      h->data = hash_with_time;
      if (tail != NULL) {
        tail->next = h;
      }
      tail = h;

      if (head == NULL) {
        head = tail;
      }
    }
  }

  /* expire them */
  while (head != NULL) {
    mtev_hash_delete(&dedupe_hashes, (const char *)&head->key, sizeof(head->key), free, NULL);
    mtev_hash_destroy(&head->data->hash, free, NULL);
    free(head->data);
    struct removable_hashes *prev = head;
    head = head->next;
    free(prev);
  }

  e->whence.tv_sec = now->tv_sec + 5;
  return 1;
}
Example #8
0
static void noit_fq_free_metric_hash(void *d) {
  mtev_hash_table *metrics_table = (mtev_hash_table *)d;
  if (metrics_table) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    void *entry;
    const char *key;
    int klen;

    while(mtev_hash_next(metrics_table, &iter, &key, &klen, &entry)) {
      if (key) free((char *)key);
      if (entry) free ((void *)entry);
    }
    
  }
  free(metrics_table);
}
Example #9
0
static void
histogram_sweep_calculations(struct histogram_config *conf, noit_check_t *check) {
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *metric_name;
  int klen;
  void *data;
  mtev_hash_table *metrics;
  stats_t *c;
  double *out_q;

  c = noit_check_get_stats_current(check);
  /* Only need to do work if it's asked for */
  if(!conf->mean && !conf->sum && conf->n_quantiles < 1) return;
  metrics = noit_check_get_module_metadata(check, histogram_module_id);
  if(!metrics) return;
  out_q = alloca(sizeof(double *) * conf->n_quantiles);

  u_int64_t s = time(NULL);
  while(mtev_hash_next(metrics, &iter, &metric_name, &klen, &data)) {
    char mname[1024];
    histotier *ht = data;
    if(ht->last_aggr == NULL) continue;
    if(conf->mean) {
      double mean_value;
      snprintf(mname, sizeof(mname), "%s:mean", metric_name);
      mean_value = hist_approx_mean(ht->last_aggr);
      noit_stats_set_metric(check, mname, METRIC_DOUBLE, &mean_value);
    }
    if(conf->sum) {
      double sum;
      snprintf(mname, sizeof(mname), "%s:sum", metric_name);
      sum = hist_approx_sum(ht->last_aggr);
      noit_stats_set_metric(check, mname, METRIC_DOUBLE, &sum);
    }
    if(conf->n_quantiles) {
      if(hist_approx_quantile(ht->last_aggr,
           conf->quantiles, conf->n_quantiles, out_q) == 0) {
        int i;
        for(i=0;i<conf->n_quantiles;i++) {
          snprintf(mname, sizeof(mname), "%s:q(%0.5f)", metric_name, conf->quantiles[i]);
          noit_stats_set_metric(check, mname, METRIC_DOUBLE, &out_q[i]);
        }
      }
    }
  }
}
Example #10
0
int
mtev_dso_list(mtev_hash_table *t, const char ***f) {
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *name;
  int klen, i = 0;
  void *vhdr;

  if(mtev_hash_size(t) == 0) {
    *f = NULL;
    return 0;
  }

  *f = calloc(mtev_hash_size(t), sizeof(**f));
  while(mtev_hash_next(t, &iter, (const char **)&name, &klen,
                       &vhdr)) {
    (*f)[i++] = name;
  }
  return i;
}
Example #11
0
static void
add_metrics_to_node(stats_t *c, xmlNodePtr metrics, const char *type,
                    int include_time) {
  mtev_hash_table *mets;
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  xmlNodePtr tmp;

  mets = noit_check_stats_metrics(c);
  while(mtev_hash_next(mets, &iter, &k, &klen, &data)) {
    char buff[256];
    metric_t *m = (metric_t *)data;
    xmlAddChild(metrics, (tmp = xmlNewNode(NULL, (xmlChar *)"metric")));
    xmlSetProp(tmp, (xmlChar *)"name", (xmlChar *)m->metric_name);
    buff[0] = m->metric_type; buff[1] = '\0';
    xmlSetProp(tmp, (xmlChar *)"type", (xmlChar *)buff);
    if(m->metric_value.s) {
      int rv;
      rv = noit_stats_snprint_metric_value(buff, sizeof(buff), m);
      if(rv < 0)
        xmlSetProp(tmp, (xmlChar *)"error", (xmlChar *)"unknown type");
      else
        xmlNodeAddContent(tmp, (xmlChar *)buff);
    }
  }
  xmlSetProp(metrics, (xmlChar *)"type", (const xmlChar *) type);
  if(include_time) {
    struct timeval *f = noit_check_stats_whence(c, NULL);
    char timestr[20];
    snprintf(timestr, sizeof(timestr), "%0.3f",
             f->tv_sec + (f->tv_usec / 1000000.0));
    xmlSetProp(metrics, (xmlChar *)"timestamp", (xmlChar *)timestr);
  }
}
static void
mtev_capabilities_tobuff(mtev_capsvc_closure_t *cl, eventer_func_t curr) {
    const char **mod_names;
    struct utsname utsn;
    char vbuff[128], bwstr[4];
    mtev_hash_table *lc;
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *k;
    int klen, i, nmods;
    void *data;
    struct timeval now;
    struct dso_type *t;

    xmlDocPtr xmldoc;
    xmlNodePtr root, cmds, bi, ri, mods, feat;

    /* fill out capabilities */

    /* Create an XML Document */
    xmldoc = xmlNewDoc((xmlChar *)"1.0");
    root = xmlNewDocNode(xmldoc, NULL, (xmlChar *)capabilities_namespace, NULL);
    xmlDocSetRootElement(xmldoc, root);

    /* Fill in the document */
    mtev_build_version(vbuff, sizeof(vbuff));
    xmlNewTextChild(root, NULL, (xmlChar *)"version", (xmlChar *)vbuff);

    snprintf(bwstr, sizeof(bwstr), "%d", (int)sizeof(void *)*8);
    /* Build info */
    bi = xmlNewNode(NULL, (xmlChar *)"unameBuild");
    xmlSetProp(bi, (xmlChar *)"bitwidth", (xmlChar *)bwstr);
    xmlAddChild(root, bi);
    xmlNewTextChild(bi, NULL, (xmlChar *)"sysname", (xmlChar *)UNAME_S);
    xmlNewTextChild(bi, NULL, (xmlChar *)"nodename", (xmlChar *)UNAME_N);
    xmlNewTextChild(bi, NULL, (xmlChar *)"release", (xmlChar *)UNAME_R);
    xmlNewTextChild(bi, NULL, (xmlChar *)"version", (xmlChar *)UNAME_V);
    xmlNewTextChild(bi, NULL, (xmlChar *)"machine", (xmlChar *)UNAME_M);

    /* Run info */
    ri = xmlNewNode(NULL, (xmlChar *)"unameRun");
    xmlSetProp(ri, (xmlChar *)"bitwidth", (xmlChar *)bwstr);
    xmlAddChild(root, ri);
    if(uname(&utsn) < 0) {
      xmlNewTextChild(ri, NULL, (xmlChar *)"error", (xmlChar *)strerror(errno));
    } else {
      xmlNewTextChild(ri, NULL, (xmlChar *)"sysname", (xmlChar *)utsn.sysname);
      xmlNewTextChild(ri, NULL, (xmlChar *)"nodename", (xmlChar *)utsn.nodename);
      xmlNewTextChild(ri, NULL, (xmlChar *)"release", (xmlChar *)utsn.release);
      xmlNewTextChild(ri, NULL, (xmlChar *)"version", (xmlChar *)utsn.version);
      xmlNewTextChild(ri, NULL, (xmlChar *)"machine", (xmlChar *)utsn.machine);
    }

    /* features */
    feat = xmlNewNode(NULL, (xmlChar *)"features");
    xmlAddChild(root, feat);
    if(mtev_hash_size(&features)) {
      mtev_hash_iter iter2 = MTEV_HASH_ITER_ZERO;
      void *vfv;
      const char *f;
      int flen;
      while(mtev_hash_next(&features, &iter2, &f, &flen, &vfv)) {
        xmlNodePtr featnode;
        featnode = xmlNewNode(NULL, (xmlChar *)"feature");
        xmlSetProp(featnode, (xmlChar *)"name", (xmlChar *)f);
        if(vfv) xmlSetProp(featnode, (xmlChar *)"version", (xmlChar *)vfv);
        xmlAddChild(feat, featnode);
      }
    }

    /* time (poor man's time check) */
    gettimeofday(&now, NULL);
    snprintf(vbuff, sizeof(vbuff), "%llu.%03d", (unsigned long long)now.tv_sec,
             (int)(now.tv_usec / 1000));
    xmlNewTextChild(root, NULL, (xmlChar *)"current_time", (xmlChar *)vbuff);

    cmds = xmlNewNode(NULL, (xmlChar *)"services");
    xmlAddChild(root, cmds);
    lc = mtev_listener_commands();
    while(mtev_hash_next(lc, &iter, &k, &klen, &data)) {
      xmlNodePtr cnode;
      char hexcode[11];
      const char *name;
      eventer_func_t *f = (eventer_func_t *)k;
      mtev_hash_table *sc = (mtev_hash_table *)data;
      mtev_hash_iter sc_iter = MTEV_HASH_ITER_ZERO;
      const char *sc_k;
      int sc_klen;
      void *sc_data;

      name = eventer_name_for_callback(*f);
      cnode = xmlNewNode(NULL, (xmlChar *)"service");
      xmlSetProp(cnode, (xmlChar *)"name", name ? (xmlChar *)name : NULL);
      if(*f == curr)
        xmlSetProp(cnode, (xmlChar *)"connected", (xmlChar *)"true");
      xmlAddChild(cmds, cnode);
      while(mtev_hash_next(sc, &sc_iter, &sc_k, &sc_klen, &sc_data)) {
        xmlNodePtr scnode;
        char *name_copy, *version = NULL;
        eventer_func_t *f = (eventer_func_t *)sc_data;

        snprintf(hexcode, sizeof(hexcode), "0x%08x", *((u_int32_t *)sc_k));
        name = eventer_name_for_callback(*f);
        name_copy = strdup(name ? name : "[[unknown]]");
        version = strchr(name_copy, '/');
        if(version) *version++ = '\0';

        scnode = xmlNewNode(NULL, (xmlChar *)"command");
        xmlSetProp(scnode, (xmlChar *)"name", (xmlChar *)name_copy);
        if(version)
          xmlSetProp(scnode, (xmlChar *)"version", (xmlChar *)version);
        xmlSetProp(scnode, (xmlChar *)"code", (xmlChar *)hexcode);
        xmlAddChild(cnode, scnode);
        free(name_copy);
      }
    }

    mods = xmlNewNode(NULL, (xmlChar *)"modules");
    xmlAddChild(root, mods);

#define list_modules(func, name) do { \
    nmods = func(&mod_names); \
    for(i=0; i<nmods; i++) { \
      xmlNodePtr pnode; \
      pnode = xmlNewNode(NULL, (xmlChar *)"module"); \
      xmlSetProp(pnode, (xmlChar *)"type", (xmlChar *)name); \
      xmlSetProp(pnode, (xmlChar *)"name", (xmlChar *)mod_names[i]); \
      xmlAddChild(mods, pnode); \
    } \
    if(mod_names) free(mod_names); \
} while(0)
    for(t = mtev_dso_get_types(); t; t = t->next)
      list_modules(t->list, t->name);

    /* Write it out to a buffer and copy it for writing */
    cl->buff = mtev_xmlSaveToBuffer(xmldoc);
    cl->towrite = strlen(cl->buff);

    /* Clean up after ourselves */
    xmlFreeDoc(xmldoc);
}
Example #13
0
static int
rest_show_check(mtev_http_rest_closure_t *restc,
                int npats, char **pats) {
  mtev_http_session_ctx *ctx = restc->http_ctx;
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL;
  xmlDocPtr doc = NULL;
  xmlNodePtr node, root, attr, config, state, tmp, anode;
  uuid_t checkid;
  noit_check_t *check;
  char xpath[1024], *uuid_conf, *module = NULL, *value = NULL;
  int rv, mod, mod_cnt, cnt, error_code = 500;
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  mtev_hash_table *configh;

  if(npats != 2 && npats != 3) goto error;

  rv = noit_check_xpath(xpath, sizeof(xpath), pats[0], pats[1]);
  if(rv == 0) goto not_found;
  if(rv < 0) goto error;

  mtev_conf_xml_xpath(NULL, &xpath_ctxt);
  pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET ||
     xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto not_found;
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  if(cnt != 1) goto error;

  node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
  uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid");
  if(!uuid_conf || uuid_parse(uuid_conf, checkid)) goto error;

  if(npats == 3 && !strcmp(pats[2], ".json")) {
    return rest_show_check_json(restc, checkid);
  }

  doc = xmlNewDoc((xmlChar *)"1.0");
  root = xmlNewDocNode(doc, NULL, (xmlChar *)"check", NULL);
  xmlDocSetRootElement(doc, root);

#define MYATTR(node,a,n,b) _mtev_conf_get_string(node, &(n), "@" #a, &(b))
#define INHERIT(node,a,n,b) \
  _mtev_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b))
#define SHOW_ATTR(parent, node, a) do { \
  char *_value = NULL; \
  INHERIT(node, a, anode, _value); \
  if(_value != NULL) { \
    int clen, plen;\
    char *_cpath, *_apath; \
    xmlNodePtr child; \
    _cpath = node ? (char *)xmlGetNodePath(node) : strdup(""); \
    _apath = anode ? (char *)xmlGetNodePath(anode) : strdup(""); \
    clen = strlen(_cpath); \
    plen = strlen("/noit/checks"); \
    child = xmlNewNode(NULL, (xmlChar *)#a); \
    xmlNodeAddContent(child, (xmlChar *)_value); \
    if(!strncmp(_cpath, _apath, clen) && _apath[clen] == '/') { \
    } \
    else { \
      xmlSetProp(child, (xmlChar *)"inherited", (xmlChar *)_apath+plen); \
    } \
    xmlAddChild(parent, child); \
    free(_cpath); \
    free(_apath); \
    free(_value); \
  } \
} while(0)

  attr = xmlNewNode(NULL, (xmlChar *)"attributes");
  xmlAddChild(root, attr);

  SHOW_ATTR(attr,node,uuid);
  SHOW_ATTR(attr,node,seq);

  /* Name is odd, it falls back transparently to module */
  if(!INHERIT(node, module, tmp, module)) module = NULL;
  xmlAddChild(attr, (tmp = xmlNewNode(NULL, (xmlChar *)"name")));
  if(MYATTR(node, name, anode, value))
    xmlNodeAddContent(tmp, (xmlChar *)value);
  else if(module)
    xmlNodeAddContent(tmp, (xmlChar *)module);
  if(value) free(value);
  if(module) free(module);

  SHOW_ATTR(attr,node,module);
  SHOW_ATTR(attr,node,target);
  SHOW_ATTR(attr,node,resolve_rtype);
  SHOW_ATTR(attr,node,seq);
  SHOW_ATTR(attr,node,period);
  SHOW_ATTR(attr,node,timeout);
  SHOW_ATTR(attr,node,oncheck);
  SHOW_ATTR(attr,node,filterset);
  SHOW_ATTR(attr,node,disable);

  /* Add the config */
  config = xmlNewNode(NULL, (xmlChar *)"config");
  configh = mtev_conf_get_hash(node, "config");
  while(mtev_hash_next(configh, &iter, &k, &klen, &data))
    NODE_CONTENT(config, k, data);
  mtev_hash_destroy(configh, free, free);
  free(configh);

  mod_cnt = noit_check_registered_module_cnt();
  for(mod=0; mod<mod_cnt; mod++) {
    xmlNsPtr ns;
    const char *nsname;
    char buff[256];

    nsname = noit_check_registered_module(mod);
 
    snprintf(buff, sizeof(buff), "noit://module/%s", nsname);
    ns = xmlSearchNs(root->doc, root, (xmlChar *)nsname);
    if(!ns) ns = xmlNewNs(root, (xmlChar *)buff, (xmlChar *)nsname);
    if(ns) {
      configh = mtev_conf_get_namespaced_hash(node, "config", nsname);
      if(configh) {
        memset(&iter, 0, sizeof(iter));
        while(mtev_hash_next(configh, &iter, &k, &klen, &data)) {
          NS_NODE_CONTENT(config, ns, "value", data,
            xmlSetProp(tmp, (xmlChar *)"name", (xmlChar *)k);
          );
        }
        mtev_hash_destroy(configh, free, free);
        free(configh);
      }
    }
  }
Example #14
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;
}
Example #15
0
static int
rest_httptrap_handler(mtev_http_rest_closure_t *restc,
                      int npats, char **pats) {
  int mask, complete = 0, cnt;
  struct rest_json_payload *rxc = NULL;
  const char *error = "internal error", *secret = NULL;
  mtev_http_session_ctx *ctx = restc->http_ctx;
  const unsigned int DEBUGDATA_OUT_SIZE=4096;
  const unsigned int JSON_OUT_SIZE=DEBUGDATA_OUT_SIZE+128;
  char json_out[JSON_OUT_SIZE];
  char debugdata_out[DEBUGDATA_OUT_SIZE];
  int debugflag=0;
  const char *debugchkflag;
  noit_check_t *check;
  uuid_t check_id;
  mtev_http_request *req;
  mtev_hash_table *hdrs;

  if(npats != 2) {
    error = "bad uri";
    goto error;
  }
  if(uuid_parse(pats[0], check_id)) {
    error = "uuid parse error";
    goto error;
  }

  if(restc->call_closure == NULL) {
    mtev_boolean allowed = mtev_false;
    httptrap_closure_t *ccl = NULL;
    const char *delimiter = NULL;
    rxc = restc->call_closure = calloc(1, sizeof(*rxc));
    rxc->delimiter = DEFAULT_HTTPTRAP_DELIMITER;
    check = noit_poller_lookup(check_id);
    if(!check) {
      error = "no such check";
      goto error;
    }
    if(!httptrap_surrogate && strcmp(check->module, "httptrap")) {
      error = "no such httptrap check";
      goto error;
    }
 
    /* check "secret" then "httptrap_secret" as a fallback */
    (void)mtev_hash_retr_str(check->config, "secret", strlen("secret"), &secret);
    if(!secret) (void)mtev_hash_retr_str(check->config, "httptrap_secret", strlen("httptrap_secret"), &secret);
    if(secret && !strcmp(pats[1], secret)) allowed = mtev_true;
    if(!allowed && cross_module_reverse_allowed(check, pats[1])) allowed = mtev_true;

    if(!allowed) {
      error = "secret mismatch";
      goto error;
    }

    /* check "delimiter" then "httptrap_delimiter" as a fallback */
    (void)mtev_hash_retr_str(check->config, "delimiter", strlen("delimiter"), &delimiter);
    if(!delimiter) (void)mtev_hash_retr_str(check->config, "httptrap_delimiter", strlen("httptrap_delimiter"), &delimiter);
    if(delimiter && *delimiter) rxc->delimiter = *delimiter;
    rxc->check = check;
    uuid_copy(rxc->check_id, check_id);
    rxc->parser = yajl_alloc(&httptrap_yajl_callbacks, NULL, rxc);
    rxc->depth = -1;
    yajl_config(rxc->parser, yajl_allow_comments, 1);
    yajl_config(rxc->parser, yajl_dont_validate_strings, 1);
    yajl_config(rxc->parser, yajl_allow_trailing_garbage, 1);
    yajl_config(rxc->parser, yajl_allow_partial_values, 1);
    restc->call_closure_free = rest_json_payload_free;
  }
  else rxc = restc->call_closure;

  /* flip threads */
  {
    mtev_http_connection *conn = mtev_http_session_connection(ctx);
    eventer_t e = mtev_http_connection_event(conn);
    if(e) {
      pthread_t tgt = CHOOSE_EVENTER_THREAD_FOR_CHECK(rxc->check);
      if(!pthread_equal(e->thr_owner, tgt)) {
        e->thr_owner = tgt;
        return EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION;
      }
    }
  }

  rxc = rest_get_json_upload(restc, &mask, &complete);
  if(rxc == NULL && !complete) return mask;

  if(!rxc) goto error;
  if(rxc->error) goto error;

  cnt = rxc->cnt;

  mtev_http_response_status_set(ctx, 200, "OK"); 
  mtev_http_response_header_set(ctx, "Content-Type", "application/json");
  mtev_http_response_option_set(ctx, MTEV_HTTP_CLOSE); 
  
  /*Examine headers for x-circonus-httptrap-debug flag*/
  req = mtev_http_session_request(ctx);
  hdrs = mtev_http_request_headers_table(req); 
    
  /*Check if debug header passed in. If present and set to true, set debugflag value to one.*/
  if(mtev_hash_retr_str(hdrs, "x-circonus-httptrap-debug", strlen("x-circonus-httptrap-debug"), &debugchkflag))
  {
    if (strcmp(debugchkflag,"true")==0)
    {
      debugflag=1;
    }
  }
   
  /*If debugflag remains zero, simply output the number of metrics.*/
  if (debugflag==0)
  {
    snprintf(json_out, sizeof(json_out),
           "{ \"stats\": %d }", cnt);    
  }
  
  /*Otherwise, if set to one, output current metrics in addition to number of current metrics.*/
  else if (debugflag==1)
  {        
      stats_t *c;
      mtev_hash_table *metrics;
        
      /*Retrieve check information.*/        
      check = noit_poller_lookup(check_id);
      c = noit_check_get_stats_current(check);
      metrics = noit_check_stats_metrics(c);
      mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
      const char *k;
      int klen;
      void *data;
      int written=0;
      int offset=0;
      memset(debugdata_out,'\0',sizeof(debugdata_out));
      
      /*Extract metrics*/
      while(mtev_hash_next(metrics, &iter, &k, &klen, &data))
      {
        char buff[256];
        int toWrite = DEBUGDATA_OUT_SIZE-offset;
        metric_t *tmp=(metric_t *)data;
        char *metric_name=tmp->metric_name;
        metric_type_t metric_type=tmp->metric_type;
        noit_stats_snprint_metric_value(buff, sizeof(buff), tmp);
        written = snprintf(debugdata_out + offset, toWrite, "\"%s\": {\"_type\":\"%c\",\"_value\":\"%s\"},", metric_name,metric_type,buff);
        if(toWrite < written) 
        {
            break;
        }
        offset += written;
      }
        
      /*Set last character to empty-don't want extra comma in output*/
      if (offset>1)
      {
        snprintf(debugdata_out + (offset-1), 1, "%s"," ");
      }
      
      /*Output stats and metrics.*/
      snprintf(json_out, sizeof(json_out)+strlen(debugdata_out),
             "{ \"stats\": %d, \"metrics\": {%s } }", cnt, debugdata_out);
  }

  mtev_http_response_append(ctx, json_out, strlen(json_out));
  mtev_http_response_end(ctx);
  return 0;

 error:
  mtev_http_response_server_error(ctx, "application/json");
  mtev_http_response_append(ctx, "{ \"error\": \"", 12);
  if(rxc && rxc->error) error = rxc->error;
  mtev_http_response_append(ctx, error, strlen(error));
  mtev_http_response_append(ctx, "\" }", 3);
  mtev_http_response_end(ctx);
  return 0;
}
Example #16
0
static int
stratcon_datastore_journal_sync(eventer_t e, int mask, void *closure,
                                struct timeval *now) {
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *vij;
  interim_journal_t *ij;
  syncset_t *syncset = closure;

  if((mask & EVENTER_ASYNCH) == EVENTER_ASYNCH) {
    if(syncset->completion) {
      eventer_add(syncset->completion);
      eventer_trigger(syncset->completion, EVENTER_READ | EVENTER_WRITE);
    }
    free(syncset);
    return 0;
  }
  if(!((mask & EVENTER_ASYNCH_WORK) == EVENTER_ASYNCH_WORK)) return 0;

  mtevL(ds_deb, "Syncing journal sets...\n");
  if (syncset->ws) {
    while(mtev_hash_next(syncset->ws, &iter, &k, &klen, &vij)) {
      char tmppath[PATH_MAX], id_str[32];
      int suffix_idx;
      ij = vij;
      mtevL(ds_deb, "Syncing journal set [%s,%s,%s]\n",
            ij->remote_str, ij->remote_cn, ij->fqdn);
      strlcpy(tmppath, ij->filename, sizeof(tmppath));
      suffix_idx = strlen(ij->filename) - 4; /* . t m p */
      ij->filename[suffix_idx] = '\0';
      if(rename(tmppath, ij->filename) != 0) {
        if(errno == EEXIST) {
          unlink(ij->filename);
          if(rename(tmppath, ij->filename) != 0) goto rename_failed;
        }
        else {
         rename_failed:
          mtevL(noit_error, "rename failed(%s): (%s->%s)\n", strerror(errno),
                tmppath, ij->filename);
          exit(-1);
        }
      }
      if(ij->fd >= 0) {
        fsync(ij->fd);
        close(ij->fd);
      }
      ij->fd = -1;
      snprintf(id_str, sizeof(id_str), "%d", ij->storagenode_id);
      stratcon_ingest(ij->filename, ij->remote_str,
                      ij->remote_cn, id_str,
                      mtev_false);
    }
    mtev_hash_destroy(syncset->ws, free, interim_journal_free);
    free(syncset->ws);
  }
  else {
    mtevL(noit_error, "attempted to sync non-existing working set\n");
  }

  return 0;
}
Example #17
0
static int
noit_console_config_show(mtev_console_closure_t ncct,
                         int argc, char **argv,
                         mtev_console_state_t *state, void *closure) {
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  int i, cnt, titled = 0, cliplen = 0;
  const char *path = "", *basepath = NULL;
  char xpath[1024];
  mtev_conf_t_userdata_t *info = NULL;
  mtev_hash_table *config;
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt;
  xmlDocPtr master_config = NULL;
  xmlNodePtr node = NULL;

  mtev_conf_xml_xpath(&master_config, &xpath_ctxt);
  if(argc > 1) {
    nc_printf(ncct, "too many arguments\n");
    return -1;
  }

  info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA);
  if(info && info->path) path = basepath = info->path;
  if(!info && argc == 0) {
    nc_printf(ncct, "argument required when not in configuration mode\n");
    return -1;
  }

  if(argc == 1) path = argv[0];
  if(!basepath) basepath = path;

  /* { / } is a special case */
  if(!strcmp(basepath, "/")) basepath = "";
  if(!strcmp(path, "/")) path = "";

  if(!master_config) {
    nc_printf(ncct, "no config\n");
    return -1;
  }

  /* { / } is the only path that will end with a /
   * in XPath { / / * } means something _entirely different than { / * }
   * Ever notice how it is hard to describe xpath in C comments?
   */
  /* We don't want to show the root node */
  cliplen = strlen("/noit/");

  /* If we are in configuration mode
   * and we are without an argument or the argument is absolute,
   * clip the current path off */
  if(info && (argc == 0 || path[0] != '/')) cliplen += strlen(basepath);
  if(!path[0] || path[0] == '/') /* base only, or absolute path requested */
    snprintf(xpath, sizeof(xpath), "/noit%s/@*", path);
  else
    snprintf(xpath, sizeof(xpath), "/noit%s/%s/@*", basepath, path);

  current_ctxt = xpath_ctxt;
  pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET) {
    nc_printf(ncct, "no such object\n");
    goto bad;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  titled = 0;
  for(i=0; i<cnt; i++) {
    node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "check")) continue;
    if(node->children && node->children == xmlGetLastChild(node) &&
      xmlNodeIsText(node->children)) {
      char *node_str, *xmlpath;
      node_str = (char *)xmlXPathCastNodeToString(node->children);
      xmlpath = (char *)xmlGetNodePath(node);
      if(!titled++) nc_printf(ncct, "== Section Settings ==\n");
      nc_printf(ncct, "%s: %s\n", xmlpath + cliplen, node_str);
      free(xmlpath);
      free(node_str);
    }
  }
  xmlXPathFreeObject(pobj);

  /* Print out all the config settings */
  if(!path[0] || path[0] == '/') /* base only, or absolute path requested */
    snprintf(xpath, sizeof(xpath), "/noit%s", path);
  else
    snprintf(xpath, sizeof(xpath), "/noit%s/%s", basepath, path);
  pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET) {
    nc_printf(ncct, "no such object\n");
    goto bad;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  if(cnt > 0) {
    node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
    titled = 0;
    config = mtev_conf_get_hash(node, "config");
    while(mtev_hash_next(config, &iter, &k, &klen, &data)) {
      if(!titled++) nc_printf(ncct, "== Section [Aggregated] Config ==\n");
      nc_printf(ncct, "config::%s: %s\n", k, (const char *)data);
    }
    mtev_hash_destroy(config, free, free);
    free(config);
  }
  xmlXPathFreeObject(pobj);

  /* _shorten string_ turning last { / @ * } to { / * } */
  if(!path[0] || path[0] == '/') /* base only, or absolute path requested */
    snprintf(xpath, sizeof(xpath), "/noit%s/*", path);
  else
    snprintf(xpath, sizeof(xpath), "/noit%s/%s/*", basepath, path);
  pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET) {
    nc_printf(ncct, "no such object\n");
    goto bad;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  titled = 0;
  for(i=0; i<cnt; i++) {
    char *xmlpath;
    node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "check")) continue;
    if(!strcmp((char *)node->name, "filterset")) continue;
    xmlpath = (char *)xmlGetNodePath(node);
    if(strcmp(xmlpath + cliplen, "config")) {
      if(!(node->children && node->children == xmlGetLastChild(node) &&
           xmlNodeIsText(node->children))) {
        if(!titled++) nc_printf(ncct, "== Subsections ==\n");
        nc_printf(ncct, "%s\n", xmlpath + cliplen);
      }
    }
    free(xmlpath);
  }

  titled = 0;
  for(i=0; i<cnt; i++) {
    node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "filterset")) {
      xmlAttr *attr;
      char *filter_name = NULL;
      for(attr=node->properties; attr; attr = attr->next) {
        if(!strcmp((char *)attr->name, "name"))
          filter_name = (char *)xmlXPathCastNodeToString(attr->children);
      }
      if(filter_name) {
        nc_printf(ncct, "filterset[@name=\"%s\"]\n", filter_name);
        xmlFree(filter_name);
      }
      else nc_printf(ncct, "fitlerset\n");
    }
    else if(!strcmp((char *)node->name, "check")) {
      int busted = 1;
      xmlAttr *attr;
      char *uuid_str = NULL;
      uuid_t checkid;

      if(!titled++) nc_printf(ncct, "== Checks ==\n");

      for(attr=node->properties; attr; attr = attr->next) {
        if(!strcmp((char *)attr->name, "uuid")) {
          uuid_str = (char *)xmlXPathCastNodeToString(attr->children);
          break;
        }
      }
      nc_printf(ncct, "check[@uuid=\"%s\"] ", uuid_str ? uuid_str : "undefined");
      if(uuid_str && uuid_parse(uuid_str, checkid) == 0) {
        noit_check_t *check;
        check = noit_poller_lookup(checkid);
        if(check) {
          busted = 0;
          nc_printf(ncct, "%s`%s`%s", check->target, check->module, check->name);
        }
      }
      if(uuid_str) free(uuid_str);
      if(busted) nc_printf(ncct, "[check not in running system]");
      nc_write(ncct, "\n", 1);
    }
  }
  xmlXPathFreeObject(pobj);
  return 0;
 bad:
  if(pobj) xmlXPathFreeObject(pobj);
  return -1;
}
Example #18
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;
}
Example #19
0
int
noit_filtersets_cull_unused() {
  mtev_hash_table active = MTEV_HASH_EMPTY;
  char *buffer = NULL;
  mtev_conf_section_t *declares;
  int i, n_uses = 0, n_declares = 0, removed = 0;
  const char *declare_xpath = "//filterset[@name and not (@cull='false')]";

  declares = mtev_conf_get_sections(NULL, declare_xpath, &n_declares);
  if(declares) {
    /* store all unit filtersets used */
    for(i=0;i<n_declares;i++) {
      if(!buffer) buffer = malloc(128);
      if(mtev_conf_get_stringbuf(declares[i], "@name", buffer, 128)) {
        if(mtev_hash_store(&active, buffer, strlen(buffer), declares[i])) {
          buffer = NULL;
        }
        else {
          void *vnode = NULL;
          /* We've just hit a duplicate.... check to see if there's an existing
           * entry and if there is, load the latest one and delete the old
           * one. */
          mtev_hash_retrieve(&active, buffer, strlen(buffer), &vnode);
          if (vnode) {
            noit_filter_compile_add(declares[i]);
            CONF_REMOVE(vnode);
            xmlUnlinkNode(vnode);
            xmlFreeNode(vnode);
            removed++;
            if(mtev_hash_replace(&active, buffer, strlen(buffer), declares[i], free, NULL)) {
              buffer = NULL;
            }
          }
        }
      }
    }
    if(buffer) free(buffer);
    free(declares);
  }

  n_uses = noit_poller_do(filterset_accum, &active);

  if(n_uses > 0 && mtev_hash_size(&active) > 0) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *filter_name;
    int filter_name_len;
    void *vnode;
    while(mtev_hash_next(&active, &iter, &filter_name, &filter_name_len,
                         &vnode)) {
      if(noit_filter_remove(vnode)) {
        CONF_REMOVE(vnode);
        xmlUnlinkNode(vnode);
        xmlFreeNode(vnode);
        removed++;
      }
    }
  }

  mtev_hash_destroy(&active, free, NULL);
  return removed;
}
static void
mtev_capabilities_tobuff_json(mtev_capsvc_closure_t *cl, eventer_func_t curr) {
    const char **mod_names;
    struct utsname utsn;
    char vbuff[128];
    mtev_hash_table *lc;
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *k;
    int klen, i, nmods;
    void *data;
    struct timeval now;
    struct dso_type *t;

    struct json_object *doc;
    struct json_object *svcs, *bi, *ri, *mods, *feat;

    /* fill out capabilities */

    /* Create an XML Document */
    doc = json_object_new_object();

    /* Fill in the document */
    mtev_build_version(vbuff, sizeof(vbuff));
    json_object_object_add(doc, "version", json_object_new_string(vbuff));

    /* Build info */
    bi = json_object_new_object();
    json_object_object_add(bi, "bitwidth", json_object_new_int(sizeof(void *)*8));
    json_object_object_add(bi, "sysname", json_object_new_string(UNAME_S));
    json_object_object_add(bi, "nodename", json_object_new_string(UNAME_N));
    json_object_object_add(bi, "release", json_object_new_string(UNAME_R));
    json_object_object_add(bi, "version", json_object_new_string(UNAME_V));
    json_object_object_add(bi, "machine", json_object_new_string(UNAME_M));
    json_object_object_add(doc, "unameBuild", bi);

    /* Run info */
    ri = json_object_new_object();
    json_object_object_add(ri, "bitwidth", json_object_new_int(sizeof(void *)*8));
    if(uname(&utsn) < 0) {
      json_object_object_add(ri, "error", json_object_new_string(strerror(errno)));
    } else {
      json_object_object_add(ri, "sysname", json_object_new_string(utsn.sysname));
      json_object_object_add(ri, "nodename", json_object_new_string(utsn.nodename));
      json_object_object_add(ri, "release", json_object_new_string(utsn.release));
      json_object_object_add(ri, "version", json_object_new_string(utsn.version));
      json_object_object_add(ri, "machine", json_object_new_string(utsn.machine));
    }
    json_object_object_add(doc, "unameRun", ri);

    /* features */
    feat = json_object_new_object();
    if(mtev_hash_size(&features)) {
      mtev_hash_iter iter2 = MTEV_HASH_ITER_ZERO;
      void *vfv;
      const char *f;
      int flen;
      while(mtev_hash_next(&features, &iter2, &f, &flen, &vfv)) {
        struct json_object *featnode;
        featnode = json_object_new_object();
        if(vfv) json_object_object_add(featnode, "version", json_object_new_string(vfv));
        json_object_object_add(feat, f, featnode);
      }
    }
    json_object_object_add(doc, "features", feat);

    /* time (poor man's time check) */
    gettimeofday(&now, NULL);
    snprintf(vbuff, sizeof(vbuff), "%llu%03d", (unsigned long long)now.tv_sec,
             (int)(now.tv_usec / 1000));
    json_object_object_add(doc, "current_time", json_object_new_string(vbuff));

    svcs = json_object_new_object();
    lc = mtev_listener_commands();
    while(mtev_hash_next(lc, &iter, &k, &klen, &data)) {
      struct json_object *cnode, *cmds;
      char hexcode[11];
      const char *name;
      eventer_func_t *f = (eventer_func_t *)k;
      mtev_hash_table *sc = (mtev_hash_table *)data;
      mtev_hash_iter sc_iter = MTEV_HASH_ITER_ZERO;
      const char *sc_k;
      int sc_klen;
      void *sc_data;

      name = eventer_name_for_callback(*f);
      cnode = json_object_new_object();
      if(klen == 8)
        snprintf(hexcode, sizeof(hexcode), "0x%0llx",
                 (unsigned long long int)(vpsized_uint)**f);
      else
        snprintf(hexcode, sizeof(hexcode), "0x%0x",
                 (unsigned int)(vpsized_uint)**f);
      json_object_object_add(svcs, hexcode, cnode);
      if(name) json_object_object_add(cnode, name, json_object_new_string(name));
      cmds = json_object_new_object();
      json_object_object_add(cnode, "commands", cmds);
      while(mtev_hash_next(sc, &sc_iter, &sc_k, &sc_klen, &sc_data)) {
        struct json_object *scnode;
        char *name_copy, *version = NULL;
        eventer_func_t *f = (eventer_func_t *)sc_data;

        scnode = json_object_new_object();
        snprintf(hexcode, sizeof(hexcode), "0x%08x", *((u_int32_t *)sc_k));
        name = eventer_name_for_callback(*f);
        name_copy = strdup(name ? name : "[[unknown]]");
        version = strchr(name_copy, '/');
        if(version) *version++ = '\0';

        json_object_object_add(scnode, "name", json_object_new_string(name_copy));
        if(version) json_object_object_add(scnode, "version", json_object_new_string(version));
        json_object_object_add(cmds, hexcode, scnode);
        free(name_copy);
      }
    }
    json_object_object_add(doc, "services", svcs);

    mods = json_object_new_object();

#define list_modules_json(func, name) do { \
    nmods = func(&mod_names); \
    for(i=0; i<nmods; i++) { \
      struct json_object *pnode; \
      pnode = json_object_new_object(); \
      json_object_object_add(pnode, "type", json_object_new_string(name)); \
      json_object_object_add(mods, mod_names[i], pnode); \
    } \
    if(mod_names) free(mod_names); \
} while(0)
    for(t = mtev_dso_get_types(); t; t = t->next)
      list_modules_json(t->list, t->name);
    json_object_object_add(doc, "modules", mods);

    /* Write it out to a buffer and copy it for writing */
    cl->buff = strdup(json_object_to_json_string(doc));
    cl->towrite = strlen(cl->buff);

    /* Clean up after ourselves */
    json_object_put(doc);
}
Example #21
0
int mtev_hash_adv(mtev_hash_table *h, mtev_hash_iter *iter) {
  return mtev_hash_next(h, iter, &iter->key.str, &iter->klen, &iter->value.ptr);
}