Merge pull request #312 from jazzmes/libvirt-mem-usage
authorPierre-Yves Ritschard <pyr@spootnik.org>
Thu, 31 Jul 2014 21:49:35 +0000 (23:49 +0200)
committerPierre-Yves Ritschard <pyr@spootnik.org>
Thu, 31 Jul 2014 21:49:35 +0000 (23:49 +0200)
Included memory usage per VM

1  2 
src/libvirt.c

diff --combined src/libvirt.c
@@@ -32,9 -32,6 +32,9 @@@
  #include <libxml/tree.h>
  #include <libxml/xpath.h>
  
 +/* Plugin name */
 +#define PLUGIN_NAME "libvirt"
 +
  static const char *config_keys[] = {
      "Connection",
  
@@@ -48,8 -45,6 +48,8 @@@
      "HostnameFormat",
      "InterfaceFormat",
  
 +    "PluginInstanceFormat",
 +
      NULL
  };
  #define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1)
@@@ -118,18 -113,6 +118,18 @@@ enum hf_field 
  static enum hf_field hostname_format[HF_MAX_FIELDS] =
      { hf_name };
  
 +/* PluginInstanceFormat */
 +#define PLGINST_MAX_FIELDS 2
 +
 +enum plginst_field {
 +    plginst_none = 0,
 +    plginst_name,
 +    plginst_uuid
 +};
 +
 +static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] =
 +    { plginst_name };
 +
  /* InterfaceFormat. */
  enum if_field {
      if_address,
@@@ -158,7 -141,7 +158,7 @@@ init_value_list (value_list_t *vl, virD
      const char *name;
      char uuid[VIR_UUID_STRING_BUFLEN];
  
 -    sstrncpy (vl->plugin, "libvirt", sizeof (vl->plugin));
 +    sstrncpy (vl->plugin, PLUGIN_NAME, sizeof (vl->plugin));
  
      vl->host[0] = '\0';
  
      }
  
      vl->host[sizeof (vl->host) - 1] = '\0';
 +
 +    /* Construct the plugin instance field according to PluginInstanceFormat. */
 +    for (i = 0; i < PLGINST_MAX_FIELDS; ++i) {
 +        if (plugin_instance_format[i] == plginst_none)
 +            continue;
 +
 +        n = sizeof(vl->plugin_instance) - strlen (vl->plugin_instance) - 2;
 +
 +        if (i > 0 && n >= 1) {
 +            strncat (vl->plugin_instance, ":", 1);
 +            n--;
 +        }
 +
 +        switch (plugin_instance_format[i]) {
 +        case plginst_none: break;
 +        case plginst_name:
 +            name = virDomainGetName (dom);
 +            if (name)
 +                strncat (vl->plugin_instance, name, n);
 +            break;
 +        case plginst_uuid:
 +            if (virDomainGetUUIDString (dom, uuid) == 0)
 +                strncat (vl->plugin_instance, uuid, n);
 +            break;
 +        }
 +    }
 +
 +    vl->plugin_instance[sizeof (vl->plugin_instance) - 1] = '\0';
 +
  } /* void init_value_list */
  
  static void
@@@ -243,6 -197,28 +243,28 @@@ memory_submit (gauge_t memory, virDomai
  }
  
  static void
+ memory_stats_submit (gauge_t memory, virDomainPtr dom, int tag_index)
+ {
+     static const char *tags[] = { "swap_in", "swap_out", "major_fault", "minor_fault",
+                                     "unused", "available", "actual_balloon", "rss"};
+     value_t values[1];
+     value_list_t vl = VALUE_LIST_INIT;
+     init_value_list (&vl, dom);
+     values[0].gauge = memory;
+     vl.values = values;
+     vl.values_len = 1;
+     sstrncpy (vl.type, "memory", sizeof (vl.type));
+     sstrncpy (vl.type_instance, tags[tag_index], sizeof (vl.type_instance));
+     plugin_dispatch_values (&vl);
+ }
+ static void
  cpu_submit (unsigned long long cpu_time,
              virDomainPtr dom, const char *type)
  {
@@@ -325,7 -301,7 +347,7 @@@ lv_config (const char *key, const char 
      if (strcasecmp (key, "Connection") == 0) {
          char *tmp = strdup (value);
          if (tmp == NULL) {
 -            ERROR ("libvirt plugin: Connection strdup failed.");
 +            ERROR (PLUGIN_NAME " plugin: Connection strdup failed.");
              return 1;
          }
          sfree (conn_string);
  
          value_copy = strdup (value);
          if (value_copy == NULL) {
 -            ERROR ("libvirt plugin: strdup failed.");
 +            ERROR (PLUGIN_NAME " plugin: strdup failed.");
              return -1;
          }
  
          n = strsplit (value_copy, fields, HF_MAX_FIELDS);
          if (n < 1) {
              sfree (value_copy);
 -            ERROR ("HostnameFormat: no fields");
 +            ERROR (PLUGIN_NAME " plugin: HostnameFormat: no fields");
              return -1;
          }
  
                  hostname_format[i] = hf_uuid;
              else {
                  sfree (value_copy);
 -                ERROR ("unknown HostnameFormat field: %s", fields[i]);
 +                ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]);
                  return -1;
              }
          }
          return 0;
      }
  
 +    if (strcasecmp (key, "PluginInstanceFormat") == 0) {
 +        char *value_copy;
 +        char *fields[PLGINST_MAX_FIELDS];
 +        int i, n;
 +
 +        value_copy = strdup (value);
 +        if (value_copy == NULL) {
 +            ERROR (PLUGIN_NAME " plugin: strdup failed.");
 +            return -1;
 +        }
 +
 +        n = strsplit (value_copy, fields, PLGINST_MAX_FIELDS);
 +        if (n < 1) {
 +            sfree (value_copy);
 +            ERROR (PLUGIN_NAME " plugin: PluginInstanceFormat: no fields");
 +            return -1;
 +        }
 +
 +        for (i = 0; i < n; ++i) {
 +            if (strcasecmp (fields[i], "name") == 0)
 +                plugin_instance_format[i] = plginst_name;
 +            else if (strcasecmp (fields[i], "uuid") == 0)
 +                plugin_instance_format[i] = plginst_uuid;
 +            else {
 +                sfree (value_copy);
 +                ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]);
 +                return -1;
 +            }
 +        }
 +        sfree (value_copy);
 +
 +        for (i = n; i < PLGINST_MAX_FIELDS; ++i)
 +            plugin_instance_format[i] = plginst_none;
 +
 +        return 0;
 +    }
 +
      if (strcasecmp (key, "InterfaceFormat") == 0) {
          if (strcasecmp (value, "name") == 0)
              interface_format = if_name;
          else if (strcasecmp (value, "number") == 0)
              interface_format = if_number;
          else {
 -            ERROR ("unknown InterfaceFormat: %s", value);
 +            ERROR (PLUGIN_NAME " plugin: unknown InterfaceFormat: %s", value);
              return -1;
          }
          return 0;
@@@ -474,13 -413,13 +496,13 @@@ lv_read (void
          conn = virConnectOpenReadOnly (conn_string);
          if (conn == NULL) {
              c_complain (LOG_ERR, &conn_complain,
 -                    "libvirt plugin: Unable to connect: "
 +                    PLUGIN_NAME " plugin: Unable to connect: "
                      "virConnectOpenReadOnly failed.");
              return -1;
          }
      }
      c_release (LOG_NOTICE, &conn_complain,
 -            "libvirt plugin: Connection established.");
 +            PLUGIN_NAME " plugin: Connection established.");
  
      time (&t);
  
      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 ("libvirt plugin: virDomainGetInfo failed with status %i.",
 +            ERROR (PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
                      status);
              continue;
          }
  
          vinfo = malloc (info.nrVirtCpu * sizeof (vinfo[0]));
          if (vinfo == NULL) {
 -            ERROR ("libvirt plugin: malloc failed.");
 +            ERROR (PLUGIN_NAME " plugin: malloc failed.");
              continue;
          }
  
                  /* cpu map = */ NULL, /* cpu map length = */ 0);
          if (status < 0)
          {
 -            ERROR ("libvirt plugin: virDomainGetVcpus failed with status %i.",
 +            ERROR (PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.",
                      status);
-             free (vinfo);
+             sfree (vinfo);
              continue;
          }
  
                      domains[i], vinfo[j].number, "virt_vcpu");
  
          sfree (vinfo);
+         minfo = malloc (VIR_DOMAIN_MEMORY_STAT_NR * sizeof (virDomainMemoryStatStruct));
+         if (minfo == NULL) {
+             ERROR ("libvirt plugin: malloc failed.");
+             continue;
+         }
+         status =  virDomainMemoryStats (domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0);
+         if (status < 0) {
+             ERROR ("libvirt plugin: virDomainMemoryStats failed with status %i.",
+                     status);
+             sfree (minfo);
+             continue;
+         }
+         for (j = 0; j < status; j++) {
+             memory_stats_submit ((gauge_t) minfo[j].val, 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;
@@@ -634,7 -596,7 +679,7 @@@ refresh_lists (void
          /* Get list of domains. */
          domids = malloc (sizeof (int) * n);
          if (domids == 0) {
 -            ERROR ("libvirt plugin: malloc failed.");
 +            ERROR (PLUGIN_NAME " plugin: malloc failed.");
              return -1;
          }
  
                  goto cont;
  
              if (add_domain (dom) < 0) {
 -                ERROR ("libvirt plugin: malloc failed.");
 +                ERROR (PLUGIN_NAME " plugin: malloc failed.");
                  goto cont;
              }
  
@@@ -913,7 -875,7 +958,7 @@@ ignore_device_match (ignorelist_t *il, 
      n = sizeof (char) * (strlen (domname) + strlen (devpath) + 2);
      name = malloc (n);
      if (name == NULL) {
 -        ERROR ("libvirt plugin: malloc failed.");
 +        ERROR (PLUGIN_NAME " plugin: malloc failed.");
          return 0;
      }
      ssnprintf (name, n, "%s:%s", domname, devpath);
@@@ -946,12 -908,12 +991,12 @@@ lv_shutdown (void
  void
  module_register (void)
  {
 -    plugin_register_config ("libvirt",
 +    plugin_register_config (PLUGIN_NAME,
      lv_config,
      config_keys, NR_CONFIG_KEYS);
 -    plugin_register_init ("libvirt", lv_init);
 -    plugin_register_read ("libvirt", lv_read);
 -    plugin_register_shutdown ("libvirt", lv_shutdown);
 +    plugin_register_init (PLUGIN_NAME, lv_init);
 +    plugin_register_read (PLUGIN_NAME, lv_read);
 +    plugin_register_shutdown (PLUGIN_NAME, lv_shutdown);
  }
  
  /*