Beispiel #1
0
void latency_counter_add (latency_counter_t *lc, cdtime_t latency) /* {{{ */
{
  size_t latency_ms;

  if ((lc == NULL) || (latency == 0))
    return;

  lc->sum += latency;
  lc->num++;

  if ((lc->min == 0) && (lc->max == 0))
    lc->min = lc->max = latency;
  if (lc->min > latency)
    lc->min = latency;
  if (lc->max < latency)
    lc->max = latency;

  /* A latency of _exactly_ 1.0 ms should be stored in the buffer 0, so
   * subtract one from the cdtime_t value so that exactly 1.0 ms get sorted
   * accordingly. */
  latency_ms = (size_t) CDTIME_T_TO_MS (latency - 1);
  if (latency_ms < STATIC_ARRAY_SIZE (lc->histogram))
    lc->histogram[latency_ms]++;
} /* }}} void latency_counter_add */
Beispiel #2
0
static int cc_page_init_curl (web_page_t *wp) /* {{{ */
{
  wp->curl = curl_easy_init ();
  if (wp->curl == NULL)
  {
    ERROR ("curl plugin: curl_easy_init failed.");
    return (-1);
  }

  curl_easy_setopt (wp->curl, CURLOPT_NOSIGNAL, 1L);
  curl_easy_setopt (wp->curl, CURLOPT_WRITEFUNCTION, cc_curl_callback);
  curl_easy_setopt (wp->curl, CURLOPT_WRITEDATA, wp);
  curl_easy_setopt (wp->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
  curl_easy_setopt (wp->curl, CURLOPT_ERRORBUFFER, wp->curl_errbuf);
  curl_easy_setopt (wp->curl, CURLOPT_URL, wp->url);
  curl_easy_setopt (wp->curl, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt (wp->curl, CURLOPT_MAXREDIRS, 50L);

  if (wp->user != NULL)
  {
#ifdef HAVE_CURLOPT_USERNAME
    curl_easy_setopt (wp->curl, CURLOPT_USERNAME, wp->user);
    curl_easy_setopt (wp->curl, CURLOPT_PASSWORD,
        (wp->pass == NULL) ? "" : wp->pass);
#else
    size_t credentials_size;

    credentials_size = strlen (wp->user) + 2;
    if (wp->pass != NULL)
      credentials_size += strlen (wp->pass);

    wp->credentials = malloc (credentials_size);
    if (wp->credentials == NULL)
    {
      ERROR ("curl plugin: malloc failed.");
      return (-1);
    }

    ssnprintf (wp->credentials, credentials_size, "%s:%s",
        wp->user, (wp->pass == NULL) ? "" : wp->pass);
    curl_easy_setopt (wp->curl, CURLOPT_USERPWD, wp->credentials);
#endif

    if (wp->digest)
      curl_easy_setopt (wp->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
  }

  curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYPEER, (long) wp->verify_peer);
  curl_easy_setopt (wp->curl, CURLOPT_SSL_VERIFYHOST,
      wp->verify_host ? 2L : 0L);
  if (wp->cacert != NULL)
    curl_easy_setopt (wp->curl, CURLOPT_CAINFO, wp->cacert);
  if (wp->headers != NULL)
    curl_easy_setopt (wp->curl, CURLOPT_HTTPHEADER, wp->headers);
  if (wp->post_body != NULL)
    curl_easy_setopt (wp->curl, CURLOPT_POSTFIELDS, wp->post_body);

#ifdef HAVE_CURLOPT_TIMEOUT_MS
  if (wp->timeout >= 0)
    curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) wp->timeout);
  else
    curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif

  return (0);
} /* }}} int cc_page_init_curl */
Beispiel #3
0
static int memcached_query_daemon (char *buffer, int buffer_size) /* {{{ */
{
	int fd;
	ssize_t status;
	int buffer_fill;
	int i = 0;

	if (memcached_socket != NULL) {
		struct sockaddr_un serv_addr;

		memset (&serv_addr, 0, sizeof (serv_addr));
		serv_addr.sun_family = AF_UNIX;
		sstrncpy (serv_addr.sun_path, memcached_socket,
				sizeof (serv_addr.sun_path));

		/* create our socket descriptor */
		fd = socket (AF_UNIX, SOCK_STREAM, 0);
		if (fd < 0) {
			char errbuf[1024];
			ERROR ("memcached: unix socket: %s", sstrerror (errno, errbuf,
						sizeof (errbuf)));
			return -1;
		}

		/* connect to the memcached daemon */
		status = (ssize_t) connect (fd, (struct sockaddr *) &serv_addr,
				sizeof (serv_addr));
		if (status != 0) {
			shutdown (fd, SHUT_RDWR);
			close (fd);
			fd = -1;
		}
	}
	else { /* if (memcached_socket == NULL) */
		const char *host;
		const char *port;

		struct addrinfo  ai_hints;
		struct addrinfo *ai_list, *ai_ptr;
		int              ai_return = 0;

		memset (&ai_hints, '\0', sizeof (ai_hints));
		ai_hints.ai_flags    = 0;
#ifdef AI_ADDRCONFIG
		/*	ai_hints.ai_flags   |= AI_ADDRCONFIG; */
#endif
		ai_hints.ai_family   = AF_INET;
		ai_hints.ai_socktype = SOCK_STREAM;
		ai_hints.ai_protocol = 0;

		host = memcached_host;
		if (host == NULL) {
			host = MEMCACHED_DEF_HOST;
		}

		port = memcached_port;
		if (strlen (port) == 0) {
			port = MEMCACHED_DEF_PORT;
		}

		if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0) {
			char errbuf[1024];
			ERROR ("memcached: getaddrinfo (%s, %s): %s",
					host, port,
					(ai_return == EAI_SYSTEM)
					? sstrerror (errno, errbuf, sizeof (errbuf))
					: gai_strerror (ai_return));
			return -1;
		}

		fd = -1;
		for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) {
			/* create our socket descriptor */
			fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
			if (fd < 0) {
				char errbuf[1024];
				ERROR ("memcached: socket: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
				continue;
			}

			/* connect to the memcached daemon */
			status = (ssize_t) connect (fd, (struct sockaddr *) ai_ptr->ai_addr, ai_ptr->ai_addrlen);
			if (status != 0) {
				shutdown (fd, SHUT_RDWR);
				close (fd);
				fd = -1;
				continue;
			}

			/* A socket could be opened and connecting succeeded. We're
			 * done. */
			break;
		}

		freeaddrinfo (ai_list);
	}

	if (fd < 0) {
		ERROR ("memcached: Could not connect to daemon.");
		return -1;
	}

	if (send(fd, "stats\r\n", sizeof("stats\r\n") - 1, MSG_DONTWAIT) != (sizeof("stats\r\n") - 1)) {
		ERROR ("memcached: Could not send command to the memcached daemon.");
		return -1;
	}

	{
		struct pollfd p;
		int status;

		memset (&p, 0, sizeof (p));
		p.fd = fd;
		p.events = POLLIN | POLLERR | POLLHUP;
		p.revents = 0;

		status = poll (&p, /* nfds = */ 1,
				/* timeout = */ CDTIME_T_TO_MS (interval_g));
		if (status <= 0)
		{
			if (status == 0)
			{
				ERROR ("memcached: poll(2) timed out after %.3f seconds.",
						CDTIME_T_TO_DOUBLE (interval_g));
			}
			else
			{
				char errbuf[1024];
				ERROR ("memcached: poll(2) failed: %s",
						sstrerror (errno, errbuf, sizeof (errbuf)));
			}
			shutdown (fd, SHUT_RDWR);
			close (fd);
			return (-1);
		}
	}

	/* receive data from the memcached daemon */
	memset (buffer, '\0', buffer_size);

	buffer_fill = 0;
	while ((status = recv (fd, buffer + buffer_fill, buffer_size - buffer_fill, MSG_DONTWAIT)) != 0) {
		if (i > MEMCACHED_RETRY_COUNT) {
			ERROR("recv() timed out");
			break;
		}
		i++;

		if (status == -1) {
			char errbuf[1024];

			if (errno == EAGAIN) {
				continue;
			}

			ERROR ("memcached: Error reading from socket: %s",
					sstrerror (errno, errbuf, sizeof (errbuf)));
			shutdown(fd, SHUT_RDWR);
			close (fd);
			return -1;
		}
		buffer_fill += status;

		if (buffer_fill > 3 && buffer[buffer_fill-5] == 'E' && buffer[buffer_fill-4] == 'N' && buffer[buffer_fill-3] == 'D') {
			/* we got all the data */
			break;
		}
	}

	if (buffer_fill >= buffer_size) {
		buffer[buffer_size - 1] = '\0';
		WARNING ("memcached: Message from memcached has been truncated.");
	} else if (buffer_fill == 0) {
		WARNING ("memcached: Peer has unexpectedly shut down the socket. "
				"Buffer: `%s'", buffer);
		shutdown(fd, SHUT_RDWR);
		close(fd);
		return -1;
	}

	shutdown(fd, SHUT_RDWR);
	close(fd);
	return 0;
}
Beispiel #4
0
static int dns_run_pcap_loop (void)
{
	pcap_t *pcap_obj;
	char    pcap_error[PCAP_ERRBUF_SIZE];
	struct  bpf_program fp = { 0 };

	int status;

	/* Don't block any signals */
	{
		sigset_t sigmask;
		sigemptyset (&sigmask);
		pthread_sigmask (SIG_SETMASK, &sigmask, NULL);
	}

	/* Passing `pcap_device == NULL' is okay and the same as passign "any" */
	DEBUG ("dns plugin: Creating PCAP object..");
	pcap_obj = pcap_open_live ((pcap_device != NULL) ? pcap_device : "any",
			PCAP_SNAPLEN,
			0 /* Not promiscuous */,
			(int) CDTIME_T_TO_MS (plugin_get_interval () / 2),
			pcap_error);
	if (pcap_obj == NULL)
	{
		ERROR ("dns plugin: Opening interface `%s' "
				"failed: %s",
				(pcap_device != NULL) ? pcap_device : "any",
				pcap_error);
		return (PCAP_ERROR);
	}

	status = pcap_compile (pcap_obj, &fp, "udp port 53", 1, 0);
	if (status < 0)
	{
		ERROR ("dns plugin: pcap_compile failed: %s",
				pcap_statustostr (status));
		return (status);
	}

	status = pcap_setfilter (pcap_obj, &fp);
	if (status < 0)
	{
		ERROR ("dns plugin: pcap_setfilter failed: %s",
				pcap_statustostr (status));
		return (status);
	}

	DEBUG ("dns plugin: PCAP object created.");

	dnstop_set_pcap_obj (pcap_obj);
	dnstop_set_callback (dns_child_callback);

	status = pcap_loop (pcap_obj,
			-1 /* loop forever */,
			handle_pcap /* callback */,
			NULL /* user data */);
	INFO ("dns plugin: pcap_loop exited with status %i.", status);
	/* We need to handle "PCAP_ERROR" specially because libpcap currently
	 * doesn't return PCAP_ERROR_IFACE_NOT_UP for compatibility reasons. */
	if (status == PCAP_ERROR)
		status = PCAP_ERROR_IFACE_NOT_UP;

	pcap_close (pcap_obj);
	return (status);
} /* int dns_run_pcap_loop */
Beispiel #5
0
/*
 * Functions
 */
static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
    const value_list_t *vl,
    _Bool store_rates)
{
  bson *ret;
  gauge_t *rates;

  ret = bson_alloc (); /* matched by bson_dealloc() */
  if (ret == NULL)
  {
    ERROR ("write_mongodb plugin: bson_create failed.");
    return (NULL);
  }

  if (store_rates)
  {
    rates = uc_get_rate (ds, vl);
    if (rates == NULL)
    {
      ERROR ("write_mongodb plugin: uc_get_rate() failed.");
      return (NULL);
    }
  }
  else
  {
    rates = NULL;
  }

  bson_init (ret); /* matched by bson_destroy() */
  bson_append_date (ret, "time", (bson_date_t) CDTIME_T_TO_MS (vl->time));
  bson_append_string (ret, "host", vl->host);
  bson_append_string (ret, "plugin", vl->plugin);
  bson_append_string (ret, "plugin_instance", vl->plugin_instance);
  bson_append_string (ret, "type", vl->type);
  bson_append_string (ret, "type_instance", vl->type_instance);

  bson_append_start_array (ret, "values"); /* {{{ */
  for (int i = 0; i < ds->ds_num; i++)
  {
    char key[16];

    ssnprintf (key, sizeof (key), "%i", i);

    if (ds->ds[i].type == DS_TYPE_GAUGE)
      bson_append_double(ret, key, vl->values[i].gauge);
    else if (store_rates)
      bson_append_double(ret, key, (double) rates[i]);
    else if (ds->ds[i].type == DS_TYPE_COUNTER)
      bson_append_long(ret, key, vl->values[i].counter);
    else if (ds->ds[i].type == DS_TYPE_DERIVE)
      bson_append_long(ret, key, vl->values[i].derive);
    else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
      bson_append_long(ret, key, vl->values[i].absolute);
    else
      assert (23 == 42);
  }
  bson_append_finish_array (ret); /* }}} values */

  bson_append_start_array (ret, "dstypes"); /* {{{ */
  for (int i = 0; i < ds->ds_num; i++)
  {
    char key[16];

    ssnprintf (key, sizeof (key), "%i", i);

    if (store_rates)
      bson_append_string (ret, key, "gauge");
    else
      bson_append_string (ret, key, DS_TYPE_TO_STRING (ds->ds[i].type));
  }
  bson_append_finish_array (ret); /* }}} dstypes */

  bson_append_start_array (ret, "dsnames"); /* {{{ */
  for (int i = 0; i < ds->ds_num; i++)
  {
    char key[16];

    ssnprintf (key, sizeof (key), "%i", i);
    bson_append_string (ret, key, ds->ds[i].name);
  }
  bson_append_finish_array (ret); /* }}} dsnames */

  bson_finish (ret);

  sfree (rates);
  return (ret);
} /* }}} bson *wm_create_bson */
static int values_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */
                              const data_set_t *ds, const value_list_t *vl,
                              int store_rates, size_t ds_idx) {
  size_t offset = 0;
  gauge_t *rates = NULL;

  memset(buffer, 0, buffer_size);

#define BUFFER_ADD(...)                                                        \
  do {                                                                         \
    int status;                                                                \
    status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__);     \
    if (status < 1) {                                                          \
      sfree(rates);                                                            \
      return -1;                                                               \
    } else if (((size_t)status) >= (buffer_size - offset)) {                   \
      sfree(rates);                                                            \
      return -ENOMEM;                                                          \
    } else                                                                     \
      offset += ((size_t)status);                                              \
  } while (0)

  if (ds->ds[ds_idx].type == DS_TYPE_GAUGE) {
    if (isfinite(vl->values[ds_idx].gauge)) {
      BUFFER_ADD("[[");
      BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
      BUFFER_ADD(",");
      BUFFER_ADD(JSON_GAUGE_FORMAT, vl->values[ds_idx].gauge);
    } else {
      DEBUG("utils_format_kairosdb: invalid vl->values[ds_idx].gauge for "
            "%s|%s|%s|%s|%s",
            vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
            ds->ds[ds_idx].name);
      return -1;
    }
  } else if (store_rates) {
    if (rates == NULL)
      rates = uc_get_rate(ds, vl);
    if (rates == NULL) {
      WARNING("utils_format_kairosdb: uc_get_rate failed for %s|%s|%s|%s|%s",
              vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
              ds->ds[ds_idx].name);

      return -1;
    }

    if (isfinite(rates[ds_idx])) {
      BUFFER_ADD("[[");
      BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
      BUFFER_ADD(",");
      BUFFER_ADD(JSON_GAUGE_FORMAT, rates[ds_idx]);
    } else {
      WARNING("utils_format_kairosdb: invalid rates[ds_idx] for %s|%s|%s|%s|%s",
              vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
              ds->ds[ds_idx].name);
      sfree(rates);
      return -1;
    }
  } else if (ds->ds[ds_idx].type == DS_TYPE_COUNTER) {
    BUFFER_ADD("[[");
    BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
    BUFFER_ADD(",");
    BUFFER_ADD("%" PRIu64, (uint64_t)vl->values[ds_idx].counter);
  } else if (ds->ds[ds_idx].type == DS_TYPE_DERIVE) {
    BUFFER_ADD("[[");
    BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
    BUFFER_ADD(",");
    BUFFER_ADD("%" PRIi64, vl->values[ds_idx].derive);
  } else if (ds->ds[ds_idx].type == DS_TYPE_ABSOLUTE) {
    BUFFER_ADD("[[");
    BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
    BUFFER_ADD(",");
    BUFFER_ADD("%" PRIu64, vl->values[ds_idx].absolute);
  } else {
    ERROR("format_kairosdb: Unknown data source type: %i", ds->ds[ds_idx].type);
    sfree(rates);
    return -1;
  }
  BUFFER_ADD("]]");

#undef BUFFER_ADD

  DEBUG("format_kairosdb: values_to_kairosdb: buffer = %s;", buffer);
  sfree(rates);
  return 0;
} /* }}} int values_to_kairosdb */
Beispiel #7
0
/* initialize curl for each host */
static int init_host (apache_t *st) /* {{{ */
{
	assert (st->url != NULL);
	/* (Assured by `config_add') */

	if (st->curl != NULL)
	{
		curl_easy_cleanup (st->curl);
		st->curl = NULL;
	}

	if ((st->curl = curl_easy_init ()) == NULL)
	{
		ERROR ("apache plugin: init_host: `curl_easy_init' failed.");
		return (-1);
	}

	curl_easy_setopt (st->curl, CURLOPT_NOSIGNAL, 1L);
	curl_easy_setopt (st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback);
	curl_easy_setopt (st->curl, CURLOPT_WRITEDATA, st);

	/* not set as yet if the user specified string doesn't match apache or
	 * lighttpd, then ignore it. Headers will be parsed to find out the
	 * server type */
	st->server_type = -1;

	if (st->server != NULL)
	{
		if (strcasecmp(st->server, "apache") == 0)
			st->server_type = APACHE;
		else if (strcasecmp(st->server, "lighttpd") == 0)
			st->server_type = LIGHTTPD;
		else if (strcasecmp(st->server, "ibm_http_server") == 0)
			st->server_type = APACHE;
		else
			WARNING ("apache plugin: Unknown `Server' setting: %s",
					st->server);
	}

	/* if not found register a header callback to determine the server_type */
	if (st->server_type == -1)
	{
		curl_easy_setopt (st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback);
		curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st);
	}

	curl_easy_setopt (st->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
	curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error);

	if (st->user != NULL)
	{
#ifdef HAVE_CURLOPT_USERNAME
		curl_easy_setopt (st->curl, CURLOPT_USERNAME, st->user);
		curl_easy_setopt (st->curl, CURLOPT_PASSWORD,
				(st->pass == NULL) ? "" : st->pass);
#else
		static char credentials[1024];
		int status;

		status = ssnprintf (credentials, sizeof (credentials), "%s:%s",
				st->user, (st->pass == NULL) ? "" : st->pass);
		if ((status < 0) || ((size_t) status >= sizeof (credentials)))
		{
			ERROR ("apache plugin: init_host: Returning an error "
					"because the credentials have been "
					"truncated.");
			curl_easy_cleanup (st->curl);
			st->curl = NULL;
			return (-1);
		}

		curl_easy_setopt (st->curl, CURLOPT_USERPWD, credentials);
#endif
	}

	curl_easy_setopt (st->curl, CURLOPT_URL, st->url);
	curl_easy_setopt (st->curl, CURLOPT_FOLLOWLOCATION, 1L);
	curl_easy_setopt (st->curl, CURLOPT_MAXREDIRS, 50L);

	curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER,
			(long) st->verify_peer);
	curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST,
			st->verify_host ? 2L : 0L);
	if (st->cacert != NULL)
		curl_easy_setopt (st->curl, CURLOPT_CAINFO, st->cacert);
	if (st->ssl_ciphers != NULL)
		curl_easy_setopt (st->curl, CURLOPT_SSL_CIPHER_LIST,st->ssl_ciphers);

#ifdef HAVE_CURLOPT_TIMEOUT_MS
	if (st->timeout >= 0)
		curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) st->timeout);
	else
		curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif

	return (0);
} /* }}} int init_host */