Beispiel #1
0
static int zh_read (void)
{
	gauge_t  arc_hits, arc_misses, l2_hits, l2_misses;
	value_t  zfs_io[2];
	kstat_t	 *ksp	= NULL;

	get_kstat (&ksp, "unix", 0, "vopstats_zfs");
	if (ksp == NULL)
	{
		ERROR ("zfs_health plugin: Cannot find unix:0:vopstats_zfs kstat.");
		return (-1);
	}

	/* Sizes */ 
	/* zh_read_gauge (ksp, "size",    "cache_size", "arc");
	* zh_read_gauge (ksp, "l2_size", "cache_size", "L2");
	*/
        /* Operations */
	/* zh_read_derive (ksp, "allocated","cache_operation", "allocated");
	* zh_read_derive (ksp, "deleted",  "cache_operation", "deleted");
	* zh_read_derive (ksp, "stolen",   "cache_operation", "stolen");
	*/

	/* I/O */
	zfs_io[0].derive = get_kstat_value(ksp, "read_bytes");
	zfs_io[1].derive = get_kstat_value(ksp, "write_bytes");

	zh_submit ("io_octets", "ZFS", zfs_io, /* num values = */ 2);

	return (0);
} /* int zh_read */
Beispiel #2
0
static int interface_init (void)
{
	kstat_t *ksp_chain;

	numif = 0;

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

	for (numif = 0, ksp_chain = kc->kc_chain;
			(numif < MAX_NUMIF) && (ksp_chain != NULL);
			ksp_chain = ksp_chain->ks_next)
	{
		if (strncmp (ksp_chain->ks_class, "net", 3))
			continue;
		if (ksp_chain->ks_type != KSTAT_TYPE_NAMED)
			continue;
		if (kstat_read (kc, ksp_chain, NULL) == -1)
			continue;
		if (get_kstat_value (ksp_chain, "obytes") == -1LL)
			continue;
		ksp[numif++] = ksp_chain;
	}

	return (0);
} /* int interface_init */
Beispiel #3
0
static int zh_read_gauge (kstat_t *ksp, const char *kstat_value,
    const char *type, const char *type_instance)
{
  long long tmp;
  value_t v;

  tmp = get_kstat_value (ksp, (char *)kstat_value);
  if (tmp == -1LL)
  {
    ERROR ("zfs_health plugin: Reading kstat value \"%s\" failed.", kstat_value);
    return (-1);
  }

  v.gauge = (gauge_t) tmp;
  zh_submit (type, type_instance, /* values = */ &v, /* values_num = */ 1);
  return (0);
}
Beispiel #4
0
static long long get_zfs_value(kstat_t *ksp, char *name)
{

	return (get_kstat_value(ksp, name));
}
Beispiel #5
0
static int interface_read (void)
{
#if HAVE_GETIFADDRS
	struct ifaddrs *if_list;
	struct ifaddrs *if_ptr;

/* Darwin/Mac OS X and possible other *BSDs */
#if HAVE_STRUCT_IF_DATA
#  define IFA_DATA if_data
#  define IFA_RX_BYTES ifi_ibytes
#  define IFA_TX_BYTES ifi_obytes
#  define IFA_RX_PACKT ifi_ipackets
#  define IFA_TX_PACKT ifi_opackets
#  define IFA_RX_ERROR ifi_ierrors
#  define IFA_TX_ERROR ifi_oerrors
/* #endif HAVE_STRUCT_IF_DATA */

#elif HAVE_STRUCT_NET_DEVICE_STATS
#  define IFA_DATA net_device_stats
#  define IFA_RX_BYTES rx_bytes
#  define IFA_TX_BYTES tx_bytes
#  define IFA_RX_PACKT rx_packets
#  define IFA_TX_PACKT tx_packets
#  define IFA_RX_ERROR rx_errors
#  define IFA_TX_ERROR tx_errors
#else
#  error "No suitable type for `struct ifaddrs->ifa_data' found."
#endif

	struct IFA_DATA *if_data;

	if (getifaddrs (&if_list) != 0)
		return (-1);

	for (if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
	{
		if (if_ptr->ifa_addr != NULL && if_ptr->ifa_addr->sa_family == AF_LINK) {
			if_data = (struct IFA_DATA *) if_ptr->ifa_data;

			if_submit (if_ptr->ifa_name, "if_octets",
				if_data->IFA_RX_BYTES,
				if_data->IFA_TX_BYTES);
			if_submit (if_ptr->ifa_name, "if_packets",
				if_data->IFA_RX_PACKT,
				if_data->IFA_TX_PACKT);
			if_submit (if_ptr->ifa_name, "if_errors",
				if_data->IFA_RX_ERROR,
				if_data->IFA_TX_ERROR);
		}
	}

	freeifaddrs (if_list);
/* #endif HAVE_GETIFADDRS */

#elif KERNEL_LINUX
	FILE *fh;
	char buffer[1024];
	derive_t incoming, outgoing;
	char *device;

	char *dummy;
	char *fields[16];
	int numfields;

	if ((fh = fopen ("/proc/net/dev", "r")) == NULL)
	{
		char errbuf[1024];
		WARNING ("interface plugin: fopen: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	while (fgets (buffer, 1024, fh) != NULL)
	{
		if (!(dummy = strchr(buffer, ':')))
			continue;
		dummy[0] = '\0';
		dummy++;

		device = buffer;
		while (device[0] == ' ')
			device++;

		if (device[0] == '\0')
			continue;

		numfields = strsplit (dummy, fields, 16);

		if (numfields < 11)
			continue;

		incoming = atoll (fields[0]);
		outgoing = atoll (fields[8]);
		if_submit (device, "if_octets", incoming, outgoing);

		incoming = atoll (fields[1]);
		outgoing = atoll (fields[9]);
		if_submit (device, "if_packets", incoming, outgoing);

		incoming = atoll (fields[2]);
		outgoing = atoll (fields[10]);
		if_submit (device, "if_errors", incoming, outgoing);

		incoming = atoll (fields[3]);
		outgoing = atoll (fields[11]);
		if_submit (device, "if_dropped", incoming, outgoing);
	}

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

#elif HAVE_LIBKSTAT
	int i;
	derive_t rx;
	derive_t tx;
	char iname[DATA_MAX_NAME_LEN];

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

	for (i = 0; i < numif; i++)
	{
		if (kstat_read (kc, ksp[i], NULL) == -1)
			continue;

		if (unique_name)
			ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module, ksp[i]->ks_instance, ksp[i]->ks_name);
		else
			sstrncpy(iname, ksp[i]->ks_name, sizeof(iname));

		/* try to get 64bit counters */
		rx = get_kstat_value (ksp[i], "rbytes64");
		tx = get_kstat_value (ksp[i], "obytes64");
		/* or fallback to 32bit */
		if (rx == -1LL)
			rx = get_kstat_value (ksp[i], "rbytes");
		if (tx == -1LL)
			tx = get_kstat_value (ksp[i], "obytes");
		if ((rx != -1LL) || (tx != -1LL))
			if_submit (iname, "if_octets", rx, tx);

		/* try to get 64bit counters */
		rx = get_kstat_value (ksp[i], "ipackets64");
		tx = get_kstat_value (ksp[i], "opackets64");
		/* or fallback to 32bit */
		if (rx == -1LL)
			rx = get_kstat_value (ksp[i], "ipackets");
		if (tx == -1LL)
			tx = get_kstat_value (ksp[i], "opackets");
		if ((rx != -1LL) || (tx != -1LL))
			if_submit (iname, "if_packets", rx, tx);

		/* no 64bit error counters yet */
		rx = get_kstat_value (ksp[i], "ierrors");
		tx = get_kstat_value (ksp[i], "oerrors");
		if ((rx != -1LL) || (tx != -1LL))
			if_submit (iname, "if_errors", rx, tx);
	}
/* #endif HAVE_LIBKSTAT */

#elif defined(HAVE_LIBSTATGRAB)
	sg_network_io_stats *ios;
	int i, num;

	ios = sg_get_network_io_stats (&num);

	for (i = 0; i < num; i++)
		if_submit (ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx);
/* #endif HAVE_LIBSTATGRAB */

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

	if ((nif =  perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0)
	{
		char errbuf[1024];
		WARNING ("interface plugin: perfstat_netinterface: %s",
			sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	if (pnif != nif || ifstat == NULL)
	{
		free(ifstat);
		ifstat = malloc(nif * sizeof (*ifstat));
	}
	pnif = nif;

	id.name[0]='\0';
	if ((ifs = perfstat_netinterface(&id, ifstat, sizeof(perfstat_netinterface_t), nif)) < 0)
	{
		char errbuf[1024];
		WARNING ("interface plugin: perfstat_netinterface (interfaces=%d): %s",
			nif, sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	for (i = 0; i < ifs; i++)
	{
		if_submit (ifstat[i].name, "if_octets", ifstat[i].ibytes, ifstat[i].obytes);
		if_submit (ifstat[i].name, "if_packets", ifstat[i].ipackets ,ifstat[i].opackets);
		if_submit (ifstat[i].name, "if_errors", ifstat[i].ierrors, ifstat[i].oerrors );
	}
#endif /* HAVE_PERFSTAT */

	return (0);
} /* int interface_read */
Beispiel #6
0
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 */
Beispiel #7
0
static void nfs2_read_kstat (kstat_t *ksp, char *inst)
{
    unsigned long long values[18];

    values[0] = get_kstat_value (ksp, "null");
    values[1] = get_kstat_value (ksp, "getattr");
    values[2] = get_kstat_value (ksp, "setattr");
    values[3] = get_kstat_value (ksp, "root");
    values[4] = get_kstat_value (ksp, "lookup");
    values[5] = get_kstat_value (ksp, "readlink");
    values[6] = get_kstat_value (ksp, "read");
    values[7] = get_kstat_value (ksp, "wrcache");
    values[8] = get_kstat_value (ksp, "write");
    values[9] = get_kstat_value (ksp, "create");
    values[10] = get_kstat_value (ksp, "remove");
    values[11] = get_kstat_value (ksp, "rename");
    values[12] = get_kstat_value (ksp, "link");
    values[13] = get_kstat_value (ksp, "symlink");
    values[14] = get_kstat_value (ksp, "mkdir");
    values[15] = get_kstat_value (ksp, "rmdir");
    values[16] = get_kstat_value (ksp, "readdir");
    values[17] = get_kstat_value (ksp, "statfs");

    nfs2_procedures_submit (values, inst);
}
Beispiel #8
0
static int za_read (void)
{
	gauge_t   arcsize, targetsize, minlimit, maxlimit, hits, misses, l2_size, l2_hits, l2_misses;
	counter_t demand_data_hits, demand_metadata_hits, prefetch_data_hits, prefetch_metadata_hits;
	counter_t demand_data_misses, demand_metadata_misses, prefetch_data_misses, prefetch_metadata_misses;
	counter_t l2_read_bytes, l2_write_bytes;

	get_kstat (&ksp, "zfs", 0, "arcstats");
	if (ksp == NULL)
	{
		ERROR ("zfs_arc plugin: Cannot find zfs:0:arcstats kstat.");
		return (-1);
	}

	arcsize    = get_kstat_value(ksp, "size");
	targetsize = get_kstat_value(ksp, "c");
	minlimit   = get_kstat_value(ksp, "c_min");
	maxlimit   = get_kstat_value(ksp, "c_max");

	demand_data_hits       = get_kstat_value(ksp, "demand_data_hits");
	demand_metadata_hits   = get_kstat_value(ksp, "demand_metadata_hits");
	prefetch_data_hits     = get_kstat_value(ksp, "prefetch_data_hits");
	prefetch_metadata_hits = get_kstat_value(ksp, "prefetch_metadata_hits");

	demand_data_misses       = get_kstat_value(ksp, "demand_data_misses");
	demand_metadata_misses   = get_kstat_value(ksp, "demand_metadata_misses");
	prefetch_data_misses     = get_kstat_value(ksp, "prefetch_data_misses");
	prefetch_metadata_misses = get_kstat_value(ksp, "prefetch_metadata_misses");

	hits   = get_kstat_value(ksp, "hits");
	misses = get_kstat_value(ksp, "misses");

	l2_size        = get_kstat_value(ksp, "l2_size");
	l2_read_bytes  = get_kstat_value(ksp, "l2_read_bytes");
	l2_write_bytes = get_kstat_value(ksp, "l2_write_bytes");
	l2_hits        = get_kstat_value(ksp, "l2_hits");
	l2_misses      = get_kstat_value(ksp, "l2_misses");


	za_submit_size (arcsize, targetsize, minlimit, maxlimit);
	za_submit_gauge ("arc_l2_size", "", l2_size);

	za_submit_counts ("hits",   demand_data_hits,     demand_metadata_hits,
	                            prefetch_data_hits,   prefetch_metadata_hits);
	za_submit_counts ("misses", demand_data_misses,   demand_metadata_misses,
	                            prefetch_data_misses, prefetch_metadata_misses);

	za_submit_gauge ("arc_ratio", "L1", hits / (hits + misses));
	za_submit_gauge ("arc_ratio", "L2", l2_hits / (l2_hits + l2_misses));

	za_submit_bytes (l2_read_bytes, l2_write_bytes);

	return (0);
}
Beispiel #9
0
static int interface_read (void)
{
#if HAVE_GETIFADDRS
	struct ifaddrs *if_list;
	struct ifaddrs *if_ptr;

/* Darin/Mac OS X and possible other *BSDs */
#if HAVE_STRUCT_IF_DATA
#  define IFA_DATA if_data
#  define IFA_RX_BYTES ifi_ibytes
#  define IFA_TX_BYTES ifi_obytes
#  define IFA_RX_PACKT ifi_ipackets
#  define IFA_TX_PACKT ifi_opackets
#  define IFA_RX_ERROR ifi_ierrors
#  define IFA_TX_ERROR ifi_oerrors
/* #endif HAVE_STRUCT_IF_DATA */

#elif HAVE_STRUCT_NET_DEVICE_STATS
#  define IFA_DATA net_device_stats
#  define IFA_RX_BYTES rx_bytes
#  define IFA_TX_BYTES tx_bytes
#  define IFA_RX_PACKT rx_packets
#  define IFA_TX_PACKT tx_packets
#  define IFA_RX_ERROR rx_errors
#  define IFA_TX_ERROR tx_errors
#else
#  error "No suitable type for `struct ifaddrs->ifa_data' found."
#endif

	struct IFA_DATA *if_data;

	if (getifaddrs (&if_list) != 0)
		return (-1);

	for (if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
	{
		if ((if_data = (struct IFA_DATA *) if_ptr->ifa_data) == NULL)
			continue;

		if_submit (if_ptr->ifa_name, "if_octets",
				if_data->IFA_RX_BYTES,
				if_data->IFA_TX_BYTES);
		if_submit (if_ptr->ifa_name, "if_packets",
				if_data->IFA_RX_PACKT,
				if_data->IFA_TX_PACKT);
		if_submit (if_ptr->ifa_name, "if_errors",
				if_data->IFA_RX_ERROR,
				if_data->IFA_TX_ERROR);
	}

	freeifaddrs (if_list);
/* #endif HAVE_GETIFADDRS */

#elif KERNEL_LINUX
	FILE *fh;
	char buffer[1024];
	unsigned long long incoming, outgoing;
	char *device;
	
	char *dummy;
	char *fields[16];
	int numfields;

	if ((fh = fopen ("/proc/net/dev", "r")) == NULL)
	{
		char errbuf[1024];
		WARNING ("interface plugin: fopen: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	while (fgets (buffer, 1024, fh) != NULL)
	{
		if (!(dummy = strchr(buffer, ':')))
			continue;
		dummy[0] = '\0';
		dummy++;

		device = buffer;
		while (device[0] == ' ')
			device++;

		if (device[0] == '\0')
			continue;
		
		numfields = strsplit (dummy, fields, 16);

		if (numfields < 11)
			continue;

		incoming = atoll (fields[0]);
		outgoing = atoll (fields[8]);
		if_submit (device, "if_octets", incoming, outgoing);

		incoming = atoll (fields[1]);
		outgoing = atoll (fields[9]);
		if_submit (device, "if_packets", incoming, outgoing);

		incoming = atoll (fields[2]);
		outgoing = atoll (fields[10]);
		if_submit (device, "if_errors", incoming, outgoing);
	}

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

#elif HAVE_LIBKSTAT
	int i;
	unsigned long long rx;
	unsigned long long tx;

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

	for (i = 0; i < numif; i++)
	{
		if (kstat_read (kc, ksp[i], NULL) == -1)
			continue;

		rx = get_kstat_value (ksp[i], "rbytes");
		tx = get_kstat_value (ksp[i], "obytes");
		if ((rx != -1LL) || (tx != -1LL))
			if_submit (ksp[i]->ks_name, "if_octets", rx, tx);

		rx = get_kstat_value (ksp[i], "ipackets");
		tx = get_kstat_value (ksp[i], "opackets");
		if ((rx != -1LL) || (tx != -1LL))
			if_submit (ksp[i]->ks_name, "if_packets", rx, tx);

		rx = get_kstat_value (ksp[i], "ierrors");
		tx = get_kstat_value (ksp[i], "oerrors");
		if ((rx != -1LL) || (tx != -1LL))
			if_submit (ksp[i]->ks_name, "if_errors", rx, tx);
	}
/* #endif HAVE_LIBKSTAT */

#elif defined(HAVE_LIBSTATGRAB)
	sg_network_io_stats *ios;
	int i, num;

	ios = sg_get_network_io_stats (&num);

	for (i = 0; i < num; i++)
		if_submit (ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx);
#endif /* HAVE_LIBSTATGRAB */

	return (0);
} /* int interface_read */
Beispiel #10
0
static int memory_read (void)
{
#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);
    memory_submit ("active",   active);
    memory_submit ("inactive", inactive);
    memory_submit ("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
     */
    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];

    int    i;

    for (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 (i = 1; sysctl_keys[i] != NULL; i++)
        if (!isnan (sysctl_vals[i]))
            sysctl_vals[i] *= sysctl_vals[0];

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

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

    char *fields[8];
    int numfields;

    long long mem_used = 0;
    long long mem_buffered = 0;
    long long mem_cached = 0;
    long long mem_free = 0;

    if ((fh = fopen ("/proc/meminfo", "r")) == NULL)
    {
        char errbuf[1024];
        WARNING ("memory: fopen: %s",
                 sstrerror (errno, errbuf, sizeof (errbuf)));
        return (-1);
    }

    while (fgets (buffer, 1024, fh) != NULL)
    {
        long long *val = NULL;

        if (strncasecmp (buffer, "MemTotal:", 9) == 0)
            val = &mem_used;
        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
            continue;

        numfields = strsplit (buffer, fields, 8);

        if (numfields < 2)
            continue;

        *val = atoll (fields[1]) * 1024LL;
    }

    if (fclose (fh))
    {
        char errbuf[1024];
        WARNING ("memory: fclose: %s",
                 sstrerror (errno, errbuf, sizeof (errbuf)));
    }

    if (mem_used >= (mem_free + mem_buffered + mem_cached))
    {
        mem_used -= mem_free + mem_buffered + mem_cached;
        memory_submit ("used",     mem_used);
        memory_submit ("buffered", mem_buffered);
        memory_submit ("cached",   mem_cached);
        memory_submit ("free",     mem_free);
    }
    /* #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 pp_kernel;
    long long physmem;
    long long availrmem;

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

    mem_used = get_kstat_value (ksp, "pagestotal");
    mem_free = get_kstat_value (ksp, "pagesfree");
    mem_lock = get_kstat_value (ksp, "pageslocked");
    mem_kern = 0;
    mem_unus = 0;

    pp_kernel = get_kstat_value (ksp, "pp_kernel");
    physmem = get_kstat_value (ksp, "physmem");
    availrmem = get_kstat_value (ksp, "availrmem");

    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;

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

#elif HAVE_SYSCTL
    int mib[] = {CTL_VM, VM_METER};
    struct vmtotal vmtotal;
    size_t size;

    memset (&vmtotal, 0, sizeof (vmtotal));
    size = sizeof (vmtotal);

    if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) {
        char errbuf[1024];
        WARNING ("memory plugin: sysctl failed: %s",
                 sstrerror (errno, errbuf, sizeof (errbuf)));
        return (-1);
    }

    assert (pagesize > 0);
    memory_submit ("active",   vmtotal.t_arm * pagesize);
    memory_submit ("inactive", (vmtotal.t_rm - vmtotal.t_arm) * pagesize);
    memory_submit ("free",     vmtotal.t_free * pagesize);
    /* #endif HAVE_SYSCTL */

#elif HAVE_LIBSTATGRAB
    sg_mem_stats *ios;

    if ((ios = sg_get_mem_stats ()) != NULL)
    {
        memory_submit ("used",   ios->used);
        memory_submit ("cached", ios->cache);
        memory_submit ("free",   ios->free);
    }
    /* #endif HAVE_LIBSTATGRAB */

#elif HAVE_PERFSTAT
    if (perfstat_memory_total(NULL, &pmemory, sizeof(perfstat_memory_total_t), 1) < 0)
    {
        char errbuf[1024];
        WARNING ("memory plugin: perfstat_memory_total failed: %s",
                 sstrerror (errno, errbuf, sizeof (errbuf)));
        return (-1);
    }
    memory_submit ("used",   pmemory.real_inuse * pagesize);
    memory_submit ("free",   pmemory.real_free * pagesize);
    memory_submit ("cached", pmemory.numperm * pagesize);
    memory_submit ("system", pmemory.real_system * pagesize);
    memory_submit ("user",   pmemory.real_process * pagesize);
#endif /* HAVE_PERFSTAT */

    return (0);
}