Modified plugin virt.c
authorDeyan Chepishev <dchepishev@superhosting.bg>
Wed, 26 Oct 2016 15:10:47 +0000 (18:10 +0300)
committerDeyan Chepishev <dchepishev@superhosting.bg>
Wed, 26 Oct 2016 15:10:47 +0000 (18:10 +0300)
Added options:
BlockDeviceFormat
BlockDeviceFormatBasename

src/collectd.conf.in
src/collectd.conf.pod
src/virt.c

index ae29951..821d0ff 100644 (file)
 #      RefreshInterval 60
 #      Domain "name"
 #      BlockDevice "name:device"
+#      BlockDeviceFormat dev
+#      BlockDeviceFormatBasename false
 #      InterfaceDevice "name:device"
 #      IgnoreSelected false
 #      HostnameFormat name
index 1310c50..9088163 100644 (file)
@@ -7773,6 +7773,10 @@ option is set to 0, refreshing is disabled completely.
 
 =item B<BlockDevice> I<name:dev>
 
+=item B<lockDeviceFormat> B<source>|B<dev>
+
+=item B<BlockDeviceFormatBasename> B<false>|B<true>
+
 =item B<InterfaceDevice> I<name:dev>
 
 =item B<IgnoreSelected> B<true>|B<false>
@@ -7798,6 +7802,53 @@ Example:
 Ignore all I<hdb> devices on any domain, but other block devices (eg. I<hda>)
 will be collected.
 
+If I<BlockDeviceFormat> is set to B<dev>, then the device names will be the ones
+in the I<target> node for the device in the XML definition of the domain. The
+default is B<dev>. This is the behavior before adding the option.
+
+If I<BlockDeviceFormat> is set to B<source>, then the device names will be the ones
+in the I<source> node for the device in the XML definition of the domain.
+
+Example:
+
+If the domain XML have the following device defined:
+
+   <disk type='block' device='disk'>
+      <driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
+      <source dev='/var/lib/libvirt/images/image1.qcow2'/>
+      <target dev='sda' bus='scsi'/>
+      <boot order='2'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+
+setting 
+
+        BlockDeviceFormat dev
+
+will name the device in the graph as sda 
+
+setting
+       BlockDeviceFormat source
+
+will name the device in the graph as var_lib_libvirt_images_image1.qcow2
+
+These names will also be part of the RRD filename.
+
+I<BlockDeviceFormatBasename> - this option is honored if and only if 
+option I<BlockDeviceFormat> is set to B<source>. If set to B<true> then 
+only the last part of the path will be used for device name and naming the
+RRD file.
+
+Example: 
+
+if the device path (source tag) is: /var/lib/libvirt/images/image1.qcow2
+
+setting:
+       BlockDeviceFormatBasename true
+
+will set the device name to: image1.qcow2
+
 =item B<HostnameFormat> B<name|uuid|hostname|...>
 
 When the virt plugin logs data, it sets the hostname of the collected data
index 99fe42d..e32150a 100644 (file)
@@ -31,6 +31,7 @@
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
+#include <libgen.h>
 
 /* Plugin name */
 #define PLUGIN_NAME "virt"
@@ -42,6 +43,8 @@ static const char *config_keys[] = {
 
     "Domain",
     "BlockDevice",
+    "BlockDeviceFormat",
+    "BlockDeviceFormatBasename",
     "InterfaceDevice",
     "IgnoreSelected",
 
@@ -130,6 +133,12 @@ enum plginst_field {
 static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] =
     { plginst_none };
 
+/* BlockDeviceFormat */
+enum bd_field {
+       dev,
+       source
+};
+
 /* InterfaceFormat. */
 enum if_field {
     if_address,
@@ -137,6 +146,9 @@ enum if_field {
     if_number
 };
 
+/* BlockDeviceFormatBasename */
+char *blockdevice_format_basename="false";
+static enum bd_field blockdevice_format = dev;
 static enum if_field interface_format = if_name;
 
 /* Time that we last refreshed. */
@@ -338,6 +350,29 @@ lv_config (const char *key, const char *value)
         if (ignorelist_add (il_block_devices, value)) return 1;
         return 0;
     }
+
+    if (strcasecmp (key, "BlockDeviceFormat") == 0) {
+        if (strcasecmp (value, "dev") == 0)
+            blockdevice_format = dev;
+        else if (strcasecmp (value, "source") == 0)
+            blockdevice_format = source;
+        else {
+            ERROR (PLUGIN_NAME " plugin: unknown BlockDeviceFormat: %s", value);
+            return -1;
+        }
+        return 0;
+    }
+    if (strcasecmp (key, "BlockDeviceFormatBasename") == 0) {
+        if (strcasecmp (value, "true") == 0)
+            blockdevice_format_basename = "true";
+        else if (strcasecmp (value, "false") == 0)
+            blockdevice_format_basename = "false";
+        else {
+            ERROR (PLUGIN_NAME " plugin: unknown BlockDeviceFormatBasename: %s", value);
+            return -1;
+        }
+        return 0;
+    }
     if (strcasecmp (key, "InterfaceDevice") == 0) {
         if (ignorelist_add (il_interface_devices, value)) return 1;
         return 0;
@@ -578,15 +613,23 @@ lv_read (void)
                     &stats, sizeof stats) != 0)
             continue;
 
+       char *new_path=NULL;
+       if( 0==strcasecmp("true", blockdevice_format_basename) && source==blockdevice_format){ //valid only if we use source (full path to the device)
+               new_path=strdup(basename(block_devices[i].path));
+       }else{
+               new_path=strdup(block_devices[i].path);
+       }
         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);
+                    block_devices[i].dom, new_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);
+                    block_devices[i].dom, new_path);
+       
+       free(new_path);
     } /* for (nr_block_devices) */
 
     /* Get interface stats for each domain. */
@@ -715,9 +758,18 @@ refresh_lists (void)
             xpath_ctx = xmlXPathNewContext (xml_doc);
 
             /* Block devices. */
+           char * bd_xmlpath=NULL;
+           if( source == blockdevice_format ){
+                   bd_xmlpath="/domain/devices/disk/source[@dev]";
+           }else{
+                       if( dev == blockdevice_format ){
+                               bd_xmlpath="/domain/devices/disk/target[@dev]";
+                       }
+           }
             xpath_obj = xmlXPathEval
-                ((xmlChar *) "/domain/devices/disk/target[@dev]",
-                 xpath_ctx);
+                  ((xmlChar *) bd_xmlpath,
+                   xpath_ctx);
+
             if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
                 xpath_obj->nodesetval == NULL)
                 goto cont;