Beispiel #1
0
static void dns_check_log_results(struct dns_check_info *ci) {
  struct timeval duration;
  double rtt;

  gettimeofday(&ci->current.whence, NULL);
  sub_timeval(ci->current.whence, ci->check->last_fire_time, &duration);
  rtt = duration.tv_sec * 1000.0 + duration.tv_usec / 1000.0;
  ci->current.duration = rtt;

  ci->current.state = (ci->error || ci->nrr == 0) ? NP_BAD : NP_GOOD;
  ci->current.available = ci->timed_out ? NP_UNAVAILABLE : NP_AVAILABLE;
  if(ci->error) {
    ci->current.status = strdup(ci->error);
  }
  else if(!ci->current.status) {
    char buff[48];
    snprintf(buff, sizeof(buff), "%d %s",
             ci->nrr, ci->nrr == 1 ? "record" : "records");
    ci->current.status = strdup(buff);
  }
  noit_stats_set_metric(ci->check, &ci->current, "rtt", METRIC_DOUBLE,
                        ci->timed_out ? NULL : &rtt);

  noit_check_set_stats(ci->check, &ci->current);
  if(ci->error) free(ci->error);
  if(ci->current.status) free(ci->current.status);
  ci->error = NULL;
  memset(&ci->current, 0, sizeof(ci->current));
}
Beispiel #2
0
static int example_initiate(noit_module_t *self, noit_check_t *check,
                            noit_check_t *cause) {
  struct example_check_info *ci = check->closure;
  const char *limit = "0";
  struct timeval now, diff;

  BAIL_ON_RUNNING_CHECK(check);
  check->flags |= NP_RUNNING;

  mtev_hash_retrieve(check->config, "limit", strlen("limit"), (void **)&limit);
  ci->limit = atoi(limit);

  mtev_gettimeofday(&now, NULL);
  sub_timeval(now, check->last_fire_time, &diff);
  noit_stats_set_whence(check, &now);
  noit_stats_set_duration(check, diff.tv_sec * 1000 + diff.tv_usec / 1000);
  noit_stats_set_available(check, NP_AVAILABLE);
  noit_stats_set_status(check, "hello world");

  if(ci->limit) {
    int value = (int)(lrand48() % ci->limit);
    noit_stats_set_metric(check, "random", METRIC_INT32, &value);
    noit_stats_set_state(check, NP_GOOD);
  }
  else {
    noit_stats_set_metric(check, "random", METRIC_INT32, NULL);
    noit_stats_set_state(check, NP_BAD);
  }

  noit_check_set_stats(check);
  check->flags &= ~NP_RUNNING;

  return 0;
}
Beispiel #3
0
static void mysql_log_results(noit_module_t *self, noit_check_t *check) {
  struct timeval duration, now;
  mysql_check_info_t *ci = check->closure;

  gettimeofday(&now, NULL);
  sub_timeval(now, check->last_fire_time, &duration);
  noit_stats_set_whence(check, &now);
  noit_stats_set_duration(check, duration.tv_sec * 1000 + duration.tv_usec / 1000);
  noit_stats_set_available(check, NP_UNAVAILABLE);
  noit_stats_set_state(check, NP_BAD);
  if(ci->error) noit_stats_set_status(check, ci->error);
  else if(ci->timed_out) noit_stats_set_status(check, "timeout");
  else if(ci->rv == 0) {
    noit_stats_set_available(check, NP_AVAILABLE);
    noit_stats_set_state(check, NP_GOOD);
    noit_stats_set_status(check, "no rows, ok");
  }
  else {
    noit_stats_set_available(check, NP_AVAILABLE);
    noit_stats_set_state(check, NP_GOOD);
    noit_stats_set_status(check, "got rows, ok");
  }

  if(ci->rv >= 0)
    noit_stats_set_metric(check, "row_count", METRIC_INT32, &ci->rv);
  if(ci->connect_duration)
    noit_stats_set_metric(check, "connect_duration", METRIC_DOUBLE,
                          ci->connect_duration);
  if(ci->query_duration)
    noit_stats_set_metric(check, "query_duration", METRIC_DOUBLE,
                          ci->query_duration);

  noit_check_set_stats(check);
}
Beispiel #4
0
static void ssh2_log_results(noit_module_t *self, noit_check_t *check) {
  struct timeval duration;
  ssh2_check_info_t *ci = check->closure;

  noit_check_stats_clear(check, &check->stats.inprogress);

  gettimeofday(&check->stats.inprogress.whence, NULL);
  sub_timeval(check->stats.inprogress.whence, check->last_fire_time, &duration);
  check->stats.inprogress.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  check->stats.inprogress.available = ci->available ? NP_AVAILABLE : NP_UNAVAILABLE;
  check->stats.inprogress.state = ci->fingerprint[0] ? NP_GOOD : NP_BAD;

  if(ci->error) check->stats.inprogress.status = ci->error;
  else if(ci->timed_out) check->stats.inprogress.status = "timeout";
  else if(ci->fingerprint[0]) check->stats.inprogress.status = ci->fingerprint;
  else check->stats.inprogress.status = "internal error";

  if(ci->fingerprint[0]) {
    u_int32_t mduration = check->stats.inprogress.duration;
    noit_stats_set_metric(check, &check->stats.inprogress, "duration", METRIC_UINT32, &mduration);
    noit_stats_set_metric(check, &check->stats.inprogress, "fingerprint", METRIC_STRING,
                          ci->fingerprint);
  }
  noit_check_set_stats(check, &check->stats.inprogress);
  noit_check_stats_clear(check, &check->stats.inprogress);
}
Beispiel #5
0
static void postgres_log_results(noit_module_t *self, noit_check_t *check) {
  struct timeval duration;
  postgres_check_info_t *ci = check->closure;

  gettimeofday(&ci->current.whence, NULL);
  sub_timeval(ci->current.whence, check->last_fire_time, &duration);
  ci->current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  ci->current.available = NP_UNAVAILABLE;
  ci->current.state = NP_BAD;
  if(ci->connect_duration)
    noit_stats_set_metric(&ci->current, "connect_duration", METRIC_DOUBLE,
                          ci->connect_duration);
  if(ci->query_duration)
    noit_stats_set_metric(&ci->current, "query_duration", METRIC_DOUBLE,
                          ci->query_duration);
  if(ci->error) ci->current.status = ci->error;
  else if(ci->timed_out) ci->current.status = "timeout";
  else if(ci->rv == PGRES_COMMAND_OK) {
    ci->current.available = NP_AVAILABLE;
    ci->current.state = NP_GOOD;
    ci->current.status = "command ok";
  }
  else if(ci->rv == PGRES_TUPLES_OK) {
    ci->current.available = NP_AVAILABLE;
    ci->current.state = NP_GOOD;
    ci->current.status = "tuples ok";
  }
  else ci->current.status = "internal error";

  noit_check_set_stats(self, check, &ci->current);
}
Beispiel #6
0
static void ping_icmp_log_results(noit_module_t *self, noit_check_t *check) {
  struct check_info *data;
  double avail = 0.0, min = MAXFLOAT, max = 0.0, avg = 0.0, cnt;
  int avail_needed = 100;
  const char *config_val = NULL;
  int i, points = 0;
  char human_buffer[256];
  struct timeval duration;

  noit_check_stats_clear(check, &check->stats.inprogress);

  data = (struct check_info *)check->closure;
  for(i=0; i<data->expected_count; i++) {
    if(data->turnaround[i] >= 0.0) {
      points++;
      avg += data->turnaround[i];
      if(data->turnaround[i] > max) max = data->turnaround[i];
      if(data->turnaround[i] < min) min = data->turnaround[i];
    }
  }
  cnt = data->expected_count;
  if(points == 0) {
    min = 0.0 / 0.0;
    max = 0.0 / 0.0;
    avg = 0.0 / 0.0;
  }
  else {
    avail = (float)points /cnt;
    avg /= (float)points;
  }

  if(noit_hash_retr_str(check->config, "avail_needed", strlen("avail_needed"),
                        &config_val))
    avail_needed = atoi(config_val);

  snprintf(human_buffer, sizeof(human_buffer),
           "cnt=%d,avail=%0.0f,min=%0.4f,max=%0.4f,avg=%0.4f",
           (int)cnt, 100.0*avail, min, max, avg);
  noitL(nldeb, "ping_icmp(%s) [%s]\n", check->target_ip, human_buffer);

  gettimeofday(&check->stats.inprogress.whence, NULL);
  sub_timeval(check->stats.inprogress.whence, check->last_fire_time, &duration);
  check->stats.inprogress.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  check->stats.inprogress.available = (avail > 0.0) ? NP_AVAILABLE : NP_UNAVAILABLE;
  check->stats.inprogress.state = (avail < ((float)avail_needed / 100.0)) ? NP_BAD : NP_GOOD;
  check->stats.inprogress.status = human_buffer;
  noit_stats_set_metric(check, &check->stats.inprogress, "count",
                        METRIC_INT32, &data->expected_count);
  avail *= 100.0;
  noit_stats_set_metric(check, &check->stats.inprogress, "available", METRIC_DOUBLE, &avail);
  noit_stats_set_metric(check, &check->stats.inprogress, "minimum",
                        METRIC_DOUBLE, avail > 0.0 ? &min : NULL);
  noit_stats_set_metric(check, &check->stats.inprogress, "maximum",
                        METRIC_DOUBLE, avail > 0.0 ? &max : NULL);
  noit_stats_set_metric(check, &check->stats.inprogress, "average",
                        METRIC_DOUBLE, avail > 0.0 ? &avg : NULL);
  noit_check_set_stats(check, &check->stats.inprogress);
  noit_check_stats_clear(check, &check->stats.inprogress);
}
Beispiel #7
0
static void selfcheck_log_results(noit_module_t *self, noit_check_t *check) {
  char buff[128];
  u_int64_t u64;
  int64_t s64;
  int32_t s32;
  struct threadq_crutch crutch;
  struct timeval duration, epoch, diff;
  selfcheck_info_t *ci = check->closure;

  crutch.check = check;
  noit_check_stats_clear(check, &check->stats.inprogress);

  gettimeofday(&check->stats.inprogress.whence, NULL);
  sub_timeval(check->stats.inprogress.whence, check->last_fire_time, &duration);
  check->stats.inprogress.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  check->stats.inprogress.available = NP_UNAVAILABLE;
  check->stats.inprogress.state = NP_BAD;
  if(ci->timed_out) check->stats.inprogress.status = "timeout";
  else {
    check->stats.inprogress.available = NP_AVAILABLE;
    check->stats.inprogress.state = NP_GOOD;
    check->stats.inprogress.status = "ok";
  }
  /* Set all the metrics here */
  s64 = (int64_t)ci->logsize;
  noit_stats_set_metric(check, &check->stats.inprogress, "feed_bytes", METRIC_INT64, &s64);
  s32 = noit_poller_check_count();
  noit_stats_set_metric(check, &check->stats.inprogress, "check_cnt", METRIC_INT32, &s32);
  s32 = noit_poller_transient_check_count();
  noit_stats_set_metric(check, &check->stats.inprogress, "transient_cnt", METRIC_INT32, &s32);
  if(eventer_get_epoch(&epoch)) s64 = 0;
  else {
    sub_timeval(check->stats.inprogress.whence, epoch, &diff);
    s64 = diff.tv_sec;
  }
  noit_stats_set_metric(check, &check->stats.inprogress, "uptime", METRIC_INT64, &s64);
  eventer_jobq_process_each(jobq_thread_helper, &crutch);
  noit_build_version(buff, sizeof(buff));
  noit_stats_set_metric(check, &check->stats.inprogress, "version", METRIC_STRING, buff);
  u64 = noit_check_completion_count();
  noit_stats_set_metric(check, &check->stats.inprogress, "checks_run", METRIC_UINT64, &u64);
  /* feed pull info */
  noit_jlog_foreach_feed_stats(selfcheck_feed_details, &crutch);

  noit_check_set_stats(check, &check->stats.inprogress);
  noit_check_stats_clear(check, &check->stats.inprogress);
}
Beispiel #8
0
static noit_hook_return_t
ip_acl_hook_impl(void *closure, noit_module_t *self,
                 noit_check_t *check, noit_check_t *cause) {
  char deny_msg[128];
  stats_t current;
  noit_hash_table *config;
  noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
  const char *k = NULL;
  int klen;
  void *data;
  config = noit_check_get_module_config(check, ip_acl_module_id);
  if(!config || config->size == 0) return NOIT_HOOK_CONTINUE;
  while(noit_hash_next(config, &iter, &k, &klen, &data)) {
    if(k) {
      void *dir = NULL;
      unsigned char mask;
      if(noit_hash_retrieve(&acls, k, strlen(k), &data)) {
        btrie *acl = data;
        if(check->target_family == AF_INET) {
          dir = noit_find_bpm_route_ipv4(acl, &check->target_addr.addr, &mask);
          if(dir == DENY_PTR) goto prevent;
          else if(dir == ALLOW_PTR) return NOIT_HOOK_CONTINUE;
        }
        else if(check->target_family == AF_INET6) {
          dir = noit_find_bpm_route_ipv6(acl, &check->target_addr.addr6, &mask);
          if(dir == DENY_PTR) goto prevent;
          else if(dir == ALLOW_PTR) return NOIT_HOOK_CONTINUE;
        }
      }
    }
  }
  return NOIT_HOOK_CONTINUE;

 prevent:
  memset(&current, 0, sizeof(current));
  current.available = NP_UNAVAILABLE;
  current.state = NP_BAD;
  gettimeofday(&current.whence, NULL);
  snprintf(deny_msg, sizeof(deny_msg), "prevented by ACL '%s'", k ? k : "unknown");
  current.status = deny_msg;
  noit_check_set_stats(check, &current);
  return NOIT_HOOK_DONE;
}
Beispiel #9
0
static void external_log_results(noit_module_t *self, noit_check_t *check) {
  external_data_t *data;
  struct check_info *ci;
  stats_t current;
  struct timeval duration;

  noit_check_stats_clear(&current);

  data = noit_module_get_userdata(self);
  ci = (struct check_info *)check->closure;

  noitL(data->nldeb, "external(%s) (timeout: %d, exit: %x)\n",
        check->target, ci->timedout, ci->exit_code);

  gettimeofday(&current.whence, NULL);
  sub_timeval(current.whence, check->last_fire_time, &duration);
  current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  if(ci->timedout) {
    current.available = NP_UNAVAILABLE;
    current.state = NP_BAD;
  }
  else if(WEXITSTATUS(ci->exit_code) == 3) {
    current.available = NP_UNKNOWN;
    current.state = NP_UNKNOWN;
  }
  else {
    current.available = NP_AVAILABLE;
    current.state = (WEXITSTATUS(ci->exit_code) == 0) ? NP_GOOD : NP_BAD;
  }

  /* Hack the output into metrics */
  if(ci->output && ci->matcher) {
    int rc, len, startoffset = 0;
    int ovector[30];
    len = strlen(ci->output);
    noitL(data->nldeb, "going to match output at %d/%d\n", startoffset, len);
    while((rc = pcre_exec(ci->matcher, NULL, ci->output, len, startoffset, 0,
                          ovector, sizeof(ovector)/sizeof(*ovector))) > 0) {
      char metric[128];
      char value[128];
      startoffset = ovector[1];
      noitL(data->nldeb, "matched at offset %d\n", rc);
      if(pcre_copy_named_substring(ci->matcher, ci->output, ovector, rc,
                                   "key", metric, sizeof(metric)) > 0 &&
         pcre_copy_named_substring(ci->matcher, ci->output, ovector, rc,
                                   "value", value, sizeof(value)) > 0) {
        /* We're able to extract something... */
        noit_stats_set_metric(&current, metric, METRIC_GUESS, value);
      }
      noitL(data->nldeb, "going to match output at %d/%d\n", startoffset, len);
    }
    noitL(data->nldeb, "match failed.... %d\n", rc);
  }

  current.status = ci->output;
  noit_check_set_stats(self, check, &current);

  /* If we didn't exit normally, or we core, or we have stderr to report...
   * provide a full report.
   */
  if((WTERMSIG(ci->exit_code) != SIGQUIT && WTERMSIG(ci->exit_code) != 0) ||
     WCOREDUMP(ci->exit_code) ||
     (ci->error && *ci->error)) {
    char uuid_str[37];
    uuid_unparse_lower(check->checkid, uuid_str);
    noitL(data->nlerr, "external/%s: (sig:%d%s) [%s]\n", uuid_str,
          WTERMSIG(ci->exit_code), WCOREDUMP(ci->exit_code)?", cored":"",
          ci->error ? ci->error : "");
  }
}
Beispiel #10
0
static int test_abort_drive_session(eventer_t e, int mask, void *closure,
                                  struct timeval *passed_now) {
  struct timespec rqtp;
  struct timeval target_time, now, diff;
  double i, r;
  test_abort_check_info_t *ci = closure;
  noit_check_t *check = ci->check;

  if(mask & (EVENTER_READ | EVENTER_WRITE)) {
    /* this case is impossible from the eventer.  It is called as
     * such on the synchronous completion of the event.
     */
    noit_check_stats_clear(check, &check->stats.inprogress);
    check->stats.inprogress.available = NP_AVAILABLE;
    check->stats.inprogress.state = ci->timed_out ? NP_BAD : NP_GOOD;
    noitL(nlerr, "test_abort: EVENTER_READ | EVENTER_WRITE\n");
    noit_check_set_stats(check, &check->stats.inprogress);
    noit_check_stats_clear(check, &check->stats.inprogress);
    check->flags &= ~NP_RUNNING;
    return 0;
  }
  switch(mask) {
    case EVENTER_ASYNCH_WORK:
      noitL(nlerr, "test_abort: EVENTER_ASYNCH_WORK\n");
      r = modf(ci->timeout, &i);
      ci->timed_out = 1;

      if(ci->ignore_signals) { /* compuational loop */
        double trash = 1.0;
        gettimeofday(&now, NULL);
        diff.tv_sec = (int)i;
        diff.tv_usec = (int)(r * 1000000.0);
        add_timeval(now, diff, &target_time);

        do {
          for(i=0; i<100000; i++) {
            trash += drand48();
            trash = log(trash);
            trash += 1.1;
            trash = exp(trash);
          }
          gettimeofday(&now, NULL);
          sub_timeval(target_time, now, &diff);
        } while(diff.tv_sec >= 0 && diff.tv_usec >= 0);
      }
      else {
        rqtp.tv_sec = (int)i;
        rqtp.tv_nsec = (int)(r * 1000000000.0);
        nanosleep(&rqtp,NULL);
      }
      noitL(nlerr, "test_abort: EVENTER_ASYNCH_WORK (done)\n");
      ci->timed_out = 0;
      return 0;
      break;
    case EVENTER_ASYNCH_CLEANUP:
      /* This sets us up for a completion call. */
      noitL(nlerr, "test_abort: EVENTER_ASYNCH_CLEANUP\n");
      e->mask = EVENTER_READ | EVENTER_WRITE;
      break;
    default:
      abort();
  }
  return 0;
}
Beispiel #11
0
/* Handling of results */
static void noit_snmp_log_results(noit_module_t *self, noit_check_t *check,
                                  struct snmp_pdu *pdu) {
  struct check_info *info = check->closure;
  struct variable_list *vars;
  struct timeval duration;
  char buff[128];
  stats_t current;
  int nresults = 0;

  noit_check_stats_clear(check, &current);

  if(pdu)
    for(vars = pdu->variables; vars; vars = vars->next_variable)
      nresults++;

  gettimeofday(&current.whence, NULL);
  sub_timeval(current.whence, check->last_fire_time, &duration);
  current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  current.available = pdu ? NP_AVAILABLE : NP_UNAVAILABLE;
  current.state = (nresults == info->noids) ? NP_GOOD : NP_BAD;
  snprintf(buff, sizeof(buff), "%d/%d gets", nresults, info->noids);
  current.status = buff;

  /* We have no results over which to iterate. */
  if(!pdu) {
    noit_check_set_stats(check, &current);
    return;
  }

  /* manipulate the information ourselves */
  nresults = 0;
  for(vars = pdu->variables; vars; vars = vars->next_variable) {
    char *sp;
    int oid_idx;
    double float_conv;
    u_int64_t u64;
    int64_t i64;
    char *endptr;
    char varbuff[256];

    /* find the oid to which this is the response */
    oid_idx = nresults; /* our current idx is the most likely */
    if(info->oids[oid_idx].oidlen != vars->name_length ||
       memcmp(info->oids[oid_idx].oid, vars->name,
              vars->name_length * sizeof(oid))) {
      /* Not the most obvious guess */
      for(oid_idx = info->noids - 1; oid_idx >= 0; oid_idx--) {
        if(info->oids[oid_idx].oidlen == vars->name_length &&
           memcmp(info->oids[oid_idx].oid, vars->name,
                  vars->name_length * sizeof(oid))) break;
      }
    }
    if(oid_idx < 0) {
      snprint_variable(varbuff, sizeof(varbuff),
                       vars->name, vars->name_length, vars);
      noitL(nlerr, "Unexpected oid results to %s`%s`%s: %s\n",
            check->target, check->module, check->name, varbuff);
      nresults++;
      continue;
    }

#define SETM(a,b) noit_stats_set_metric(check, &current, \
                                        info->oids[oid_idx].confname, a, b)
    if(info->oids[oid_idx].type_should_override) {
      snprint_value(varbuff, sizeof(varbuff), vars->name, vars->name_length, vars);
      sp = strchr(varbuff, ' ');
      if(sp) sp++;
      noit_stats_set_metric_coerce(check, &current, info->oids[oid_idx].confname,
                                   info->oids[oid_idx].type_override,
                                   sp);
    }
    else {
      switch(vars->type) {
        case ASN_OCTET_STR:
          sp = malloc(1 + vars->val_len);
          memcpy(sp, vars->val.string, vars->val_len);
          sp[vars->val_len] = '\0';
          SETM(METRIC_STRING, sp);
          free(sp);
          break;
        case ASN_INTEGER:
        case ASN_GAUGE:
          SETM(METRIC_INT32, vars->val.integer);
          break;
        case ASN_TIMETICKS:
        case ASN_COUNTER:
          SETM(METRIC_UINT32, vars->val.integer);
          break;
        case ASN_INTEGER64:
          printI64(varbuff, vars->val.counter64);
          i64 = strtoll(varbuff, &endptr, 10);
          SETM(METRIC_INT64, (varbuff == endptr) ? NULL : &i64);
          break;
        case ASN_COUNTER64:
          printU64(varbuff, vars->val.counter64);
          u64 = strtoull(varbuff, &endptr, 10);
          SETM(METRIC_UINT64, (varbuff == endptr) ? NULL : &u64);
          break;
        case ASN_FLOAT:
          if(vars->val.floatVal) float_conv = *(vars->val.floatVal);
          SETM(METRIC_DOUBLE, vars->val.floatVal ? &float_conv : NULL);
          break;
        case ASN_DOUBLE:
          SETM(METRIC_DOUBLE, vars->val.doubleVal);
          break;
        case SNMP_NOSUCHOBJECT:
        case SNMP_NOSUCHINSTANCE:
          SETM(METRIC_STRING, NULL);
          break;
        default:
          snprint_variable(varbuff, sizeof(varbuff), vars->name, vars->name_length, vars);
          /* Advance passed the first space and use that unless there
           * is no space or we have no more string left.
           */
          sp = strchr(varbuff, ' ');
          if(sp) sp++;
          SETM(METRIC_STRING, (sp && *sp) ? sp : NULL);
      }
    }
    nresults++;
  }
  noit_check_set_stats(check, &current);
}