コード例 #1
0
ファイル: collectd.c プロジェクト: octo/collectd
static int do_loop(void) {
  cdtime_t interval = cf_get_default_interval();
  cdtime_t wait_until = cdtime() + interval;

  while (loop == 0) {
#if HAVE_LIBKSTAT
    update_kstat();
#endif

    /* Issue all plugins */
    plugin_read_all();

    cdtime_t now = cdtime();
    if (now >= wait_until) {
      WARNING("Not sleeping because the next interval is "
              "%.3f seconds in the past!",
              CDTIME_T_TO_DOUBLE(now - wait_until));
      wait_until = now + interval;
      continue;
    }

    struct timespec ts_wait = CDTIME_T_TO_TIMESPEC(wait_until - now);
    wait_until = wait_until + interval;

    while ((loop == 0) && (nanosleep(&ts_wait, &ts_wait) != 0)) {
      if (errno != EINTR) {
        ERROR("nanosleep failed: %s", STRERRNO);
        return -1;
      }
    }
  } /* while (loop == 0) */

  return 0;
} /* int do_loop */
コード例 #2
0
ファイル: write_tsdb.c プロジェクト: bpiraeus/collectd
/* NOTE: You must hold cb->send_lock when calling this function! */
static int wt_flush_nolock (cdtime_t timeout, struct wt_callback *cb)
{
    int status;

    DEBUG ("write_tsdb plugin: wt_flush_nolock: timeout = %.3f; "
            "send_buf_fill = %zu;",
            (double)timeout,
            cb->send_buf_fill);

    /* timeout == 0  => flush unconditionally */
    if (timeout > 0)
    {
        cdtime_t now;

        now = cdtime ();
        if ((cb->send_buf_init_time + timeout) > now)
            return (0);
    }

    if (cb->send_buf_fill <= 0)
    {
        cb->send_buf_init_time = cdtime ();
        return (0);
    }

    status = wt_send_buffer (cb);
    wt_reset_buffer (cb);

    return (status);
}
コード例 #3
0
ファイル: curl.c プロジェクト: brd/collectd
static int cc_read_page (web_page_t *wp) /* {{{ */
{
  int status;
  cdtime_t start = 0;

  if (wp->response_time)
    start = cdtime ();

  wp->buffer_fill = 0;
  status = curl_easy_perform (wp->curl);
  if (status != CURLE_OK)
  {
    ERROR ("curl plugin: curl_easy_perform failed with status %i: %s",
        status, wp->curl_errbuf);
    return (-1);
  }

  if (wp->response_time)
    cc_submit_response_time (wp, cdtime() - start);
  if (wp->stats != NULL)
    curl_stats_dispatch (wp->stats, wp->curl, hostname_g, "curl", wp->instance);

  if(wp->response_code)
  {
    long response_code = 0;
    status = curl_easy_getinfo(wp->curl, CURLINFO_RESPONSE_CODE, &response_code);
    if(status != CURLE_OK) {
      ERROR ("curl plugin: Fetching response code failed with status %i: %s",
        status, wp->curl_errbuf);
    } else {
      cc_submit_response_code(wp, response_code);
    }
  }

  for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next)
  {
    cu_match_value_t *mv;

    status = match_apply (wm->match, wp->buffer);
    if (status != 0)
    {
      WARNING ("curl plugin: match_apply failed.");
      continue;
    }

    mv = match_get_user_data (wm->match);
    if (mv == NULL)
    {
      WARNING ("curl plugin: match_get_user_data returned NULL.");
      continue;
    }

    cc_submit (wp, wm, mv);
    match_value_reset (mv);
  } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */

  return (0);
} /* }}} int cc_read_page */
コード例 #4
0
ファイル: snmp.c プロジェクト: kmiku7/collectd
static int csnmp_read_host (user_data_t *ud)
{
  host_definition_t *host;
  cdtime_t time_start;
  cdtime_t time_end;
  int status;
  int success;
  int i;

  host = ud->data;

  if (host->interval == 0)
    host->interval = plugin_get_interval ();

  time_start = cdtime ();

  if (host->sess_handle == NULL)
    csnmp_host_open_session (host);

  if (host->sess_handle == NULL)
    return (-1);

  success = 0;
  for (i = 0; i < host->data_list_len; i++)
  {
    data_definition_t *data = host->data_list[i];

    if (data->is_table)
      status = csnmp_read_table (host, data);
    else
      status = csnmp_read_value (host, data);

    if (status == 0)
      success++;
  }

  time_end = cdtime ();
  if ((time_end - time_start) > host->interval)
  {
    WARNING ("snmp plugin: Host `%s' should be queried every %.3f "
        "seconds, but reading all values takes %.3f seconds.",
        host->name,
        CDTIME_T_TO_DOUBLE (host->interval),
        CDTIME_T_TO_DOUBLE (time_end - time_start));
  }

  if (success == 0)
    return (-1);

  return (0);
} /* int csnmp_read_host */
コード例 #5
0
ファイル: write_extremon.c プロジェクト: zbyufei/ExtreMon
static int we_flush_nolock (cdtime_t timeout, we_callback_t *cb) 
{
  int status;

  DEBUG("write_extremon plugin: we_flush_nolock: timeout = %.3f; "
        "send_buffer_fill = %zu;", CDTIME_T_TO_DOUBLE (timeout),
                                  cb->send_buffer_fill);

  if(timeout>0)
  {
    cdtime_t now;
    now = cdtime ();
    if ((cb->send_buffer_init_time + timeout) > now)
      return (0);
  }

/*  if (cb->send_buffer_fill <= 0)
# {
#   cb->send_buffer_init_time = cdtime ();
#   return (0);
# } */

  status = we_send_buffer (cb);
  we_reset_buffer (cb);

  return (status);
} 
コード例 #6
0
ファイル: ipmi.c プロジェクト: Stackdriver/collectd
static notification_t c_ipmi_notification_init(c_ipmi_instance_t const *st,
                                               int severity) {
  notification_t n = {severity, cdtime(), "", "", "ipmi", "", "", "", NULL};

  sstrncpy(n.host, (st->host != NULL) ? st->host : hostname_g, sizeof(n.host));
  return n;
} /* notification_t c_ipmi_notification_init */
コード例 #7
0
ファイル: dpdkevents.c プロジェクト: Feandil/collectd
static int dpdk_helper_link_status_get(dpdk_helper_ctx_t *phc) {
  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);

  /* get Link Status values from DPDK */
  uint8_t nb_ports = rte_eth_dev_count();
  if (nb_ports == 0) {
    DPDK_CHILD_LOG("dpdkevent-helper: No DPDK ports available. "
                   "Check bound devices to DPDK driver.\n");
    return -ENODEV;
  }
  ec->nb_ports = nb_ports > RTE_MAX_ETHPORTS ? RTE_MAX_ETHPORTS : nb_ports;

  for (int i = 0; i < ec->nb_ports; i++) {
    if (ec->config.link_status.enabled_port_mask & (1 << i)) {
      struct rte_eth_link link;
      ec->link_info[i].read_time = cdtime();
      rte_eth_link_get_nowait(i, &link);
      if ((link.link_status == ETH_LINK_NA) ||
          (link.link_status != ec->link_info[i].link_status)) {
        ec->link_info[i].link_status = link.link_status;
        ec->link_info[i].status_updated = 1;
        DPDK_CHILD_LOG(" === PORT %d Link Status: %s\n", i,
                       link.link_status ? "UP" : "DOWN");
      }
    }
  }

  return 0;
}
コード例 #8
0
ファイル: utils_latency.c プロジェクト: BrandonArp/collectd
void latency_counter_reset(latency_counter_t *lc) /* {{{ */
{
  if (lc == NULL)
    return;

  cdtime_t bin_width = lc->bin_width;
  cdtime_t max_bin = (lc->max - 1) / lc->bin_width;

/*
  If max latency is REDUCE_THRESHOLD times less than histogram's range,
  then cut it in half. REDUCE_THRESHOLD must be >= 2.
  Value of 4 is selected to reduce frequent changes of bin width.
*/
#define REDUCE_THRESHOLD 4
  if ((lc->num > 0) && (lc->bin_width >= HISTOGRAM_DEFAULT_BIN_WIDTH * 2) &&
      (max_bin < HISTOGRAM_NUM_BINS / REDUCE_THRESHOLD)) {
    /* new bin width will be the previous power of 2 */
    bin_width = bin_width / 2;

    DEBUG("utils_latency: latency_counter_reset: max_latency = %.3f; "
          "max_bin = %" PRIu64 "; old_bin_width = %.3f; new_bin_width = %.3f;",
          CDTIME_T_TO_DOUBLE(lc->max), max_bin,
          CDTIME_T_TO_DOUBLE(lc->bin_width), CDTIME_T_TO_DOUBLE(bin_width));
  }

  memset(lc, 0, sizeof(*lc));

  /* preserve bin width */
  lc->bin_width = bin_width;
  lc->start_time = cdtime();
} /* }}} void latency_counter_reset */
コード例 #9
0
ファイル: xencpu.c プロジェクト: brd/collectd
static int xencpu_read (void)
{
    cdtime_t now = cdtime ();

    int rc, nr_cpus;

    rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus);
    if (rc < 0) {
        ERROR ("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc, xc_strerror(xc_handle,errno));
        return (-1);
    }

    int status;
    for (int cpu = 0; cpu < nr_cpus; cpu++) {
        gauge_t rate = NAN;
        value_t value = {.derive = cpu_info[cpu].idletime};

        status = value_to_rate (&rate, value, DS_TYPE_DERIVE, now, &cpu_states[cpu]);
        if (status == 0) {
            submit_value(cpu, 100 - rate/10000000);
        }
    }

    return (0);
} /* static int xencpu_read */

void module_register (void)
{
    plugin_register_init ("xencpu", xencpu_init);
    plugin_register_read ("xencpu", xencpu_read);
    plugin_register_shutdown ("xencpu", xencpu_shutdown);
} /* void module_register */
コード例 #10
0
ファイル: write_tsdb.c プロジェクト: bpiraeus/collectd
/*
 * Functions
 */
static void wt_reset_buffer (struct wt_callback *cb)
{
    memset (cb->send_buf, 0, sizeof (cb->send_buf));
    cb->send_buf_free = sizeof (cb->send_buf);
    cb->send_buf_fill = 0;
    cb->send_buf_init_time = cdtime ();
}
コード例 #11
0
ファイル: utils_complain.c プロジェクト: hasso/collectd
/* vcomplain returns 0 if it did not report, 1 else */
__attribute__((format(printf, 3, 0))) static int
vcomplain(int level, c_complain_t *c, const char *format, va_list ap) {
  cdtime_t now;
  char message[512];

  now = cdtime();

  if (c->last + c->interval > now)
    return 0;

  c->last = now;

  if (c->interval < plugin_get_interval())
    c->interval = plugin_get_interval();
  else
    c->interval *= 2;

  if (c->interval > TIME_T_TO_CDTIME_T(86400))
    c->interval = TIME_T_TO_CDTIME_T(86400);

  vsnprintf(message, sizeof(message), format, ap);
  message[sizeof(message) - 1] = '\0';

  plugin_log(level, "%s", message);
  return 1;
} /* vcomplain */
コード例 #12
0
ファイル: utils_latency.c プロジェクト: Altiscale/collectd
void latency_counter_reset (latency_counter_t *lc) /* {{{ */
{
  if (lc == NULL)
    return;

  memset (lc, 0, sizeof (*lc));
  lc->start_time = cdtime ();
} /* }}} void latency_counter_reset */
コード例 #13
0
ファイル: write_extremon.c プロジェクト: zbyufei/ExtreMon
static void we_reset_buffer (we_callback_t *cb)  
{
  memset (cb->send_buffer, 0, sizeof (cb->send_buffer));
  cb->send_buffer_free = sizeof (cb->send_buffer);
  cb->send_buffer_fill = 0;
  cb->send_buffer_init_time = cdtime ();
  gettimeofday(&cb->last_write,NULL);
}
コード例 #14
0
static void sysconfig_notify(notification_t *notif, const char *type, const char *message) {
        memset (notif, '\0', sizeof (*notif));
        notif->severity = NOTIF_OKAY;
        notif->time = cdtime ();
        sstrncpy(notif->host, hostname_g, sizeof(notif->host));
        sstrncpy(notif->plugin, "sysconfig", sizeof(notif->plugin));
        sstrncpy(notif->type, type, sizeof(notif->type));
        sstrncpy(notif->message, message, sizeof(notif->message));
        plugin_dispatch_notification(notif);
}
コード例 #15
0
ファイル: tail_csv.c プロジェクト: hasso/collectd
static cdtime_t parse_time(char const *tbuf) {
  double t;
  char *endptr = NULL;

  errno = 0;
  t = strtod(tbuf, &endptr);
  if ((errno != 0) || (endptr == NULL) || (endptr[0] != 0))
    return (cdtime());

  return (DOUBLE_TO_CDTIME_T(t));
}
コード例 #16
0
ファイル: utils_latency.c プロジェクト: brd/collectd
void latency_counter_reset (latency_counter_t *lc) /* {{{ */
{
  if (lc == NULL)
    return;

  cdtime_t bin_width = lc->bin_width;
  memset (lc, 0, sizeof (*lc));

  /* preserve bin width */
  lc->bin_width = bin_width;
  lc->start_time = cdtime ();
} /* }}} void latency_counter_reset */
コード例 #17
0
/*
 * Always call while holding host->lock !
 */
static int riemann_batch_flush_nolock (cdtime_t timeout,
                                       struct riemann_host *host)
{
    cdtime_t    now;
    int         status = 0;

    if (timeout > 0) {
        now = cdtime ();
        if ((host->batch_init + timeout) > now)
            return status;
    }
    riemann_send_msg(host, host->batch_msg);
    riemann_msg_protobuf_free(host->batch_msg);

	if (host->use_tcp && ((status = riemann_recv_ack(host)) != 0))
        riemann_disconnect (host);

    host->batch_init = cdtime();
    host->batch_msg = NULL;
    return status;
}
コード例 #18
0
ファイル: memory.c プロジェクト: BrandonArp/collectd
static int memory_read(void) /* {{{ */
{
  value_t v[1];
  value_list_t vl = VALUE_LIST_INIT;

  vl.values = v;
  vl.values_len = STATIC_ARRAY_SIZE(v);
  sstrncpy(vl.plugin, "memory", sizeof(vl.plugin));
  sstrncpy(vl.type, "memory", sizeof(vl.type));
  vl.time = cdtime();

  return memory_read_internal(&vl);
} /* }}} int memory_read */
コード例 #19
0
static void wh_reset_buffer (wh_callback_t *cb)  /* {{{ */
{
        memset (cb->send_buffer, 0, cb->send_buffer_size);
        cb->send_buffer_free = cb->send_buffer_size;
        cb->send_buffer_fill = 0;
        cb->send_buffer_init_time = cdtime ();

        if (cb->format == WH_FORMAT_JSON)
        {
                format_json_initialize (cb->send_buffer,
                                &cb->send_buffer_fill,
                                &cb->send_buffer_free);
        }
} /* }}} wh_reset_buffer */
コード例 #20
0
ファイル: gce.c プロジェクト: collectd/collectd
int gce_access_token(char const *email, char *buffer,
                     size_t buffer_size) /* {{{ */
{
  char url[1024];
  char *json;
  cdtime_t now = cdtime();

  pthread_mutex_lock(&token_lock);

  if (email == NULL)
    email = GCE_DEFAULT_SERVICE_ACCOUNT;

  if ((token_email != NULL) && (strcmp(email, token_email) == 0) &&
      (token_valid_until > now)) {
    sstrncpy(buffer, token, buffer_size);
    pthread_mutex_unlock(&token_lock);
    return 0;
  }

  snprintf(url, sizeof(url), GCE_TOKEN_URL_FORMAT, email);
  json = read_url(url);
  if (json == NULL) {
    pthread_mutex_unlock(&token_lock);
    return -1;
  }

  char tmp[256];
  cdtime_t expires_in = 0;
  int status = oauth_parse_json_token(json, tmp, sizeof(tmp), &expires_in);
  sfree(json);
  if (status != 0) {
    pthread_mutex_unlock(&token_lock);
    return status;
  }

  sfree(token);
  token = strdup(tmp);

  sfree(token_email);
  token_email = strdup(email);

  /* let tokens expire a bit early */
  expires_in = (expires_in * 95) / 100;
  token_valid_until = now + expires_in;

  sstrncpy(buffer, token, buffer_size);
  pthread_mutex_unlock(&token_lock);
  return 0;
} /* }}} char *gce_token */
コード例 #21
0
ファイル: gps.c プロジェクト: NicolasJourden/collectd
/**
 * Non blocking pause for the thread.
 */
static int cgps_thread_pause(cdtime_t pTime)
{
  cdtime_t now;
  now = cdtime ();
  struct timespec pause_th;
  CDTIME_T_TO_TIMESPEC (MS_TO_CDTIME_T(10), &pause_th);
  while (CGPS_TRUE)
  {
    if ( (cdtime () - now) > pTime )
    {
      break;
    }

    pthread_mutex_lock (&cgps_thread_lock);
    if (cgps_thread_shutdown == CGPS_TRUE)
    {
      return CGPS_FALSE;
    }
    pthread_mutex_unlock (&cgps_thread_lock);
    nanosleep (&pause_th, NULL);
 }

 return CGPS_TRUE;
}
コード例 #22
0
ファイル: postgresql.c プロジェクト: Feandil/collectd
static int c_psql_begin(c_psql_database_t *db) {
  PGresult *r = PQexec(db->conn, "BEGIN");

  int status = 1;

  if (r != NULL) {
    if (PGRES_COMMAND_OK == PQresultStatus(r)) {
      db->next_commit = cdtime() + db->commit_interval;
      status = 0;
    } else
      log_warn("Failed to initiate ('BEGIN') transaction: %s",
               PQerrorMessage(db->conn));
    PQclear(r);
  }
  return status;
} /* c_psql_begin */
コード例 #23
0
ファイル: write_riemann.c プロジェクト: EMSL-MSC/collectd
/*
 * Always call while holding host->lock !
 */
static int wrr_batch_flush_nolock(cdtime_t timeout, struct riemann_host *host) {
  cdtime_t now;
  int status = 0;

  now = cdtime();
  if (timeout > 0) {
    if ((host->batch_init + timeout) > now) {
      return status;
    }
  }
  wrr_send_nolock(host, host->batch_msg);
  riemann_message_free(host->batch_msg);

  host->batch_init = now;
  host->batch_msg = NULL;
  return status;
}
コード例 #24
0
ファイル: write_http.c プロジェクト: xinity/collectdng
static void wh_reset_buffer (wh_callback_t *cb)  /* {{{ */
{
        if ((cb == NULL) || (cb->send_buffer == NULL))
                return;

        memset (cb->send_buffer, 0, cb->send_buffer_size);
        cb->send_buffer_free = cb->send_buffer_size;
        cb->send_buffer_fill = 0;
        cb->send_buffer_init_time = cdtime ();

        if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB)
        {
                format_json_initialize (cb->send_buffer,
                                &cb->send_buffer_fill,
                                &cb->send_buffer_free);
        }
} /* }}} wh_reset_buffer */
コード例 #25
0
ファイル: smart.c プロジェクト: skarlsson/collectd
static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedData *a,
                                        void* userdata)
{
  const char *dev = userdata;
  value_t values[4];
  value_list_t vl = VALUE_LIST_INIT;

  if (!a->current_value_valid || !a->worst_value_valid) return;
  values[0].gauge = a->current_value;
  values[1].gauge = a->worst_value;
  values[2].gauge = a->threshold_valid?a->threshold:0;
  values[3].gauge = a->pretty_value;

  vl.values = values;
  vl.values_len = 4;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "smart", sizeof (vl.plugin));
  sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
  sstrncpy (vl.type, "smart_attribute", sizeof (vl.type));
  sstrncpy (vl.type_instance, a->name, sizeof (vl.type_instance));

  plugin_dispatch_values (&vl);

  if (a->threshold_valid && a->current_value <= a->threshold)
  {
    notification_t notif = { NOTIF_WARNING,
                             cdtime (),
                             "",
                             "",
                             "smart", "",
                             "smart_attribute",
                             "",
                             NULL };
    sstrncpy (notif.host, hostname_g, sizeof (notif.host));
    sstrncpy (notif.plugin_instance, dev, sizeof (notif.plugin_instance));
    sstrncpy (notif.type_instance, a->name, sizeof (notif.type_instance));
    ssnprintf (notif.message, sizeof (notif.message),
               "attribute %s is below allowed threshold (%d < %d)",
               a->name, a->current_value, a->threshold);
    plugin_dispatch_notification (&notif);
  }
}
コード例 #26
0
ファイル: write_graphite.c プロジェクト: timl/collectd
/* wg_force_reconnect_check closes cb->sock_fd when it was open for longer
 * than cb->reconnect_interval. Must hold cb->send_lock when calling. */
static void wg_force_reconnect_check (struct wg_callback *cb)
{
    cdtime_t now;

    if (cb->reconnect_interval == 0)
        return;

    /* check if address changes if addr_timeout */
    now = cdtime ();
    if ((now - cb->last_reconnect_time) < cb->reconnect_interval)
        return;

    /* here we should close connection on next */
    close (cb->sock_fd);
    cb->sock_fd = -1;
    cb->last_reconnect_time = now;
    cb->reconnect_interval_reached = 1;

    INFO ("write_graphite plugin: Connection closed after %.3f seconds.",
          CDTIME_T_TO_DOUBLE (now - cb->last_reconnect_time));
}
コード例 #27
0
ファイル: dpdkstat.c プロジェクト: Feandil/collectd
static int dpdk_helper_stats_get(dpdk_helper_ctx_t *phc) {
  int len = 0;
  int ret = 0;
  int stats = 0;
  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc);

  /* get stats from DPDK */
  for (uint8_t i = 0; i < ctx->ports_count; i++) {
    if (!(ctx->config.enabled_port_mask & (1 << i)))
      continue;

    ctx->port_read_time[i] = cdtime();
    /* Store available stats array length for port */
    len = ctx->port_stats_count[i];

    ret = rte_eth_xstats_get(i, &ctx->xstats[stats], len);
    if (ret < 0 || ret > len) {
      DPDK_CHILD_LOG(DPDK_STATS_PLUGIN
                     ": Error reading stats (port=%d; len=%d, ret=%d)\n",
                     i, len, ret);
      ctx->port_stats_count[i] = 0;
      return -1;
    }
#if RTE_VERSION >= RTE_VERSION_16_07
    ret = rte_eth_xstats_get_names(i, &ctx->xnames[stats], len);
    if (ret < 0 || ret > len) {
      DPDK_CHILD_LOG(DPDK_STATS_PLUGIN
                     ": Error reading stat names (port=%d; len=%d ret=%d)\n",
                     i, len, ret);
      ctx->port_stats_count[i] = 0;
      return -1;
    }
#endif
    ctx->port_stats_count[i] = ret;
    stats += ctx->port_stats_count[i];
  }

  assert(stats <= ctx->stats_count);
  return 0;
}
コード例 #28
0
ファイル: xencpu.c プロジェクト: BrandonArp/collectd
static int xencpu_read(void) {
  cdtime_t now = cdtime();

  int rc, nr_cpus;

  rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus);
  if (rc < 0) {
    ERROR("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc,
          xc_strerror(xc_handle, errno));
    return -1;
  }

  int status;
  for (int cpu = 0; cpu < nr_cpus; cpu++) {
    gauge_t rate = NAN;

    status = value_to_rate(&rate, (value_t){.derive = cpu_info[cpu].idletime},
                           DS_TYPE_DERIVE, now, &cpu_states[cpu]);
    if (status == 0) {
      submit_value(cpu, 100 - rate / 10000000);
    }
  }
コード例 #29
0
ファイル: postgresql.c プロジェクト: BrianB2/collectd
static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
		user_data_t *ud)
{
	c_psql_database_t *db;

	char time_str[32];
	char values_name_str[1024];
	char values_type_str[1024];
	char values_str[1024];

	const char *params[9];

	int success = 0;
	int i;

	if ((ud == NULL) || (ud->data == NULL)) {
		log_err ("c_psql_write: Invalid user data.");
		return -1;
	}

	db = ud->data;
	assert (db->database != NULL);
	assert (db->writers != NULL);

	if (cdtime_to_iso8601 (time_str, sizeof (time_str), vl->time) == 0) {
		log_err ("c_psql_write: Failed to convert time to ISO 8601 format");
		return -1;
	}

	if (values_name_to_sqlarray (ds,
				values_name_str, sizeof (values_name_str)) == NULL)
		return -1;

#define VALUE_OR_NULL(v) ((((v) == NULL) || (*(v) == '\0')) ? NULL : (v))

	params[0] = time_str;
	params[1] = vl->host;
	params[2] = vl->plugin;
	params[3] = VALUE_OR_NULL(vl->plugin_instance);
	params[4] = vl->type;
	params[5] = VALUE_OR_NULL(vl->type_instance);
	params[6] = values_name_str;

#undef VALUE_OR_NULL

	pthread_mutex_lock (&db->db_lock);

	if (0 != c_psql_check_connection (db)) {
		pthread_mutex_unlock (&db->db_lock);
		return -1;
	}

	if ((db->commit_interval > 0)
			&& (db->next_commit == 0))
		c_psql_begin (db);

	for (i = 0; i < db->writers_num; ++i) {
		c_psql_writer_t *writer;
		PGresult *res;

		writer = db->writers[i];

		if (values_type_to_sqlarray (ds,
					values_type_str, sizeof (values_type_str),
					writer->store_rates) == NULL) {
			pthread_mutex_unlock (&db->db_lock);
			return -1;
		}

		if (values_to_sqlarray (ds, vl,
					values_str, sizeof (values_str),
					writer->store_rates) == NULL) {
			pthread_mutex_unlock (&db->db_lock);
			return -1;
		}

		params[7] = values_type_str;
		params[8] = values_str;

		res = PQexecParams (db->conn, writer->statement,
				STATIC_ARRAY_SIZE (params), NULL,
				(const char *const *)params,
				NULL, NULL, /* return text data */ 0);

		if ((PGRES_COMMAND_OK != PQresultStatus (res))
				&& (PGRES_TUPLES_OK != PQresultStatus (res))) {
			PQclear (res);

			if ((CONNECTION_OK != PQstatus (db->conn))
					&& (0 == c_psql_check_connection (db))) {
				/* try again */
				res = PQexecParams (db->conn, writer->statement,
						STATIC_ARRAY_SIZE (params), NULL,
						(const char *const *)params,
						NULL, NULL, /* return text data */ 0);

				if ((PGRES_COMMAND_OK == PQresultStatus (res))
						|| (PGRES_TUPLES_OK == PQresultStatus (res))) {
					PQclear (res);
					success = 1;
					continue;
				}
			}

			log_err ("Failed to execute SQL query: %s",
					PQerrorMessage (db->conn));
			log_info ("SQL query was: '%s', "
					"params: %s, %s, %s, %s, %s, %s, %s, %s",
					writer->statement,
					params[0], params[1], params[2], params[3],
					params[4], params[5], params[6], params[7]);

			/* this will abort any current transaction -> restart */
			if (db->next_commit > 0)
				c_psql_commit (db);

			pthread_mutex_unlock (&db->db_lock);
			return -1;
		}

		PQclear (res);
		success = 1;
	}

	if ((db->next_commit > 0)
			&& (cdtime () > db->next_commit))
		c_psql_commit (db);

	pthread_mutex_unlock (&db->db_lock);

	if (! success)
		return -1;
	return 0;
} /* c_psql_write */
コード例 #30
0
static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */
{
        int status;

        DEBUG ("write_http plugin: wh_flush_nolock: timeout = %.3f; "
                        "send_buffer_fill = %zu;",
                        CDTIME_T_TO_DOUBLE (timeout),
                        cb->send_buffer_fill);

        /* timeout == 0  => flush unconditionally */
        if (timeout > 0)
        {
                cdtime_t now;

                now = cdtime ();
                if ((cb->send_buffer_init_time + timeout) > now)
                        return (0);
        }

        if (cb->format == WH_FORMAT_COMMAND)
        {
                if (cb->send_buffer_fill == 0)
                {
                        cb->send_buffer_init_time = cdtime ();
                        return (0);
                }

                status = wh_send_buffer (cb);
                wh_reset_buffer (cb);
        }
        else if (cb->format == WH_FORMAT_JSON)
        {
                if (cb->send_buffer_fill <= 2)
                {
                        cb->send_buffer_init_time = cdtime ();
                        return (0);
                }

                status = format_json_finalize (cb->send_buffer,
                                &cb->send_buffer_fill,
                                &cb->send_buffer_free);
                if (status != 0)
                {
                        ERROR ("write_http: wh_flush_nolock: "
                                        "format_json_finalize failed.");
                        wh_reset_buffer (cb);
                        return (status);
                }

                status = wh_send_buffer (cb);
                wh_reset_buffer (cb);
        }
        else
        {
                ERROR ("write_http: wh_flush_nolock: "
                                "Unknown format: %i",
                                cb->format);
                return (-1);
        }

        return (status);
} /* }}} wh_flush_nolock */