コード例 #1
0
ファイル: cgroups.c プロジェクト: ajdiaz/collectd
/*
 * This callback reads the user/system CPU time for each cgroup.
 */
static int read_cpuacct_procs(const char *dirname, char const *cgroup_name,
                              void *user_data) {
  char abs_path[PATH_MAX];
  struct stat statbuf;
  char buf[1024];
  int status;

  FILE *fh;

  if (ignorelist_match(il_cgroup, cgroup_name))
    return (0);

  ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, cgroup_name);

  status = lstat(abs_path, &statbuf);
  if (status != 0) {
    ERROR("cgroups plugin: stat (\"%s\") failed.", abs_path);
    return (-1);
  }

  /* We are only interested in directories, so skip everything else. */
  if (!S_ISDIR(statbuf.st_mode))
    return (0);

  ssnprintf(abs_path, sizeof(abs_path), "%s/%s/cpuacct.stat", dirname,
            cgroup_name);
  fh = fopen(abs_path, "r");
  if (fh == NULL) {
    char errbuf[1024];
    ERROR("cgroups plugin: fopen (\"%s\") failed: %s", abs_path,
          sstrerror(errno, errbuf, sizeof(errbuf)));
    return (-1);
  }

  while (fgets(buf, sizeof(buf), fh) != NULL) {
    char *fields[8];
    int numfields = 0;
    char *key;
    size_t key_len;
    value_t value;

    /* Expected format:
     *
     *   user: 12345
     *   system: 23456
     *
     * Or:
     *
     *   user 12345
     *   system 23456
     */
    strstripnewline(buf);
    numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields));
    if (numfields != 2)
      continue;

    key = fields[0];
    key_len = strlen(key);
    if (key_len < 2)
      continue;

    /* Strip colon off the first column, if found */
    if (key[key_len - 1] == ':')
      key[key_len - 1] = 0;

    status = parse_value(fields[1], &value, DS_TYPE_DERIVE);
    if (status != 0)
      continue;

    cgroups_submit_one(cgroup_name, key, value);
  }

  fclose(fh);
  return (0);
} /* int read_cpuacct_procs */
コード例 #2
0
ファイル: battery.c プロジェクト: Civil/collectd
static int read_pmu (void) /* {{{ */
{
	int i;

	/* The upper limit here is just a safeguard. If there is a system with
	 * more than 100 batteries, this can easily be increased. */
	for (i = 0; i < 100; i++)
	{
		FILE *fh;

		char buffer[1024];
		char filename[PATH_MAX];
		char plugin_instance[DATA_MAX_NAME_LEN];

		gauge_t current = NAN;
		gauge_t voltage = NAN;
		gauge_t charge  = NAN;

		ssnprintf (filename, sizeof (filename), PROC_PMU_PATH_FORMAT, i);
		if (access (filename, R_OK) != 0)
			break;

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

		fh = fopen (filename, "r");
		if (fh == NULL)
		{
			if (errno == ENOENT)
				break;
			else if ((errno == EAGAIN) || (errno == EINTR))
				continue;
			else
				return (errno);
		}

		while (fgets (buffer, sizeof (buffer), fh) != NULL)
		{
			char *fields[8];
			int numfields;

			numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
			if (numfields < 3)
				continue;

			if (strcmp ("current", fields[0]) == 0)
				strtogauge (fields[2], &current);
			else if (strcmp ("voltage", fields[0]) == 0)
				strtogauge (fields[2], &voltage);
			else if (strcmp ("charge", fields[0]) == 0)
				strtogauge (fields[2], &charge);
		}

		fclose (fh);
		fh = NULL;

		battery_submit (plugin_instance, "charge", charge / 1000.0);
		battery_submit (plugin_instance, "current", current / 1000.0);
		battery_submit (plugin_instance, "voltage", voltage / 1000.0);
	}

	if (i == 0)
		return (ENOENT);
	return (0);
} /* }}} int read_pmu */
コード例 #3
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 */
コード例 #4
0
ファイル: protocols.c プロジェクト: ajdiaz/collectd
static int read_file(const char *path) {
  FILE *fh;
  char key_buffer[4096];
  char value_buffer[4096];
  char *key_ptr;
  char *value_ptr;
  char *key_fields[256];
  char *value_fields[256];
  int key_fields_num;
  int value_fields_num;
  int status;
  int i;

  fh = fopen(path, "r");
  if (fh == NULL) {
    ERROR("protocols plugin: fopen (%s) failed: %s.", path,
          sstrerror(errno, key_buffer, sizeof(key_buffer)));
    return (-1);
  }

  status = -1;
  while (42) {
    clearerr(fh);
    key_ptr = fgets(key_buffer, sizeof(key_buffer), fh);
    if (key_ptr == NULL) {
      if (feof(fh) != 0) {
        status = 0;
        break;
      } else if (ferror(fh) != 0) {
        ERROR("protocols plugin: Reading from %s failed.", path);
        break;
      } else {
        ERROR("protocols plugin: fgets failed for an unknown reason.");
        break;
      }
    } /* if (key_ptr == NULL) */

    value_ptr = fgets(value_buffer, sizeof(value_buffer), fh);
    if (value_ptr == NULL) {
      ERROR("protocols plugin: read_file (%s): Could not read values line.",
            path);
      break;
    }

    key_ptr = strchr(key_buffer, ':');
    if (key_ptr == NULL) {
      ERROR("protocols plugin: Could not find protocol name in keys line.");
      break;
    }
    *key_ptr = 0;
    key_ptr++;

    value_ptr = strchr(value_buffer, ':');
    if (value_ptr == NULL) {
      ERROR("protocols plugin: Could not find protocol name "
            "in values line.");
      break;
    }
    *value_ptr = 0;
    value_ptr++;

    if (strcmp(key_buffer, value_buffer) != 0) {
      ERROR("protocols plugin: Protocol names in keys and values lines "
            "don't match: `%s' vs. `%s'.",
            key_buffer, value_buffer);
      break;
    }

    key_fields_num =
        strsplit(key_ptr, key_fields, STATIC_ARRAY_SIZE(key_fields));
    value_fields_num =
        strsplit(value_ptr, value_fields, STATIC_ARRAY_SIZE(value_fields));

    if (key_fields_num != value_fields_num) {
      ERROR("protocols plugin: Number of fields in keys and values lines "
            "don't match: %i vs %i.",
            key_fields_num, value_fields_num);
      break;
    }

    for (i = 0; i < key_fields_num; i++) {
      if (values_list != NULL) {
        char match_name[2 * DATA_MAX_NAME_LEN];

        ssnprintf(match_name, sizeof(match_name), "%s:%s", key_buffer,
                  key_fields[i]);

        if (ignorelist_match(values_list, match_name))
          continue;
      } /* if (values_list != NULL) */

      submit(key_buffer, key_fields[i], value_fields[i]);
    } /* for (i = 0; i < key_fields_num; i++) */
  }   /* while (42) */

  fclose(fh);

  return (status);
} /* int read_file */
コード例 #5
0
ファイル: uptime.c プロジェクト: brd/collectd
static int uptime_init (void) /* {{{ */
{
	/*
	 * On most unix systems the uptime is calculated by looking at the boot
	 * time (stored in unix time, since epoch) and the current one. We are
	 * going to do the same, reading the boot time value while executing
	 * the uptime_init function (there is no need to read, every time the
	 * plugin_read is called, a value that won't change). However, since
	 * uptime_init is run only once, if the function fails in retrieving
	 * the boot time, the plugin is unregistered and there is no chance to
	 * try again later. Nevertheless, this is very unlikely to happen.
	 */

#if KERNEL_LINUX
	unsigned long starttime;
	char buffer[1024];
	int ret;
	FILE *fh;

	ret = 0;

	fh = fopen (STAT_FILE, "r");

	if (fh == NULL)
	{
		char errbuf[1024];
		ERROR ("uptime plugin: Cannot open "STAT_FILE": %s",
			sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	while (fgets (buffer, 1024, fh) != NULL)
	{
		/* look for the btime string and read the value */
		ret = sscanf (buffer, "btime %lu", &starttime);
		/* avoid further loops if btime has been found and read
		 * correctly (hopefully) */
		if (ret == 1)
			break;
	}

	fclose (fh);

	/* loop done, check if no value has been found/read */
	if (ret != 1)
	{
		ERROR ("uptime plugin: No value read from "STAT_FILE"");
		return (-1);
	}

	boottime = (time_t) starttime;

	if (boottime == 0)
	{
		ERROR ("uptime plugin: btime read from "STAT_FILE", "
				"but `boottime' is zero!");
		return (-1);
	}
/* #endif KERNEL_LINUX */

#elif HAVE_LIBKSTAT
	kstat_t *ksp;
	kstat_named_t *knp;

	ksp = NULL;
	knp = NULL;

	/* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
	if (kc == NULL)
	{
		ERROR ("uptime plugin: kstat chain control structure not available.");
		return (-1);
	}

	ksp = kstat_lookup (kc, "unix", 0, "system_misc");
	if (ksp == NULL)
	{
		ERROR ("uptime plugin: Cannot find unix:0:system_misc kstat.");
		return (-1);
	}

	if (kstat_read (kc, ksp, NULL) < 0)
	{
		ERROR ("uptime plugin: kstat_read failed.");
		return (-1);
	}

	knp = (kstat_named_t *) kstat_data_lookup (ksp, "boot_time");
	if (knp == NULL)
	{
		ERROR ("uptime plugin: kstat_data_lookup (boot_time) failed.");
		return (-1);
	}

	boottime = (time_t) knp->value.ui32;

	if (boottime == 0)
	{
		ERROR ("uptime plugin: kstat_data_lookup returned success, "
			"but `boottime' is zero!");
		return (-1);
	}
/* #endif HAVE_LIBKSTAT */

# elif HAVE_SYS_SYSCTL_H
	struct timeval boottv = { 0 };
	size_t boottv_len;
	int status;

	int mib[] = { CTL_KERN, KERN_BOOTTIME };

	boottv_len = sizeof (boottv);

	status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len,
			/* new_value = */ NULL, /* new_length = */ 0);
	if (status != 0)
	{
		char errbuf[1024];
		ERROR ("uptime plugin: No value read from sysctl interface: %s",
			sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	boottime = boottv.tv_sec;

	if (boottime == 0)
	{
		ERROR ("uptime plugin: sysctl(3) returned success, "
				"but `boottime' is zero!");
		return (-1);
	}
/* #endif HAVE_SYS_SYSCTL_H */

#elif HAVE_PERFSTAT
	int status;
	perfstat_cpu_total_t cputotal;
	int hertz;

	status = perfstat_cpu_total(NULL, &cputotal,
		sizeof(perfstat_cpu_total_t), 1);
	if (status < 0)
	{
		char errbuf[1024];
		ERROR ("uptime plugin: perfstat_cpu_total: %s",
			sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	hertz = sysconf(_SC_CLK_TCK);
	if (hertz <= 0)
		hertz = HZ;

	boottime = time(NULL) - cputotal.lbolt / hertz;
#endif /* HAVE_PERFSTAT */

	return (0);
} /* }}} int uptime_init */
コード例 #6
0
ファイル: config_cores.c プロジェクト: collectd/collectd
int config_cores_parse(const oconfig_item_t *ci, core_groups_list_t *cgl) {
  if (ci == NULL || cgl == NULL)
    return -EINVAL;
  if (ci->values_num == 0 || ci->values_num > MAX_CORES)
    return -EINVAL;
  core_group_t cgroups[MAX_CORES] = {{0}};
  size_t cg_idx = 0; /* index for cgroups array */
  int ret = 0;

  for (int i = 0; i < ci->values_num; i++) {
    if (ci->values[i].type != OCONFIG_TYPE_STRING) {
      WARNING(UTIL_NAME ": The %s option requires string arguments.", ci->key);
      return -EINVAL;
    }
  }

  if (ci->values_num == 1 && ci->values[0].value.string &&
      strlen(ci->values[0].value.string) == 0)
    return 0;

  for (int i = 0; i < ci->values_num; i++) {
    size_t n;
    _Bool grouped = 1;
    char str[DATA_MAX_NAME_LEN];
    unsigned cores[MAX_CORES] = {0};

    if (cg_idx >= STATIC_ARRAY_SIZE(cgroups)) {
      ERROR(UTIL_NAME
            ": Configuration exceeds maximum number of cores: %" PRIsz,
            STATIC_ARRAY_SIZE(cgroups));
      ret = -EINVAL;
      goto parse_error;
    }
    if ((ci->values[i].value.string == NULL) ||
        (strlen(ci->values[i].value.string) == 0)) {
      ERROR(UTIL_NAME ": Failed to parse parameters for %s option.", ci->key);
      ret = -EINVAL;
      goto parse_error;
    }

    ret = check_core_grouping(str, ci->values[i].value.string, sizeof(str),
                              &grouped);
    if (ret != 0) {
      ERROR(UTIL_NAME ": Failed to parse config option [%d] %s.", i,
            ci->values[i].value.string);
      goto parse_error;
    }
    n = str_list_to_nums(str, cores, STATIC_ARRAY_SIZE(cores));
    if (n == 0) {
      ERROR(UTIL_NAME ": Failed to parse config option [%d] %s.", i,
            ci->values[i].value.string);
      ret = -EINVAL;
      goto parse_error;
    }

    if (grouped) {
      cgroups[cg_idx].desc = strdup(ci->values[i].value.string);
      if (cgroups[cg_idx].desc == NULL) {
        ERROR(UTIL_NAME ": Failed to allocate description.");
        ret = -ENOMEM;
        goto parse_error;
      }

      cgroups[cg_idx].cores = calloc(n, sizeof(*cgroups[cg_idx].cores));
      if (cgroups[cg_idx].cores == NULL) {
        ERROR(UTIL_NAME ": Failed to allocate cores for cgroup.");
        ret = -ENOMEM;
        goto parse_error;
      }

      for (size_t j = 0; j < n; j++)
        cgroups[cg_idx].cores[j] = cores[j];

      cgroups[cg_idx].num_cores = n;
      cg_idx++;
    } else {
      for (size_t j = 0; j < n && cg_idx < STATIC_ARRAY_SIZE(cgroups); j++) {
        char desc[DATA_MAX_NAME_LEN];
        snprintf(desc, sizeof(desc), "%u", cores[j]);

        cgroups[cg_idx].desc = strdup(desc);
        if (cgroups[cg_idx].desc == NULL) {
          ERROR(UTIL_NAME ": Failed to allocate desc for core %u.", cores[j]);
          ret = -ENOMEM;
          goto parse_error;
        }

        cgroups[cg_idx].cores = calloc(1, sizeof(*(cgroups[cg_idx].cores)));
        if (cgroups[cg_idx].cores == NULL) {
          ERROR(UTIL_NAME ": Failed to allocate cgroup for core %u.", cores[j]);
          ret = -ENOMEM;
          goto parse_error;
        }
        cgroups[cg_idx].num_cores = 1;
        cgroups[cg_idx].cores[0] = cores[j];
        cg_idx++;
      }
    }
  }

  cgl->cgroups = calloc(cg_idx, sizeof(*cgl->cgroups));
  if (cgl->cgroups == NULL) {
    ERROR(UTIL_NAME ": Failed to allocate core groups.");
    ret = -ENOMEM;
    goto parse_error;
  }

  cgl->num_cgroups = cg_idx;
  for (size_t i = 0; i < cg_idx; i++)
    cgl->cgroups[i] = cgroups[i];

  return 0;

parse_error:

  cg_idx = 0;
  while (cg_idx < STATIC_ARRAY_SIZE(cgroups) && cgroups[cg_idx].desc != NULL) {
    sfree(cgroups[cg_idx].desc);
    sfree(cgroups[cg_idx].cores);
    cg_idx++;
  }
  return ret;
}
コード例 #7
0
ファイル: utils_rrdcreate.c プロジェクト: emiddleton/collectd
#include <pthread.h>
#include <rrd.h>

/*
 * Private variables
 */
static int rra_timespans[] =
{
  3600,
  86400,
  604800,
  2678400,
  31622400
};
static int rra_timespans_num = STATIC_ARRAY_SIZE (rra_timespans);

static char *rra_types[] =
{
  "AVERAGE",
  "MIN",
  "MAX"
};
static int rra_types_num = STATIC_ARRAY_SIZE (rra_types);

#if !defined(HAVE_THREADSAFE_LIBRRD) || !HAVE_THREADSAFE_LIBRRD
static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER;
#endif

/*
 * Private functions
コード例 #8
0
ファイル: gmond.c プロジェクト: hasso/collectd
     {"load_fifteen", "load", "", "longterm", -1, -1},
     {"cpu_user", "cpu", "user", "value", -1, -1},
     {"cpu_system", "cpu", "system", "value", -1, -1},
     {"cpu_idle", "cpu", "idle", "value", -1, -1},
     {"cpu_nice", "cpu", "nice", "value", -1, -1},
     {"cpu_wio", "cpu", "wait", "value", -1, -1},
     {"mem_free", "memory", "free", "value", -1, -1},
     {"mem_shared", "memory", "shared", "value", -1, -1},
     {"mem_buffers", "memory", "buffered", "value", -1, -1},
     {"mem_cached", "memory", "cached", "value", -1, -1},
     {"mem_total", "memory", "total", "value", -1, -1},
     {"bytes_in", "if_octets", "", "rx", -1, -1},
     {"bytes_out", "if_octets", "", "tx", -1, -1},
     {"pkts_in", "if_packets", "", "rx", -1, -1},
     {"pkts_out", "if_packets", "", "tx", -1, -1}};
static size_t metric_map_len_default = STATIC_ARRAY_SIZE(metric_map_default);

static metric_map_t *metric_map = NULL;
static size_t metric_map_len = 0;

static c_avl_tree_t *staging_tree;
static pthread_mutex_t staging_lock = PTHREAD_MUTEX_INITIALIZER;

static metric_map_t *metric_lookup(const char *key) /* {{{ */
{
  metric_map_t *map;
  size_t map_len;
  size_t i;

  /* Search the user-supplied table first.. */
  map = metric_map;
コード例 #9
0
ファイル: madwifi.c プロジェクト: fcagsaway/collectd
static inline int item_watched(int i)
{
	assert (i >= 0);
	assert (i < ((STATIC_ARRAY_SIZE (watch_items) + 1) * 32));
	return watch_items[i / 32] & FLAG (i);
}
コード例 #10
0
ファイル: openvpn.c プロジェクト: brd/collectd
/* for reading status version 4 */
static int multi4_read (const char *name, FILE *fh)
{
	char buffer[1024];
	char *fields[11];
	const int max_fields = STATIC_ARRAY_SIZE (fields);
	int  fields_num, read = 0;
	long long sum_users    = 0;

	while (fgets (buffer, sizeof (buffer), fh) != NULL)
	{
		fields_num = openvpn_strsplit (buffer, fields, max_fields);

		/* status file is generated by openvpn/multi.c:multi_print_status()
		 * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
		 *
		 * The line we're expecting has 9 fields. We ignore all lines
		 *  with more or less fields.
		 */
		if (fields_num != 9)
			continue;


		if (strcmp (fields[0], "CLIENT_LIST") != 0)
			continue;


		if (collect_user_count)
			/* If so, sum all users, ignore the individuals*/
		{
			sum_users += 1;
		}
		if (collect_individual_users)
		{
			if (new_naming_schema)
			{
				/* plugin inst = file name, type inst = fields[1] */
				iostats_submit (name,               /* vpn instance */
						fields[1],          /* "Common Name" */
						atoll (fields[4]),  /* "Bytes Received" */
						atoll (fields[5])); /* "Bytes Sent" */
			}
			else
			{
				/* plugin inst = fields[1], type inst = "" */
				iostats_submit (fields[1],          /* "Common Name" */
						NULL,               /* unused when in multimode */
						atoll (fields[4]),  /* "Bytes Received" */
						atoll (fields[5])); /* "Bytes Sent" */
			}
		}

		read = 1;
	}

	if (collect_user_count)
	{
		numusers_submit(name, name, sum_users);
		read = 1;
	}

	return (read);
} /* int multi4_read */
コード例 #11
0
ファイル: battery.c プロジェクト: ajdiaz/collectd
static int read_acpi_callback(char const *dir, /* {{{ */
                              char const *power_supply, void *user_data) {
  int *battery_index = user_data;

  gauge_t power = NAN;
  gauge_t voltage = NAN;
  gauge_t capacity_charged = NAN;
  gauge_t capacity_full = NAN;
  gauge_t capacity_design = NAN;
  _Bool charging = 0;
  _Bool is_current = 0;

  char const *plugin_instance;
  char filename[PATH_MAX];
  char buffer[1024];

  FILE *fh;

  ssnprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply);
  fh = fopen(filename, "r");
  if (fh == NULL) {
    if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT))
      return (0);
    else
      return (errno);
  }

  /*
   * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state
   * [11:00] <@tokkee> present:                 yes
   * [11:00] <@tokkee> capacity state:          ok
   * [11:00] <@tokkee> charging state:          charging
   * [11:00] <@tokkee> present rate:            1724 mA
   * [11:00] <@tokkee> remaining capacity:      4136 mAh
   * [11:00] <@tokkee> present voltage:         12428 mV
   */
  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
    char *fields[8];
    int numfields;

    numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
    if (numfields < 3)
      continue;

    if ((strcmp(fields[0], "charging") == 0) &&
        (strcmp(fields[1], "state:") == 0)) {
      if (strcmp(fields[2], "charging") == 0)
        charging = 1;
      else
        charging = 0;
      continue;
    }

    /* The unit of "present rate" depends on the battery. Modern
     * batteries export power (watts), older batteries (used to)
     * export current (amperes). We check the fourth column and try
     * to find old batteries this way. */
    if ((strcmp(fields[0], "present") == 0) &&
        (strcmp(fields[1], "rate:") == 0)) {
      strtogauge(fields[2], &power);

      if ((numfields >= 4) && (strcmp("mA", fields[3]) == 0))
        is_current = 1;
    } else if ((strcmp(fields[0], "remaining") == 0) &&
               (strcmp(fields[1], "capacity:") == 0))
      strtogauge(fields[2], &capacity_charged);
    else if ((strcmp(fields[0], "present") == 0) &&
             (strcmp(fields[1], "voltage:") == 0))
      strtogauge(fields[2], &voltage);
  } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */

  fclose(fh);

  if (!charging)
    power *= -1.0;

  /* FIXME: This is a dirty hack for backwards compatibility: The battery
   * plugin, for a very long time, has had the plugin_instance
   * hard-coded to "0". So, to keep backwards compatibility, we'll use
   * "0" for the first battery we find and the power_supply name for all
   * following. This should be reverted in a future major version. */
  plugin_instance = (*battery_index == 0) ? "0" : power_supply;
  (*battery_index)++;

  read_acpi_full_capacity(dir, power_supply, &capacity_full, &capacity_design);

  submit_capacity(plugin_instance, capacity_charged * PROC_ACPI_FACTOR,
                  capacity_full * PROC_ACPI_FACTOR,
                  capacity_design * PROC_ACPI_FACTOR);

  battery_submit(plugin_instance, is_current ? "current" : "power",
                 power * PROC_ACPI_FACTOR);
  battery_submit(plugin_instance, "voltage", voltage * PROC_ACPI_FACTOR);

  return 0;
} /* }}} int read_acpi_callback */
コード例 #12
0
ファイル: openvpn.c プロジェクト: brd/collectd
/* for reading status version 1 */
static int multi1_read (const char *name, FILE *fh)
{
	char buffer[1024];
	char *fields[10];
	int  fields_num, found_header = 0;
	long long sum_users = 0;

	/* read the file until the "ROUTING TABLE" line is found (no more info after) */
	while (fgets (buffer, sizeof (buffer), fh) != NULL)
	{
		if (strcmp (buffer, "ROUTING TABLE\n") == 0)
			break;

		if (strcmp (buffer, V1STRING) == 0)
		{
			found_header = 1;
			continue;
		}

		/* skip the first lines until the client list section is found */
		if (found_header == 0)
			/* we can't start reading data until this string is found */
			continue;

		fields_num = openvpn_strsplit (buffer,
				fields, STATIC_ARRAY_SIZE (fields));
		if (fields_num < 4)
			continue;

		if (collect_user_count)
			/* If so, sum all users, ignore the individuals*/
		{
			sum_users += 1;
		}
		if (collect_individual_users)
		{
			if (new_naming_schema)
			{
				iostats_submit (name,               /* vpn instance */
						fields[0],          /* "Common Name" */
						atoll (fields[2]),  /* "Bytes Received" */
						atoll (fields[3])); /* "Bytes Sent" */
			}
			else
			{
				iostats_submit (fields[0],          /* "Common Name" */
						NULL,               /* unused when in multimode */
						atoll (fields[2]),  /* "Bytes Received" */
						atoll (fields[3])); /* "Bytes Sent" */
			}
		}
	}

	if (ferror (fh))
		return (0);

	if (collect_user_count)
		numusers_submit(name, name, sum_users);

	return (1);
} /* int multi1_read */
コード例 #13
0
ファイル: openvpn.c プロジェクト: brd/collectd
static int single_read (const char *name, FILE *fh)
{
	char buffer[1024];
	char *fields[4];
	const int max_fields = STATIC_ARRAY_SIZE (fields);
	int  fields_num, read = 0;

	derive_t link_rx, link_tx;
	derive_t tun_rx, tun_tx;
	derive_t pre_compress, post_compress;
	derive_t pre_decompress, post_decompress;
	derive_t overhead_rx, overhead_tx;

	link_rx = 0;
	link_tx = 0;
	tun_rx = 0;
	tun_tx = 0;
	pre_compress = 0;
	post_compress = 0;
	pre_decompress = 0;
	post_decompress = 0;

	while (fgets (buffer, sizeof (buffer), fh) != NULL)
	{
		fields_num = openvpn_strsplit (buffer, fields, max_fields);

		/* status file is generated by openvpn/sig.c:print_status()
		 * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/sig.c
		 *
		 * The line we're expecting has 2 fields. We ignore all lines
		 *  with more or less fields.
		 */
		if (fields_num != 2)
		{
			continue;
		}

		if (strcmp (fields[0], "TUN/TAP read bytes") == 0)
		{
			/* read from the system and sent over the tunnel */
			tun_tx = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "TUN/TAP write bytes") == 0)
		{
			/* read from the tunnel and written in the system */
			tun_rx = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "TCP/UDP read bytes") == 0)
		{
			link_rx = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "TCP/UDP write bytes") == 0)
		{
			link_tx = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "pre-compress bytes") == 0)
		{
			pre_compress = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "post-compress bytes") == 0)
		{
			post_compress = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "pre-decompress bytes") == 0)
		{
			pre_decompress = atoll (fields[1]);
		}
		else if (strcmp (fields[0], "post-decompress bytes") == 0)
		{
			post_decompress = atoll (fields[1]);
		}
	}

	iostats_submit (name, "traffic", link_rx, link_tx);

	/* we need to force this order to avoid negative values with these unsigned */
	overhead_rx = (((link_rx - pre_decompress) + post_decompress) - tun_rx);
	overhead_tx = (((link_tx - post_compress) + pre_compress) - tun_tx);

	iostats_submit (name, "overhead", overhead_rx, overhead_tx);

	if (collect_compression)
	{
		compression_submit (name, "data_in", post_decompress, pre_decompress);
		compression_submit (name, "data_out", pre_compress, post_compress);
	}

	read = 1;

	return (read);
} /* int single_read */
コード例 #14
0
ファイル: memory.c プロジェクト: BrandonArp/collectd
static int memory_read_internal(value_list_t *vl) {
#if HAVE_HOST_STATISTICS
  kern_return_t status;
  vm_statistics_data_t vm_data;
  mach_msg_type_number_t vm_data_len;

  gauge_t wired;
  gauge_t active;
  gauge_t inactive;
  gauge_t free;

  if (!port_host || !pagesize)
    return -1;

  vm_data_len = sizeof(vm_data) / sizeof(natural_t);
  if ((status = host_statistics(port_host, HOST_VM_INFO, (host_info_t)&vm_data,
                                &vm_data_len)) != KERN_SUCCESS) {
    ERROR("memory-plugin: host_statistics failed and returned the value %i",
          (int)status);
    return -1;
  }

  /*
   * From <http://docs.info.apple.com/article.html?artnum=107918>:
   *
   * Wired memory
   *   This information can't be cached to disk, so it must stay in RAM.
   *   The amount depends on what applications you are using.
   *
   * Active memory
   *   This information is currently in RAM and actively being used.
   *
   * Inactive memory
   *   This information is no longer being used and has been cached to
   *   disk, but it will remain in RAM until another application needs
   *   the space. Leaving this information in RAM is to your advantage if
   *   you (or a client of your computer) come back to it later.
   *
   * Free memory
   *   This memory is not being used.
   */

  wired = (gauge_t)(((uint64_t)vm_data.wire_count) * ((uint64_t)pagesize));
  active = (gauge_t)(((uint64_t)vm_data.active_count) * ((uint64_t)pagesize));
  inactive =
      (gauge_t)(((uint64_t)vm_data.inactive_count) * ((uint64_t)pagesize));
  free = (gauge_t)(((uint64_t)vm_data.free_count) * ((uint64_t)pagesize));

  MEMORY_SUBMIT("wired", wired, "active", active, "inactive", inactive, "free",
                free);
/* #endif HAVE_HOST_STATISTICS */

#elif HAVE_SYSCTLBYNAME
  /*
   * vm.stats.vm.v_page_size: 4096
   * vm.stats.vm.v_page_count: 246178
   * vm.stats.vm.v_free_count: 28760
   * vm.stats.vm.v_wire_count: 37526
   * vm.stats.vm.v_active_count: 55239
   * vm.stats.vm.v_inactive_count: 113730
   * vm.stats.vm.v_cache_count: 10809
   */
  const char *sysctl_keys[8] = {
      "vm.stats.vm.v_page_size",    "vm.stats.vm.v_page_count",
      "vm.stats.vm.v_free_count",   "vm.stats.vm.v_wire_count",
      "vm.stats.vm.v_active_count", "vm.stats.vm.v_inactive_count",
      "vm.stats.vm.v_cache_count",  NULL};
  double sysctl_vals[8];

  for (int i = 0; sysctl_keys[i] != NULL; i++) {
    int value;
    size_t value_len = sizeof(value);

    if (sysctlbyname(sysctl_keys[i], (void *)&value, &value_len, NULL, 0) ==
        0) {
      sysctl_vals[i] = value;
      DEBUG("memory plugin: %26s: %g", sysctl_keys[i], sysctl_vals[i]);
    } else {
      sysctl_vals[i] = NAN;
    }
  } /* for (sysctl_keys) */

  /* multiply all all page counts with the pagesize */
  for (int i = 1; sysctl_keys[i] != NULL; i++)
    if (!isnan(sysctl_vals[i]))
      sysctl_vals[i] *= sysctl_vals[0];

  MEMORY_SUBMIT("free", (gauge_t)sysctl_vals[2], "wired",
                (gauge_t)sysctl_vals[3], "active", (gauge_t)sysctl_vals[4],
                "inactive", (gauge_t)sysctl_vals[5], "cache",
                (gauge_t)sysctl_vals[6]);
/* #endif HAVE_SYSCTLBYNAME */

#elif KERNEL_LINUX
  FILE *fh;
  char buffer[1024];

  char *fields[8];
  int numfields;

  bool detailed_slab_info = false;

  gauge_t mem_total = 0;
  gauge_t mem_used = 0;
  gauge_t mem_buffered = 0;
  gauge_t mem_cached = 0;
  gauge_t mem_free = 0;
  gauge_t mem_slab_total = 0;
  gauge_t mem_slab_reclaimable = 0;
  gauge_t mem_slab_unreclaimable = 0;

  if ((fh = fopen("/proc/meminfo", "r")) == NULL) {
    WARNING("memory: fopen: %s", STRERRNO);
    return -1;
  }

  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
    gauge_t *val = NULL;

    if (strncasecmp(buffer, "MemTotal:", 9) == 0)
      val = &mem_total;
    else if (strncasecmp(buffer, "MemFree:", 8) == 0)
      val = &mem_free;
    else if (strncasecmp(buffer, "Buffers:", 8) == 0)
      val = &mem_buffered;
    else if (strncasecmp(buffer, "Cached:", 7) == 0)
      val = &mem_cached;
    else if (strncasecmp(buffer, "Slab:", 5) == 0)
      val = &mem_slab_total;
    else if (strncasecmp(buffer, "SReclaimable:", 13) == 0) {
      val = &mem_slab_reclaimable;
      detailed_slab_info = true;
    } else if (strncasecmp(buffer, "SUnreclaim:", 11) == 0) {
      val = &mem_slab_unreclaimable;
      detailed_slab_info = true;
    } else
      continue;

    numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
    if (numfields < 2)
      continue;

    *val = 1024.0 * atof(fields[1]);
  }

  if (fclose(fh)) {
    WARNING("memory: fclose: %s", STRERRNO);
  }

  if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total))
    return -1;

  mem_used =
      mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total);

  /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19
   * They sum up to the value of Slab, which is available on older & newer
   * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab
   * if not. */
  if (detailed_slab_info)
    MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached",
                  mem_cached, "free", mem_free, "slab_unrecl",
                  mem_slab_unreclaimable, "slab_recl", mem_slab_reclaimable);
  else
    MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached",
                  mem_cached, "free", mem_free, "slab", mem_slab_total);
/* #endif KERNEL_LINUX */

#elif HAVE_LIBKSTAT
  /* Most of the additions here were taken as-is from the k9toolkit from
   * Brendan Gregg and are subject to change I guess */
  long long mem_used;
  long long mem_free;
  long long mem_lock;
  long long mem_kern;
  long long mem_unus;
  long long arcsize;

  long long pp_kernel;
  long long physmem;
  long long availrmem;

  if (ksp == NULL)
    return -1;
  if (ksz == NULL)
    return -1;

  mem_used = get_kstat_value(ksp, "pagestotal");
  mem_free = get_kstat_value(ksp, "pagesfree");
  mem_lock = get_kstat_value(ksp, "pageslocked");
  arcsize = get_kstat_value(ksz, "size");
  pp_kernel = get_kstat_value(ksp, "pp_kernel");
  physmem = get_kstat_value(ksp, "physmem");
  availrmem = get_kstat_value(ksp, "availrmem");

  mem_kern = 0;
  mem_unus = 0;

  if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) {
    WARNING("memory plugin: one of used, free or locked is negative.");
    return -1;
  }

  mem_unus = physmem - mem_used;

  if (mem_used < (mem_free + mem_lock)) {
    /* source: http://wesunsolve.net/bugid/id/4909199
     * this seems to happen when swap space is small, e.g. 2G on a 32G system
     * we will make some assumptions here
     * educated solaris internals help welcome here */
    DEBUG("memory plugin: pages total is smaller than \"free\" "
          "+ \"locked\". This is probably due to small "
          "swap space");
    mem_free = availrmem;
    mem_used = 0;
  } else {
    mem_used -= mem_free + mem_lock;
  }

  /* mem_kern is accounted for in mem_lock */
  if (pp_kernel < mem_lock) {
    mem_kern = pp_kernel;
    mem_lock -= pp_kernel;
  } else {
    mem_kern = mem_lock;
    mem_lock = 0;
  }

  mem_used *= pagesize; /* If this overflows you have some serious */
  mem_free *= pagesize; /* memory.. Why not call me up and give me */
  mem_lock *= pagesize; /* some? ;) */
  mem_kern *= pagesize; /* it's 2011 RAM is cheap */
  mem_unus *= pagesize;
  mem_kern -= arcsize;

  MEMORY_SUBMIT("used", (gauge_t)mem_used, "free", (gauge_t)mem_free, "locked",
                (gauge_t)mem_lock, "kernel", (gauge_t)mem_kern, "arc",
                (gauge_t)arcsize, "unusable", (gauge_t)mem_unus);
/* #endif HAVE_LIBKSTAT */

#elif HAVE_SYSCTL
  int mib[] = {CTL_VM, VM_METER};
  struct vmtotal vmtotal = {0};
  gauge_t mem_active;
  gauge_t mem_inactive;
  gauge_t mem_free;
  size_t size;

  size = sizeof(vmtotal);

  if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) {
    WARNING("memory plugin: sysctl failed: %s", STRERRNO);
    return -1;
  }

  assert(pagesize > 0);
  mem_active = (gauge_t)(vmtotal.t_arm * pagesize);
  mem_inactive = (gauge_t)((vmtotal.t_rm - vmtotal.t_arm) * pagesize);
  mem_free = (gauge_t)(vmtotal.t_free * pagesize);

  MEMORY_SUBMIT("active", mem_active, "inactive", mem_inactive, "free",
                mem_free);
/* #endif HAVE_SYSCTL */

#elif HAVE_LIBSTATGRAB
  sg_mem_stats *ios;

  ios = sg_get_mem_stats();
  if (ios == NULL)
    return -1;

  MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache,
                "free", (gauge_t)ios->free);
/* #endif HAVE_LIBSTATGRAB */

#elif HAVE_PERFSTAT
  perfstat_memory_total_t pmemory = {0};

  if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) {
    WARNING("memory plugin: perfstat_memory_total failed: %s", STRERRNO);
    return -1;
  }

  /* Unfortunately, the AIX documentation is not very clear on how these
   * numbers relate to one another. The only thing is states explcitly
   * is:
   *   real_total = real_process + real_free + numperm + real_system
   *
   * Another segmentation, which would be closer to the numbers reported
   * by the "svmon" utility, would be:
   *   real_total = real_free + real_inuse
   *   real_inuse = "active" + real_pinned + numperm
   */
  MEMORY_SUBMIT("free", (gauge_t)(pmemory.real_free * pagesize), "cached",
                (gauge_t)(pmemory.numperm * pagesize), "system",
                (gauge_t)(pmemory.real_system * pagesize), "user",
                (gauge_t)(pmemory.real_process * pagesize));
#endif /* HAVE_PERFSTAT */

  return 0;
} /* }}} int memory_read_internal */
コード例 #15
0
ファイル: cpu.c プロジェクト: 01BTC10/collectd
static int init (void)
{
#if PROCESSOR_CPU_LOAD_INFO
	kern_return_t status;

	port_host = mach_host_self ();

	status = host_processors (port_host, &cpu_list, &cpu_list_len);
	if (status == KERN_INVALID_ARGUMENT)
	{
		ERROR ("cpu plugin: Don't have a privileged host control port. "
				"The most common cause for this problem is "
				"that collectd is running without root "
				"privileges, which are required to read CPU "
				"load information. "
				"<https://collectd.org/bugs/22>");
		cpu_list_len = 0;
		return (-1);
	}
	if (status != KERN_SUCCESS)
	{
		ERROR ("cpu plugin: host_processors() failed with status %d.", (int) status);
		cpu_list_len = 0;
		return (-1);
	}

	INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s");
/* #endif PROCESSOR_CPU_LOAD_INFO */

#elif defined(HAVE_LIBKSTAT)
	kstat_t *ksp_chain;

	numcpu = 0;

	if (kc == NULL)
		return (-1);

	/* Solaris doesn't count linear.. *sigh* */
	for (numcpu = 0, ksp_chain = kc->kc_chain;
			(numcpu < MAX_NUMCPU) && (ksp_chain != NULL);
			ksp_chain = ksp_chain->ks_next)
		if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0)
			ksp[numcpu++] = ksp_chain;
/* #endif HAVE_LIBKSTAT */

#elif CAN_USE_SYSCTL
	size_t numcpu_size;
	int mib[2] = {CTL_HW, HW_NCPU};
	int status;

	numcpu = 0;
	numcpu_size = sizeof (numcpu);

	status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
			&numcpu, &numcpu_size, NULL, 0);
	if (status == -1)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: sysctl: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}
/* #endif CAN_USE_SYSCTL */

#elif defined (HAVE_SYSCTLBYNAME)
	size_t numcpu_size;

	numcpu_size = sizeof (numcpu);

	if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

#ifdef HAVE_SYSCTL_KERN_CP_TIMES
	numcpu_size = sizeof (maxcpu);

	if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}
#else
	if (numcpu != 1)
		NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu);
#endif
/* #endif HAVE_SYSCTLBYNAME */

#elif defined(HAVE_LIBSTATGRAB)
	/* nothing to initialize */
/* #endif HAVE_LIBSTATGRAB */

#elif defined(HAVE_PERFSTAT)
	/* nothing to initialize */
#endif /* HAVE_PERFSTAT */

	return (0);
} /* int init */
コード例 #16
0
ファイル: madwifi.c プロジェクト: fcagsaway/collectd
static inline int item_summed(int i)
{
	assert (i >= 0);
	assert (i < ((STATIC_ARRAY_SIZE (misc_items) + 1) * 32));
	return misc_items[i / 32] & FLAG (i);
}
コード例 #17
0
ファイル: tcpconns.c プロジェクト: ajdiaz/collectd
/* Returns zero on success, less than zero on socket error and greater than
 * zero on other errors. */
static int conn_read_netlink(void) {
#if HAVE_STRUCT_LINUX_INET_DIAG_REQ
  int fd;
  struct inet_diag_msg *r;
  char buf[8192];

  /* If this fails, it's likely a permission problem. We'll fall back to
   * reading this information from files below. */
  fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG);
  if (fd < 0) {
    ERROR("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, "
          "NETLINK_INET_DIAG) failed: %s",
          sstrerror(errno, buf, sizeof(buf)));
    return (-1);
  }

  struct sockaddr_nl nladdr = {.nl_family = AF_NETLINK};

  struct nlreq req = {
      .nlh.nlmsg_len = sizeof(req),
      .nlh.nlmsg_type = TCPDIAG_GETSOCK,
      /* NLM_F_ROOT: return the complete table instead of a single entry.
       * NLM_F_MATCH: return all entries matching criteria (not implemented)
       * NLM_F_REQUEST: must be set on all request messages */
      .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
      .nlh.nlmsg_pid = 0,
      /* The sequence_number is used to track our messages. Since netlink is not
       * reliable, we don't want to end up with a corrupt or incomplete old
       * message in case the system is/was out of memory. */
      .nlh.nlmsg_seq = ++sequence_number,
      .r.idiag_family = AF_INET,
      .r.idiag_states = 0xfff,
      .r.idiag_ext = 0};

  struct iovec iov = {.iov_base = &req, .iov_len = sizeof(req)};

  struct msghdr msg = {.msg_name = (void *)&nladdr,
                       .msg_namelen = sizeof(nladdr),
                       .msg_iov = &iov,
                       .msg_iovlen = 1};

  if (sendmsg(fd, &msg, 0) < 0) {
    ERROR("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s",
          sstrerror(errno, buf, sizeof(buf)));
    close(fd);
    return (-1);
  }

  iov.iov_base = buf;
  iov.iov_len = sizeof(buf);

  while (1) {
    int status;
    struct nlmsghdr *h;

    memset(&msg, 0, sizeof(msg));
    msg.msg_name = (void *)&nladdr;
    msg.msg_namelen = sizeof(nladdr);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    status = recvmsg(fd, (void *)&msg, /* flags = */ 0);
    if (status < 0) {
      if ((errno == EINTR) || (errno == EAGAIN))
        continue;

      ERROR("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s",
            sstrerror(errno, buf, sizeof(buf)));
      close(fd);
      return (-1);
    } else if (status == 0) {
      close(fd);
      DEBUG("tcpconns plugin: conn_read_netlink: Unexpected zero-sized "
            "reply from netlink socket.");
      return (0);
    }

    h = (struct nlmsghdr *)buf;
    while (NLMSG_OK(h, status)) {
      if (h->nlmsg_seq != sequence_number) {
        h = NLMSG_NEXT(h, status);
        continue;
      }

      if (h->nlmsg_type == NLMSG_DONE) {
        close(fd);
        return (0);
      } else if (h->nlmsg_type == NLMSG_ERROR) {
        struct nlmsgerr *msg_error;

        msg_error = NLMSG_DATA(h);
        WARNING("tcpconns plugin: conn_read_netlink: Received error %i.",
                msg_error->error);

        close(fd);
        return (1);
      }

      r = NLMSG_DATA(h);

      /* This code does not (need to) distinguish between IPv4 and IPv6. */
      conn_handle_ports(ntohs(r->id.idiag_sport), ntohs(r->id.idiag_dport),
                        r->idiag_state);

      h = NLMSG_NEXT(h, status);
    } /* while (NLMSG_OK) */
  }   /* while (1) */

  /* Not reached because the while() loop above handles the exit condition. */
  return (0);
#else
  return (1);
#endif /* HAVE_STRUCT_LINUX_INET_DIAG_REQ */
} /* int conn_read_netlink */

static int conn_handle_line(char *buffer) {
  char *fields[32];
  int fields_len;

  char *endptr;

  char *port_local_str;
  char *port_remote_str;
  uint16_t port_local;
  uint16_t port_remote;

  uint8_t state;

  int buffer_len = strlen(buffer);

  while ((buffer_len > 0) && (buffer[buffer_len - 1] < 32))
    buffer[--buffer_len] = '\0';
  if (buffer_len <= 0)
    return (-1);

  fields_len = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
  if (fields_len < 12) {
    DEBUG("tcpconns plugin: Got %i fields, expected at least 12.", fields_len);
    return (-1);
  }

  port_local_str = strchr(fields[1], ':');
  port_remote_str = strchr(fields[2], ':');

  if ((port_local_str == NULL) || (port_remote_str == NULL))
    return (-1);
  port_local_str++;
  port_remote_str++;
  if ((*port_local_str == '\0') || (*port_remote_str == '\0'))
    return (-1);

  endptr = NULL;
  port_local = (uint16_t)strtol(port_local_str, &endptr, 16);
  if ((endptr == NULL) || (*endptr != '\0'))
    return (-1);

  endptr = NULL;
  port_remote = (uint16_t)strtol(port_remote_str, &endptr, 16);
  if ((endptr == NULL) || (*endptr != '\0'))
    return (-1);

  endptr = NULL;
  state = (uint8_t)strtol(fields[3], &endptr, 16);
  if ((endptr == NULL) || (*endptr != '\0'))
    return (-1);

  return (conn_handle_ports(port_local, port_remote, state));
} /* int conn_handle_line */

static int conn_read_file(const char *file) {
  FILE *fh;
  char buffer[1024];

  fh = fopen(file, "r");
  if (fh == NULL)
    return (-1);

  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
    conn_handle_line(buffer);
  } /* while (fgets) */

  fclose(fh);

  return (0);
} /* int conn_read_file */
/* #endif KERNEL_LINUX */

#elif HAVE_SYSCTLBYNAME
/* #endif HAVE_SYSCTLBYNAME */

#elif HAVE_LIBKVM_NLIST
#endif /* HAVE_LIBKVM_NLIST */

static int conn_config(const char *key, const char *value) {
  if (strcasecmp(key, "ListeningPorts") == 0) {
    if (IS_TRUE(value))
      port_collect_listening = 1;
    else
      port_collect_listening = 0;
  } else if ((strcasecmp(key, "LocalPort") == 0) ||
             (strcasecmp(key, "RemotePort") == 0)) {
    port_entry_t *pe;
    int port = atoi(value);

    if ((port < 1) || (port > 65535)) {
      ERROR("tcpconns plugin: Invalid port: %i", port);
      return (1);
    }

    pe = conn_get_port_entry((uint16_t)port, 1 /* create */);
    if (pe == NULL) {
      ERROR("tcpconns plugin: conn_get_port_entry failed.");
      return (1);
    }

    if (strcasecmp(key, "LocalPort") == 0)
      pe->flags |= PORT_COLLECT_LOCAL;
    else
      pe->flags |= PORT_COLLECT_REMOTE;
  } else if (strcasecmp(key, "AllPortsSummary") == 0) {
    if (IS_TRUE(value))
      port_collect_total = 1;
    else
      port_collect_total = 0;
  } else {
    return (-1);
  }

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

#if KERNEL_LINUX
static int conn_init(void) {
  if (port_collect_total == 0 && port_list_head == NULL)
    port_collect_listening = 1;

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

static int conn_read(void) {
  int status;

  conn_reset_port_entry();

  if (linux_source == SRC_NETLINK) {
    status = conn_read_netlink();
  } else if (linux_source == SRC_PROC) {
    int errors_num = 0;

    if (conn_read_file("/proc/net/tcp") != 0)
      errors_num++;
    if (conn_read_file("/proc/net/tcp6") != 0)
      errors_num++;

    if (errors_num < 2)
      status = 0;
    else
      status = ENOENT;
  } else /* if (linux_source == SRC_DUNNO) */
  {
    /* Try to use netlink for getting this data, it is _much_ faster on systems
     * with a large amount of connections. */
    status = conn_read_netlink();
    if (status == 0) {
      INFO("tcpconns plugin: Reading from netlink succeeded. "
           "Will use the netlink method from now on.");
      linux_source = SRC_NETLINK;
    } else {
      INFO("tcpconns plugin: Reading from netlink failed. "
           "Will read from /proc from now on.");
      linux_source = SRC_PROC;

      /* return success here to avoid the "plugin failed" message. */
      return (0);
    }
  }

  if (status == 0)
    conn_submit_all();
  else
    return (status);

  return (0);
} /* int conn_read */
コード例 #18
0
ファイル: openvpn.c プロジェクト: frankhereford/collectd
static _Bool new_naming_schema = 0;
static _Bool collect_compression = 1;
static _Bool collect_user_count  = 0;
static _Bool collect_individual_users  = 1;

static const char *config_keys[] =
{
	"StatusFile",
	"Compression", /* old, deprecated name */
	"ImprovedNamingSchema",
	"CollectCompression",
	"CollectUserCount",
	"CollectIndividualUsers"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);


/* Helper function
 * copy-n-pasted from common.c - changed delim to ","  */
static int openvpn_strsplit (char *string, char **fields, size_t size)
{
	size_t i;
	char *ptr;
	char *saveptr;

	i = 0;
	ptr = string;
	saveptr = NULL;
	while ((fields[i] = strtok_r (ptr, ",", &saveptr)) != NULL)
	{
コード例 #19
0
ファイル: exmp01.c プロジェクト: dch/riemann-c-client
int main(int argc, char **argv)
{
    riemann_message_t msg = RIEMANN_MSG_INIT;
    riemann_message_t *resp = NULL;
    size_t n_events = STATIC_ARRAY_SIZE(cpus);
    riemann_event_t *events[n_events]; /* using stack space */
    size_t n_attrs = STATIC_ARRAY_SIZE(attrs);

    int i;
    int error;
    riemann_client_t cli;

    if (argc != 3) {
        fprintf(stderr, "%s <IP> <PORT>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < n_events; i++) {
        events[i] = alloca(sizeof (riemann_event_t));
        riemann_event_init(events[i]);
        riemann_event_set_host(events[i], "gentoo-x86");
        riemann_event_set_service(events[i], cpus[i]);
        riemann_event_set_metric_f(events[i], 100); /* 100% idle */
        riemann_event_set_state(events[i], "ok");
        riemann_event_set_tags(events[i], tags, STATIC_ARRAY_SIZE(tags));
        riemann_event_set_attributes(events[i], attrs, STATIC_ARRAY_SIZE(attrs));
    }

    riemann_message_set_events(&msg, events, n_events);
    error = riemann_client_init(&cli);
    if (error) {
        fprintf(stderr, "Can't initialize client: strerror(%s)\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    error = riemann_client_connect(&cli, TCP, argv[1], atoi(argv[2])); /* functions that returns ints returns 0 on success */
    if (error) {
        fprintf(stderr, "Can't connectd: strerror(%s) gai_strerrror(%s)\n", strerror(errno), gai_strerror(error));
        exit(EXIT_FAILURE);
    }

    error = riemann_client_send_message(&cli, &msg, 0, NULL);
    if (error) {
        fprintf(stderr, "Can't send message: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    resp = riemann_client_recv_message(&cli, 0, NULL); /* functions that returns pointers rertuns NULL on failure */
    assert(resp);

    if (!resp->ok) {
        fprintf(stderr, "Message error %s\n", resp->error);
        exit(EXIT_FAILURE);
    } else {
        puts("Sucess");
    }

    for (i = 0; i < n_events; i++) /* freeing events fields */
        riemann_event_free(events[i]); /* Since events are on
                                                * stack the may not be
                                                * freed. */

    riemann_message_free(resp); /* responses should be freed */
    riemann_client_free(&cli);

    return 0;
}
コード例 #20
0
ファイル: cpu.c プロジェクト: JaseFace/collectd
static int init (void)
{
#if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
	kern_return_t status;

	port_host = mach_host_self ();

	/* FIXME: Free `cpu_list' if it's not NULL */
	if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS)
	{
		ERROR ("cpu plugin: host_processors returned %i", (int) status);
		cpu_list_len = 0;
		return (-1);
	}

	DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors");
	INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s");

	cpu_temp_retry_max = 86400 / CDTIME_T_TO_TIME_T (plugin_get_interval ());
/* #endif PROCESSOR_CPU_LOAD_INFO */

#elif defined(HAVE_LIBKSTAT)
	kstat_t *ksp_chain;

	numcpu = 0;

	if (kc == NULL)
		return (-1);

	/* Solaris doesn't count linear.. *sigh* */
	for (numcpu = 0, ksp_chain = kc->kc_chain;
			(numcpu < MAX_NUMCPU) && (ksp_chain != NULL);
			ksp_chain = ksp_chain->ks_next)
		if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0)
			ksp[numcpu++] = ksp_chain;
/* #endif HAVE_LIBKSTAT */

#elif CAN_USE_SYSCTL
	size_t numcpu_size;
	int mib[2] = {CTL_HW, HW_NCPU};
	int status;

	numcpu = 0;
	numcpu_size = sizeof (numcpu);

	status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
			&numcpu, &numcpu_size, NULL, 0);
	if (status == -1)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: sysctl: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}
/* #endif CAN_USE_SYSCTL */

#elif defined (HAVE_SYSCTLBYNAME)
	size_t numcpu_size;

	numcpu_size = sizeof (numcpu);

	if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

#ifdef HAVE_SYSCTL_KERN_CP_TIMES
	numcpu_size = sizeof (maxcpu);

	if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}
#else
	if (numcpu != 1)
		NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu);
#endif
/* #endif HAVE_SYSCTLBYNAME */

#elif defined(HAVE_LIBSTATGRAB)
	/* nothing to initialize */
/* #endif HAVE_LIBSTATGRAB */

#elif defined(HAVE_PERFSTAT)
	/* nothing to initialize */
#endif /* HAVE_PERFSTAT */

	return (0);
} /* int init */
コード例 #21
0
ファイル: powerdns.c プロジェクト: superfeedr/collectd
const char* const default_server_fields[] = /* {{{ */
{
  "latency"
  "packetcache-hit",
  "packetcache-miss",
  "packetcache-size",
  "query-cache-hit",
  "query-cache-miss",
  "recursing-answers",
  "recursing-questions",
  "tcp-answers",
  "tcp-queries",
  "udp-answers",
  "udp-queries",
}; /* }}} */
int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields);

statname_lookup_t lookup_table[] = /* {{{ */
{
  /*********************
   * Server statistics *
   *********************/
  /* Questions */
  {"recursing-questions",    "dns_question", "recurse"},
  {"tcp-queries",            "dns_question", "tcp"},
  {"udp-queries",            "dns_question", "udp"},

  /* Answers */
  {"recursing-answers",      "dns_answer",   "recurse"},
  {"tcp-answers",            "dns_answer",   "tcp"},
  {"udp-answers",            "dns_answer",   "udp"},
コード例 #22
0
ファイル: cpu.c プロジェクト: JaseFace/collectd
static int cpu_read (void)
{
#if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
	int cpu;

	kern_return_t status;

#if PROCESSOR_CPU_LOAD_INFO
	processor_cpu_load_info_data_t cpu_info;
	mach_msg_type_number_t	       cpu_info_len;
#endif
#if PROCESSOR_TEMPERATURE
	processor_info_data_t	       cpu_temp;
	mach_msg_type_number_t	       cpu_temp_len;
#endif

	host_t cpu_host;

	for (cpu = 0; cpu < cpu_list_len; cpu++)
	{
#if PROCESSOR_CPU_LOAD_INFO
		derive_t derives[CPU_SUBMIT_MAX] = {
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
		};
		memset(derives, -1, sizeof(derives));
		cpu_host = 0;
		cpu_info_len = PROCESSOR_BASIC_INFO_COUNT;

		if ((status = processor_info (cpu_list[cpu],
						PROCESSOR_CPU_LOAD_INFO, &cpu_host,
						(processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS)
		{
			ERROR ("cpu plugin: processor_info failed with status %i", (int) status);
			continue;
		}

		if (cpu_info_len < CPU_STATE_MAX)
		{
			ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len);
			continue;
		}

		derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER];
		derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE];
		derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM];
		derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE];
		submit (cpu, derives);

#endif /* PROCESSOR_CPU_LOAD_INFO */
#if PROCESSOR_TEMPERATURE
		/*
		 * Not all Apple computers do have this ability. To minimize
		 * the messages sent to the syslog we do an exponential
		 * stepback if `processor_info' fails. We still try ~once a day
		 * though..
		 */
		if (cpu_temp_retry_counter > 0)
		{
			cpu_temp_retry_counter--;
			continue;
		}

		cpu_temp_len = PROCESSOR_INFO_MAX;

		status = processor_info (cpu_list[cpu],
				PROCESSOR_TEMPERATURE,
				&cpu_host,
				cpu_temp, &cpu_temp_len);
		if (status != KERN_SUCCESS)
		{
			ERROR ("cpu plugin: processor_info failed: %s",
					mach_error_string (status));

			cpu_temp_retry_counter = cpu_temp_retry_step;
			cpu_temp_retry_step *= 2;
			if (cpu_temp_retry_step > cpu_temp_retry_max)
				cpu_temp_retry_step = cpu_temp_retry_max;

			continue;
		}

		if (cpu_temp_len != 1)
		{
			DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?",
					(int) cpu_temp_len);
			continue;
		}

		cpu_temp_retry_counter = 0;
		cpu_temp_retry_step    = 1;
#endif /* PROCESSOR_TEMPERATURE */
	}
	submit_flush ();
/* #endif PROCESSOR_CPU_LOAD_INFO */

#elif defined(KERNEL_LINUX)
	int cpu;
	FILE *fh;
	char buf[1024];

	char *fields[9];
	int numfields;

	if ((fh = fopen ("/proc/stat", "r")) == NULL)
	{
		char errbuf[1024];
		ERROR ("cpu plugin: fopen (/proc/stat) failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	while (fgets (buf, 1024, fh) != NULL)
	{
		derive_t derives[CPU_SUBMIT_MAX] = {
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
		};

		if (strncmp (buf, "cpu", 3))
			continue;
		if ((buf[3] < '0') || (buf[3] > '9'))
			continue;

		numfields = strsplit (buf, fields, 9);
		if (numfields < 5)
			continue;

		cpu = atoi (fields[0] + 3);
		derives[CPU_SUBMIT_USER] = atoll(fields[1]);
		derives[CPU_SUBMIT_NICE] = atoll(fields[2]);
		derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]);
		derives[CPU_SUBMIT_IDLE] = atoll(fields[4]);

		if (numfields >= 8)
		{
			derives[CPU_SUBMIT_WAIT] = atoll(fields[5]);
			derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]);
			derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]);

			if (numfields >= 9)
				derives[CPU_SUBMIT_STEAL] = atoll(fields[8]);
		}
		submit(cpu, derives);
	}
	submit_flush();

	fclose (fh);
/* #endif defined(KERNEL_LINUX) */

#elif defined(HAVE_LIBKSTAT)
	int cpu;
	static cpu_stat_t cs;

	if (kc == NULL)
		return (-1);

	for (cpu = 0; cpu < numcpu; cpu++)
	{
		derive_t derives[CPU_SUBMIT_MAX] = {
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
		};

		if (kstat_read (kc, ksp[cpu], &cs) == -1)
			continue; /* error message? */

		memset(derives, -1, sizeof(derives));
		derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE];
		derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER];
		derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL];
		derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT];
		submit (ksp[cpu]->ks_instance, derives);
	}
	submit_flush ();
/* #endif defined(HAVE_LIBKSTAT) */

#elif CAN_USE_SYSCTL
	uint64_t cpuinfo[numcpu][CPUSTATES];
	size_t cpuinfo_size;
	int status;
	int i;

	if (numcpu < 1)
	{
		ERROR ("cpu plugin: Could not determine number of "
				"installed CPUs using sysctl(3).");
		return (-1);
	}

	memset (cpuinfo, 0, sizeof (cpuinfo));

#if defined(KERN_CPTIME2)
	if (numcpu > 1) {
		for (i = 0; i < numcpu; i++) {
			int mib[] = {CTL_KERN, KERN_CPTIME2, i};

			cpuinfo_size = sizeof (cpuinfo[0]);

			status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
					cpuinfo[i], &cpuinfo_size, NULL, 0);
			if (status == -1) {
				char errbuf[1024];
				ERROR ("cpu plugin: sysctl failed: %s.",
						sstrerror (errno, errbuf, sizeof (errbuf)));
				return (-1);
			}
		}
	}
	else
#endif /* defined(KERN_CPTIME2) */
	{
		int mib[] = {CTL_KERN, KERN_CPTIME};
		long cpuinfo_tmp[CPUSTATES];

		cpuinfo_size = sizeof(cpuinfo_tmp);

		status = sysctl (mib, STATIC_ARRAY_SIZE (mib),
					&cpuinfo_tmp, &cpuinfo_size, NULL, 0);
		if (status == -1)
		{
			char errbuf[1024];
			ERROR ("cpu plugin: sysctl failed: %s.",
					sstrerror (errno, errbuf, sizeof (errbuf)));
			return (-1);
		}

		for(i = 0; i < CPUSTATES; i++) {
			cpuinfo[0][i] = cpuinfo_tmp[i];
		}
	}

	for (i = 0; i < numcpu; i++) {
		derive_t derives[CPU_SUBMIT_MAX] = {
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
		};

		derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER];
		derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE];
		derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS];
		derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE];
		derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR];
		submit(i, derives);
	}
	submit_flush();
/* #endif CAN_USE_SYSCTL */
#elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES)
	long cpuinfo[maxcpu][CPUSTATES];
	size_t cpuinfo_size;
	int i;

	memset (cpuinfo, 0, sizeof (cpuinfo));

	cpuinfo_size = sizeof (cpuinfo);
	if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0)
	{
		char errbuf[1024];
		ERROR ("cpu plugin: sysctlbyname failed: %s.",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	for (i = 0; i < numcpu; i++) {
		derive_t derives[CPU_SUBMIT_MAX] = {
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
		};

		derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER];
		derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE];
		derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS];
		derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE];
		derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR];
		submit(i, derives);
	}
	submit_flush();

/* #endif HAVE_SYSCTL_KERN_CP_TIMES */
#elif defined(HAVE_SYSCTLBYNAME)
	long cpuinfo[CPUSTATES];
	size_t cpuinfo_size;
	derive_t derives[CPU_SUBMIT_MAX] = {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
	};

	cpuinfo_size = sizeof (cpuinfo);

	if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0)
	{
		char errbuf[1024];
		ERROR ("cpu plugin: sysctlbyname failed: %s.",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER];
	derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS];
	derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE];
	derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE];
	derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR];
	submit(0, derives);
	submit_flush();

/* #endif HAVE_SYSCTLBYNAME */

#elif defined(HAVE_LIBSTATGRAB)
	sg_cpu_stats *cs;
	derive_t derives[CPU_SUBMIT_MAX] = {
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
	};
	cs = sg_get_cpu_stats ();

	if (cs == NULL)
	{
		ERROR ("cpu plugin: sg_get_cpu_stats failed.");
		return (-1);
	}

	derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle;
	derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice;
	derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap;
	derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel;
	derives[CPU_SUBMIT_USER] = (derive_t) cs->user;
	derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait;
	submit(0, derives);
	submit_flush();
/* #endif HAVE_LIBSTATGRAB */

#elif defined(HAVE_PERFSTAT)
	perfstat_id_t id;
	int i, cpus;

	numcpu =  perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
	if(numcpu == -1)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: perfstat_cpu: %s",
			sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	if (pnumcpu != numcpu || perfcpu == NULL)
	{
		if (perfcpu != NULL)
			free(perfcpu);
		perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t));
	}
	pnumcpu = numcpu;

	id.name[0] = '\0';
	if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0)
	{
		char errbuf[1024];
		WARNING ("cpu plugin: perfstat_cpu: %s",
			sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	for (i = 0; i < cpus; i++)
	{
		derive_t derives[CPU_SUBMIT_MAX] = {
			-1, -1, -1, -1, -1, -1, -1, -1, -1, -1
		};
		derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle;
		derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys;
		derives[CPU_SUBMIT_USER] = perfcpu[i].user;
		derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait;
		submit(i, derives);
	}
	submit_flush();
#endif /* HAVE_PERFSTAT */

	return (0);
}
コード例 #23
0
ファイル: table.c プロジェクト: strizhechenko/collectd
static int tbl_result_dispatch (tbl_t *tbl, tbl_result_t *res,
		char **fields, size_t fields_num)
{
	value_list_t vl = VALUE_LIST_INIT;
	value_t values[res->values_num];

	size_t i;

	assert (NULL != res->ds);
	assert (res->values_num == res->ds->ds_num);

	for (i = 0; i < res->values_num; ++i) {
		char *value;

		assert (res->values[i] < fields_num);
		value = fields[res->values[i]];

		if (0 != parse_value (value, &values[i], res->ds->ds[i].type))
			return -1;
	}

	vl.values     = values;
	vl.values_len = STATIC_ARRAY_SIZE (values);

	sstrncpy (vl.host, hostname_g, sizeof (vl.host));
	sstrncpy (vl.plugin, "table", sizeof (vl.plugin));
	sstrncpy (vl.plugin_instance, tbl->instance, sizeof (vl.plugin_instance));
	sstrncpy (vl.type, res->type, sizeof (vl.type));

	if (0 == res->instances_num) {
		if (NULL != res->instance_prefix)
			sstrncpy (vl.type_instance, res->instance_prefix,
					sizeof (vl.type_instance));
	}
	else {
		char *instances[res->instances_num];
		char  instances_str[DATA_MAX_NAME_LEN];

		for (i = 0; i < res->instances_num; ++i) {
			assert (res->instances[i] < fields_num);
			instances[i] = fields[res->instances[i]];
		}

		strjoin (instances_str, sizeof (instances_str),
				instances, STATIC_ARRAY_SIZE (instances), "-");
		instances_str[sizeof (instances_str) - 1] = '\0';

		vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
		if (NULL == res->instance_prefix)
			strncpy (vl.type_instance, instances_str,
					sizeof (vl.type_instance));
		else
			snprintf (vl.type_instance, sizeof (vl.type_instance),
					"%s-%s", res->instance_prefix, instances_str);

		if ('\0' != vl.type_instance[sizeof (vl.type_instance) - 1]) {
			vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
			log_warn ("Truncated type instance: %s.", vl.type_instance);
		}
	}

	plugin_dispatch_values (&vl);
	return 0;
} /* tbl_result_dispatch */
コード例 #24
0
ファイル: hugepages.c プロジェクト: bzed/collectd
 *   Kim-Marie Jones <*****@*****.**>
 */

#include "collectd.h"
#include "common.h" /* auxiliary functions */
#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */

static const char g_plugin_name[] = "hugepages";
static const char g_cfg_rpt_numa[] = "ReportPerNodeHP";
static const char g_cfg_rpt_mm[] = "ReportRootHP";

static const char *g_config_keys[] = {
  g_cfg_rpt_numa,
  g_cfg_rpt_mm,
};
static size_t g_config_keys_num = STATIC_ARRAY_SIZE(g_config_keys);
static int g_flag_rpt_numa = 1;
static int g_flag_rpt_mm = 1;

struct entry_info {
  char *d_name;
  const char *node;
};

static int huge_config_callback(const char *key, const char *val)
{
  DEBUG("%s: HugePages config key='%s', val='%s'", g_plugin_name, key, val);

  if (strcasecmp(key, g_cfg_rpt_numa) == 0) {
    g_flag_rpt_numa = IS_TRUE(val);
    return 0;
コード例 #25
0
ファイル: battery.c プロジェクト: Civil/collectd
static int read_acpi_callback (char const *dir, /* {{{ */
		char const *power_supply,
		void *user_data)
{
	int *battery_index = user_data;

	gauge_t current = NAN;
	gauge_t voltage = NAN;
	gauge_t charge  = NAN;
	_Bool charging = 0;

	char const *plugin_instance;
	char filename[PATH_MAX];
	char buffer[1024];

	FILE *fh;

	ssnprintf (filename, sizeof (filename), "%s/%s/state", dir, power_supply);
	fh = fopen (filename, "r");
	if ((fh = fopen (filename, "r")) == NULL)
	{
		if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT))
			return (0);
		else
			return (errno);
	}

	/*
	 * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state
	 * [11:00] <@tokkee> present:                 yes
	 * [11:00] <@tokkee> capacity state:          ok
	 * [11:00] <@tokkee> charging state:          charging
	 * [11:00] <@tokkee> present rate:            1724 mA
	 * [11:00] <@tokkee> remaining capacity:      4136 mAh
	 * [11:00] <@tokkee> present voltage:         12428 mV
	 */
	while (fgets (buffer, sizeof (buffer), fh) != NULL)
	{
		char *fields[8];
		int numfields;

		numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
		if (numfields < 3)
			continue;

		if ((strcmp (fields[0], "charging") == 0)
				&& (strcmp (fields[1], "state:") == 0))
		{
			if (strcmp (fields[2], "charging") == 0)
				charging = 1;
			else
				charging = 0;
			continue;
		}

		/* FIXME: The unit of "present rate" depends on the battery.
		 * Modern batteries export watts, not amperes, i.e. it's not a
		 * current anymore. We should check if the fourth column
		 * contains "mA" and only use a current then. Otherwise, export
		 * a power. */
		if ((strcmp (fields[0], "present") == 0)
				&& (strcmp (fields[1], "rate:") == 0))
			strtogauge (fields[2], &current);
		else if ((strcmp (fields[0], "remaining") == 0)
				&& (strcmp (fields[1], "capacity:") == 0))
			strtogauge (fields[2], &charge);
		else if ((strcmp (fields[0], "present") == 0)
				&& (strcmp (fields[1], "voltage:") == 0))
			strtogauge (fields[2], &voltage);
	} /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */

	fclose (fh);

	if (!charging)
		current *= -1.0;

	/* FIXME: This is a dirty hack for backwards compatibility: The battery
	 * plugin, for a very long time, has had the plugin_instance
	 * hard-coded to "0". So, to keep backwards compatibility, we'll use
	 * "0" for the first battery we find and the power_supply name for all
	 * following. This should be reverted in a future major version. */
	plugin_instance = (*battery_index == 0) ? "0" : power_supply;
	(*battery_index)++;

	battery_submit (plugin_instance, "charge", charge / 1000.0);
	battery_submit (plugin_instance, "current", current / 1000.0);
	battery_submit (plugin_instance, "voltage", voltage / 1000.0);

	return 0;
} /* }}} int read_acpi_callback */
コード例 #26
0
ファイル: fscache.c プロジェクト: hasso/collectd
static void fscache_read_stats_file(FILE *fh) {
  char section[DATA_MAX_NAME_LEN];
  size_t section_len;

  char linebuffer[BUFSIZE];

  /*
   *  cat /proc/fs/fscache/stats
   *      FS-Cache statistics
   *      Cookies: idx=2 dat=0 spc=0
   *      Objects: alc=0 nal=0 avl=0 ded=0
   *      ChkAux : non=0 ok=0 upd=0 obs=0
   *      Pages  : mrk=0 unc=0
   *      Acquire: n=2 nul=0 noc=0 ok=2 nbf=0 oom=0
   *      Lookups: n=0 neg=0 pos=0 crt=0
   *      Updates: n=0 nul=0 run=0
   *      Relinqs: n=0 nul=0 wcr=0
   *      AttrChg: n=0 ok=0 nbf=0 oom=0 run=0
   *      Allocs : n=0 ok=0 wt=0 nbf=0
   *      Allocs : ops=0 owt=0
   *      Retrvls: n=0 ok=0 wt=0 nod=0 nbf=0 int=0 oom=0
   *      Retrvls: ops=0 owt=0
   *      Stores : n=0 ok=0 agn=0 nbf=0 oom=0
   *      Stores : ops=0 run=0
   *      Ops    : pend=0 run=0 enq=0
   *      Ops    : dfr=0 rel=0 gc=0
   */

  /* Read file line by line */
  while (fgets(linebuffer, sizeof(linebuffer), fh) != NULL) {
    char *lineptr;
    char *fields[32];
    int fields_num;

    /* Find the colon and replace it with a null byte */
    lineptr = strchr(linebuffer, ':');
    if (lineptr == NULL)
      continue;
    *lineptr = 0;
    lineptr++;

    /* Copy and clean up the section name */
    sstrncpy(section, linebuffer, sizeof(section));
    section_len = strlen(section);
    while ((section_len > 0) && isspace((int)section[section_len - 1])) {
      section_len--;
      section[section_len] = 0;
    }
    if (section_len == 0)
      continue;

    fields_num = strsplit(lineptr, fields, STATIC_ARRAY_SIZE(fields));
    if (fields_num <= 0)
      continue;

    for (int i = 0; i < fields_num; i++) {
      char *field_name;
      char *field_value_str;
      value_t field_value_cnt;
      int status;

      field_name = fields[i];
      assert(field_name != NULL);

      field_value_str = strchr(field_name, '=');
      if (field_value_str == NULL)
        continue;
      *field_value_str = 0;
      field_value_str++;

      status = parse_value(field_value_str, &field_value_cnt, DS_TYPE_DERIVE);
      if (status != 0)
        continue;

      fscache_submit(section, field_name, field_value_cnt);
    }
  } /* while (fgets) */
} /* void fscache_read_stats_file */
コード例 #27
0
ファイル: postgresql.c プロジェクト: BrianB2/collectd
	char *service;

	int ref_cnt;
} c_psql_database_t;

static char *def_queries[] = {
	"backends",
	"transactions",
	"queries",
	"query_plans",
	"table_states",
	"disk_io",
	"disk_usage"
};
static int def_queries_num = STATIC_ARRAY_SIZE (def_queries);

static c_psql_database_t **databases     = NULL;
static size_t              databases_num = 0;

static udb_query_t       **queries       = NULL;
static size_t              queries_num   = 0;

static c_psql_writer_t    *writers       = NULL;
static size_t              writers_num   = 0;

static int c_psql_begin (c_psql_database_t *db)
{
	PGresult *r = PQexec (db->conn, "BEGIN");

	int status = 1;
コード例 #28
0
ファイル: target_replace.c プロジェクト: CheeriosJo/collectd
static int tr_action_invoke (tr_action_t *act_head, /* {{{ */
    char *buffer_in, size_t buffer_in_size, int may_be_empty)
{
  tr_action_t *act;
  int status;
  char buffer[DATA_MAX_NAME_LEN];
  regmatch_t matches[8];

  if (act_head == NULL)
    return (-EINVAL);

  sstrncpy (buffer, buffer_in, sizeof (buffer));
  memset (matches, 0, sizeof (matches));

  DEBUG ("target_replace plugin: tr_action_invoke: <- buffer = %s;", buffer);

  for (act = act_head; act != NULL; act = act->next)
  {
    char temp[DATA_MAX_NAME_LEN];
    char *subst_status;

    status = regexec (&act->re, buffer,
        STATIC_ARRAY_SIZE (matches), matches,
        /* flags = */ 0);
    if (status == REG_NOMATCH)
      continue;
    else if (status != 0)
    {
      char errbuf[1024] = "";

      regerror (status, &act->re, errbuf, sizeof (errbuf));
      ERROR ("Target `replace': Executing a regular expression failed: %s.",
          errbuf);
      continue;
    }

    subst_status = subst (temp, sizeof (temp), buffer,
        matches[0].rm_so, matches[0].rm_eo, act->replacement);
    if (subst_status == NULL)
    {
      ERROR ("Target `replace': subst (buffer = %s, start = %zu, end = %zu, "
          "replacement = %s) failed.",
          buffer, (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo,
          act->replacement);
      continue;
    }
    sstrncpy (buffer, temp, sizeof (buffer));

    DEBUG ("target_replace plugin: tr_action_invoke: -- buffer = %s;", buffer);
  } /* for (act = act_head; act != NULL; act = act->next) */

  if ((may_be_empty == 0) && (buffer[0] == 0))
  {
    WARNING ("Target `replace': Replacement resulted in an empty string, "
        "which is not allowed for this buffer (`host' or `plugin').");
    return (0);
  }

  DEBUG ("target_replace plugin: tr_action_invoke: -> buffer = %s;", buffer);
  sstrncpy (buffer_in, buffer, buffer_in_size);

  return (0);
} /* }}} int tr_action_invoke */
コード例 #29
0
ファイル: swap.c プロジェクト: CheeriosJo/collectd
#elif HAVE_PERFSTAT
static int pagesize;
static perfstat_memory_total_t pmemory;
/*# endif HAVE_PERFSTAT */

#else
# error "No applicable input method."
#endif /* HAVE_LIBSTATGRAB */

static const char *config_keys[] =
{
	"ReportBytes",
	"ReportByDevice"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);

static int swap_config (const char *key, const char *value) /* {{{ */
{
	if (strcasecmp ("ReportBytes", key) == 0)
	{
#if KERNEL_LINUX
		report_bytes = IS_TRUE (value) ? 1 : 0;
#else
		WARNING ("swap plugin: The \"ReportBytes\" option is only "
				"valid under Linux. "
				"The option is going to be ignored.");
#endif
	}
	else if (strcasecmp ("ReportByDevice", key) == 0)
	{
コード例 #30
0
ファイル: onewire.c プロジェクト: brd/collectd
    },
    /* features_num = */ 1
  },
  { /* DS2438 Volts/Temp */
    /* family = */ "26.",
    {
      {
        /* filename = */ "temperature",
        /* type = */ "temperature",
        /* type_instance = */ ""
      }
    },
    /* features_num = */ 1
  }
};
static int ow_family_features_num = STATIC_ARRAY_SIZE (ow_family_features);

static char *device_g = NULL;
static cdtime_t ow_interval = 0;
static _Bool direct_access = 0;

static const char *config_keys[] =
{
  "Device",
  "IgnoreSelected",
  "Sensor",
  "Interval"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);

static ignorelist_t *sensor_list;