Ejemplo n.º 1
0
void submit_memory_stats (cJSON* root, container_t* container) {
	/*get current memory usage*/
	unsigned long mem_value = cJSON_GetObjectItem(cJSON_GetObjectItem(root,"memory_stats"),"usage")->valueint;
	memory_submit(mem_value,container,"usage");
	
	mem_value = cJSON_GetObjectItem(cJSON_GetObjectItem(root,"memory_stats"),"failcnt")->valueint;
	memory_submit(mem_value,container,"fail_count");
	
	mem_value = cJSON_GetObjectItem(cJSON_GetObjectItem(root,"memory_stats"),"limit")->valueint;
	memory_submit(mem_value,container,"limit");

	mem_value = cJSON_GetObjectItem(cJSON_GetObjectItem(cJSON_GetObjectItem(root,"memory_stats"),"stats"),"rss")->valueint;
	memory_submit(mem_value,container,"rss");
	
	mem_value = cJSON_GetObjectItem(cJSON_GetObjectItem(cJSON_GetObjectItem(root,"memory_stats"),"stats"),"pgmajfault")->valueint;
	memory_submit(mem_value,container,"pgfault_major");
	
	mem_value = cJSON_GetObjectItem(cJSON_GetObjectItem(cJSON_GetObjectItem(root,"memory_stats"),"stats"),"pgfault")->valueint;
	memory_submit(mem_value,container,"pgfault_minor");
	
}
Ejemplo n.º 2
0
static int
lv_read (void)
{
    time_t t;
    int i;

    if (conn == NULL) {
        /* `conn_string == NULL' is acceptable. */
        conn = virConnectOpenReadOnly (conn_string);
        if (conn == NULL) {
            c_complain (LOG_ERR, &conn_complain,
                    PLUGIN_NAME " plugin: Unable to connect: "
                    "virConnectOpenReadOnly failed.");
            return -1;
        }
    }
    c_release (LOG_NOTICE, &conn_complain,
            PLUGIN_NAME " plugin: Connection established.");

    time (&t);

    /* Need to refresh domain or device lists? */
    if ((last_refresh == (time_t) 0) ||
            ((interval > 0) && ((last_refresh + interval) <= t))) {
        if (refresh_lists () != 0) {
            if (conn != NULL)
                virConnectClose (conn);
            conn = NULL;
            return -1;
        }
        last_refresh = t;
    }

#if 0
    for (i = 0; i < nr_domains; ++i)
        fprintf (stderr, "domain %s\n", virDomainGetName (domains[i]));
    for (i = 0; i < nr_block_devices; ++i)
        fprintf  (stderr, "block device %d %s:%s\n",
                  i, virDomainGetName (block_devices[i].dom),
                  block_devices[i].path);
    for (i = 0; i < nr_interface_devices; ++i)
        fprintf (stderr, "interface device %d %s:%s\n",
                 i, virDomainGetName (interface_devices[i].dom),
                 interface_devices[i].path);
#endif

    /* Get CPU usage, memory, VCPU usage for each domain. */
    for (i = 0; i < nr_domains; ++i) {
        virDomainInfo info;
        virVcpuInfoPtr vinfo = NULL;
        virDomainMemoryStatPtr minfo = NULL;
        int status;
        int j;

        status = virDomainGetInfo (domains[i], &info);
        if (status != 0)
        {
            ERROR (PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
                    status);
            continue;
        }

        if (info.state != VIR_DOMAIN_RUNNING)
        {
            /* only gather stats for running domains */
            continue;
        }

        cpu_submit (info.cpuTime, domains[i], "virt_cpu_total");
        memory_submit ((gauge_t) info.memory * 1024, domains[i]);

        vinfo = malloc (info.nrVirtCpu * sizeof (vinfo[0]));
        if (vinfo == NULL) {
            ERROR (PLUGIN_NAME " plugin: malloc failed.");
            continue;
        }

        status = virDomainGetVcpus (domains[i], vinfo, info.nrVirtCpu,
                /* cpu map = */ NULL, /* cpu map length = */ 0);
        if (status < 0)
        {
            ERROR (PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.",
                    status);
            sfree (vinfo);
            continue;
        }

        for (j = 0; j < info.nrVirtCpu; ++j)
            vcpu_submit (vinfo[j].cpuTime,
                    domains[i], vinfo[j].number, "virt_vcpu");

        sfree (vinfo);

        minfo = malloc (VIR_DOMAIN_MEMORY_STAT_NR * sizeof (virDomainMemoryStatStruct));
        if (minfo == NULL) {
            ERROR ("virt plugin: malloc failed.");
            continue;
        }

        status =  virDomainMemoryStats (domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0);

        if (status < 0) {
            ERROR ("virt plugin: virDomainMemoryStats failed with status %i.",
                    status);
            sfree (minfo);
            continue;
        }

        for (j = 0; j < status; j++) {
            memory_stats_submit ((gauge_t) minfo[j].val * 1024, domains[i], minfo[j].tag);
        }

        sfree (minfo);
    }


    /* Get block device stats for each domain. */
    for (i = 0; i < nr_block_devices; ++i) {
        struct _virDomainBlockStats stats;

        if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path,
                    &stats, sizeof stats) != 0)
            continue;

        if ((stats.rd_req != -1) && (stats.wr_req != -1))
            submit_derive2 ("disk_ops",
                    (derive_t) stats.rd_req, (derive_t) stats.wr_req,
                    block_devices[i].dom, block_devices[i].path);

        if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1))
            submit_derive2 ("disk_octets",
                    (derive_t) stats.rd_bytes, (derive_t) stats.wr_bytes,
                    block_devices[i].dom, block_devices[i].path);
    } /* for (nr_block_devices) */

    /* Get interface stats for each domain. */
    for (i = 0; i < nr_interface_devices; ++i) {
        struct _virDomainInterfaceStats stats;
        char *display_name = NULL;


        switch (interface_format) {
            case if_address:
                display_name = interface_devices[i].address;
                break;
            case if_number:
                display_name = interface_devices[i].number;
                break;
            case if_name:
            default:
                display_name = interface_devices[i].path;
        }

        if (virDomainInterfaceStats (interface_devices[i].dom,
                    interface_devices[i].path,
                    &stats, sizeof stats) != 0)
            continue;

	if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1))
	    submit_derive2 ("if_octets",
		    (derive_t) stats.rx_bytes, (derive_t) stats.tx_bytes,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_packets != -1) && (stats.tx_packets != -1))
	    submit_derive2 ("if_packets",
		    (derive_t) stats.rx_packets, (derive_t) stats.tx_packets,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_errs != -1) && (stats.tx_errs != -1))
	    submit_derive2 ("if_errors",
		    (derive_t) stats.rx_errs, (derive_t) stats.tx_errs,
		    interface_devices[i].dom, display_name);

	if ((stats.rx_drop != -1) && (stats.tx_drop != -1))
	    submit_derive2 ("if_dropped",
		    (derive_t) stats.rx_drop, (derive_t) stats.tx_drop,
		    interface_devices[i].dom, display_name);
    } /* for (nr_interface_devices) */

    return 0;
}
Ejemplo n.º 3
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);
}