summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fd64cb0)
raw | patch | inline | side by side (parent: fd64cb0)
author | Richard Jones <rjones@redhat.com> | |
Tue, 6 Nov 2007 18:46:29 +0000 (19:46 +0100) | ||
committer | Florian Forster <octo@huhu.verplant.org> | |
Tue, 6 Nov 2007 18:46:29 +0000 (19:46 +0100) |
This is something I missed out of the previous patch: I want a way to log
guests using their UUID instead of their name (more useful for us because of
the migration and other issues outlined before).
This adds:
<Plugin libvirtstats>
HostnameFormat "uuid"
</Plugin>
to let us do that. You can do other things as well such as:
HostnameFormat "name uuid"
to get "foo:1234-1234-1234-1234" as the hostname.
Rich.
guests using their UUID instead of their name (more useful for us because of
the migration and other issues outlined before).
This adds:
<Plugin libvirtstats>
HostnameFormat "uuid"
</Plugin>
to let us do that. You can do other things as well such as:
HostnameFormat "name uuid"
to get "foo:1234-1234-1234-1234" as the hostname.
Rich.
src/collectd.conf.pod | patch | blob | history | |
src/libvirtstats.c | patch | blob | history |
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index 371cfdf812e971b29210f40475f7c5338b0da499..2720e83448530a5bacb4bf1fc61d402e18f2fb42 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
this.
=item B<Domain> I<name>
+
=item B<BlockDevice> I<name:dev>
+
=item B<InterfaceDevice> I<name:dev>
+
=item B<IgnoreSelected> I<true>|I<false>
Select which domains and devices are monitored.
Ignore all I<hdb> devices on any domain, but other block devices
(eg. I<hda>) will be monitored.
+=item B<HostnameFormat> I<name|uuid|hostname|...>
+
+When libvirtstats logs data, it sets the collectd I<host> field in the
+data according to this setting.
+
+The default is I<name> which means to use the guest name from the
+hypervisor.
+
+I<uuid> means use the guest's UUID. This is useful if you want to
+track the same guest across migrations.
+
+I<hostname> means to use the global I<Hostname> setting, which is
+probably not useful on its own because all guests will appear to have
+the same name.
+
+You can also specify combinations of these fields. For example
+I<name uuid>
+means to concatenate the guest name and UUID (with a literal
+colon character between, thus I<"foo:1234-1234-1234-1234">).
+
=back
=head2 Plugin C<logfile>
diff --git a/src/libvirtstats.c b/src/libvirtstats.c
index d4cb63377964c85be58f6ef77f48860c72ca2d0c..14476ee8bbadb25e609f88b1d448068368a07974 100644 (file)
--- a/src/libvirtstats.c
+++ b/src/libvirtstats.c
"BlockDevice",
"InterfaceDevice",
"IgnoreSelected",
+
+ "HostnameFormat",
+
NULL
};
#define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1)
static void free_interface_devices (void);
static int add_interface_device (virDomainPtr dom, const char *path);
+/* HostnameFormat. */
+#define HF_MAX_FIELDS 3
+
+enum hf_field {
+ hf_none = 0,
+ hf_hostname,
+ hf_name,
+ hf_uuid
+};
+
+static enum hf_field hostname_format[HF_MAX_FIELDS] =
+ { hf_name };
+
/* Time that we last refreshed. */
static time_t last_refresh = (time_t) 0;
/* Submit functions. */
static void cpu_submit (unsigned long long cpu_time,
time_t t,
- const char *domname, const char *type);
+ virDomainPtr dom, const char *type);
static void vcpu_submit (unsigned long long cpu_time,
time_t t,
- const char *domname, int vcpu_nr, const char *type);
+ virDomainPtr dom, int vcpu_nr, const char *type);
static void disk_submit (long long read, long long write,
time_t t,
- const char *domname, const char *devname,
+ virDomainPtr dom, const char *devname,
const char *type);
static void if_submit (long long rx, long long tx,
time_t t,
- const char *domname, const char *devname,
+ virDomainPtr dom, const char *devname,
const char *type);
/* ERROR(...) macro for virterrors. */
ignorelist_set_invert (il_block_devices, 1);
ignorelist_set_invert (il_interface_devices, 1);
}
+ return 0;
+ }
+
+ if (strcasecmp (key, "HostnameFormat") == 0) {
+ char *value_copy;
+ char *fields[HF_MAX_FIELDS];
+ int i, n;
+
+ value_copy = strdup (value);
+ if (value_copy == NULL) {
+ ERROR ("strdup: %s", strerror (errno));
+ return -1;
+ }
+
+ n = strsplit (value_copy, fields, HF_MAX_FIELDS);
+ if (n < 1) {
+ free (value_copy);
+ ERROR ("HostnameFormat: no fields");
+ return -1;
+ }
+
+ for (i = 0; i < n; ++i) {
+ if (strcasecmp (fields[i], "hostname") == 0)
+ hostname_format[i] = hf_hostname;
+ else if (strcasecmp (fields[i], "name") == 0)
+ hostname_format[i] = hf_name;
+ else if (strcasecmp (fields[i], "uuid") == 0)
+ hostname_format[i] = hf_uuid;
+ else {
+ free (value_copy);
+ ERROR ("unknown HostnameFormat field: %s", fields[i]);
+ return -1;
+ }
+ }
+ free (value_copy);
+
+ for (i = n; i < HF_MAX_FIELDS; ++i)
+ hostname_format[i] = hf_none;
+
+ return 0;
}
/* Unrecognised option. */
/* Get CPU usage, VCPU usage for each domain. */
for (i = 0; i < nr_domains; ++i) {
- const char *name;
virDomainInfo info;
virVcpuInfoPtr vinfo = NULL;
int j;
- name = virDomainGetName (domains[i]);
- if (name == NULL) continue;
-
if (virDomainGetInfo (domains[i], &info) == -1) continue;
- cpu_submit (info.cpuTime, t, name, "virt_cpu_total");
+ cpu_submit (info.cpuTime, t, domains[i], "virt_cpu_total");
vinfo = malloc (info.nrVirtCpu * sizeof vinfo[0]);
if (vinfo == NULL) {
for (j = 0; j < info.nrVirtCpu; ++j)
vcpu_submit (vinfo[j].cpuTime,
- t, name, vinfo[j].number, "virt_vcpu");
+ t, domains[i], vinfo[j].number, "virt_vcpu");
free (vinfo);
}
/* Get block device stats for each domain. */
for (i = 0; i < nr_block_devices; ++i) {
- const char *name;
struct _virDomainBlockStats stats;
- name = virDomainGetName (block_devices[i].dom);
- if (name == NULL) continue;
-
if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path,
&stats, sizeof stats) == -1)
continue;
disk_submit (stats.rd_req, stats.wr_req,
- t, name, block_devices[i].path,
+ t, block_devices[i].dom, block_devices[i].path,
"disk_ops");
disk_submit (stats.rd_bytes, stats.wr_bytes,
- t, name, block_devices[i].path,
+ t, block_devices[i].dom, block_devices[i].path,
"disk_octets");
}
/* Get interface stats for each domain. */
for (i = 0; i < nr_interface_devices; ++i) {
- const char *name;
struct _virDomainInterfaceStats stats;
- name = virDomainGetName (interface_devices[i].dom);
- if (name == NULL) continue;
-
if (virDomainInterfaceStats (interface_devices[i].dom,
interface_devices[i].path,
&stats, sizeof stats) == -1)
continue;
if_submit (stats.rx_bytes, stats.tx_bytes,
- t, name, interface_devices[i].path,
+ t, interface_devices[i].dom, interface_devices[i].path,
"if_octets");
if_submit (stats.rx_packets, stats.tx_packets,
- t, name, interface_devices[i].path,
+ t, interface_devices[i].dom, interface_devices[i].path,
"if_packets");
if_submit (stats.rx_errs, stats.tx_errs,
- t, name, interface_devices[i].path,
+ t, interface_devices[i].dom, interface_devices[i].path,
"if_errors");
if_submit (stats.rx_drop, stats.tx_drop,
- t, name, interface_devices[i].path,
+ t, interface_devices[i].dom, interface_devices[i].path,
"if_dropped");
}
@@ -586,23 +630,66 @@ ignore_device_match (ignorelist_t *il, const char *domname, const char *devpath)
return r;
}
+static void
+common_submit (value_list_t *vl, time_t t, virDomainPtr dom)
+{
+ int i, n;
+ const char *name;
+ char uuid[VIR_UUID_STRING_BUFLEN];
+
+ vl->time = t;
+ vl->interval = interval_g;
+ strncpy (vl->plugin, "libvirtstats", DATA_MAX_NAME_LEN);
+ /*strncpy (vl->plugin_instance, ?, DATA_MAX_NAME_LEN);*/
+
+ vl->host[0] = '\0';
+
+ /* Construct the hostname field according to HostnameFormat. */
+ for (i = 0; i < HF_MAX_FIELDS; ++i) {
+ if (hostname_format[i] == hf_none)
+ continue;
+
+ n = DATA_MAX_NAME_LEN - strlen (vl->host) - 2;
+
+ if (i > 0 && n >= 1) {
+ strcat (vl->host, ":");
+ n--;
+ }
+
+ switch (hostname_format[i]) {
+ case hf_none: break;
+ case hf_hostname:
+ strncat (vl->host, hostname_g, n);
+ break;
+ case hf_name:
+ name = virDomainGetName (dom);
+ if (name)
+ strncat (vl->host, name, n);
+ break;
+ case hf_uuid:
+ if (virDomainGetUUIDString (dom, uuid) == 0)
+ strncat (vl->host, uuid, n);
+ break;
+ }
+ }
+
+ vl->host[DATA_MAX_NAME_LEN-1] = '\0';
+}
+
static void
cpu_submit (unsigned long long cpu_time,
time_t t,
- const char *domname, const char *type)
+ virDomainPtr dom, const char *type)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
+ common_submit (&vl, t, dom);
+
values[0].counter = cpu_time;
vl.values = values;
vl.values_len = 1;
- vl.time = t;
- vl.interval = interval_g;
- strncpy (vl.plugin, "libvirtstats", DATA_MAX_NAME_LEN);
- strncpy (vl.host, domname, DATA_MAX_NAME_LEN);
- /*strncpy (vl.type_instance, ?, DATA_MAX_NAME_LEN);*/
plugin_dispatch_values (type, &vl);
}
static void
vcpu_submit (unsigned long long cpu_time,
time_t t,
- const char *domname, int vcpu_nr, const char *type)
+ virDomainPtr dom, int vcpu_nr, const char *type)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
+ common_submit (&vl, t, dom);
+
values[0].counter = cpu_time;
vl.values = values;
vl.values_len = 1;
- vl.time = t;
- vl.interval = interval_g;
- strncpy (vl.plugin, "libvirtstats", DATA_MAX_NAME_LEN);
- strncpy (vl.host, domname, DATA_MAX_NAME_LEN);
snprintf (vl.type_instance, DATA_MAX_NAME_LEN, "%d", vcpu_nr);
+ vl.type_instance[DATA_MAX_NAME_LEN-1] = '\0';
plugin_dispatch_values (type, &vl);
}
static void
disk_submit (long long read, long long write,
time_t t,
- const char *domname, const char *devname,
+ virDomainPtr dom, const char *devname,
const char *type)
{
value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
+ common_submit (&vl, t, dom);
+
values[0].counter = read >= 0 ? (unsigned long long) read : 0;
values[1].counter = write >= 0 ? (unsigned long long) write : 0;
vl.values = values;
vl.values_len = 2;
- vl.time = t;
- vl.interval = interval_g;
- strncpy (vl.plugin, "libvirtstats", DATA_MAX_NAME_LEN);
- strncpy (vl.host, domname, DATA_MAX_NAME_LEN);
strncpy (vl.type_instance, devname, DATA_MAX_NAME_LEN);
+ vl.type_instance[DATA_MAX_NAME_LEN-1] = '\0';
plugin_dispatch_values (type, &vl);
}
static void
if_submit (long long rx, long long tx,
time_t t,
- const char *domname, const char *devname,
+ virDomainPtr dom, const char *devname,
const char *type)
{
value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
+ common_submit (&vl, t, dom);
+
values[0].counter = rx >= 0 ? (unsigned long long) rx : 0;
values[1].counter = tx >= 0 ? (unsigned long long) tx : 0;
vl.values = values;
vl.values_len = 2;
- vl.time = t;
- vl.interval = interval_g;
- strncpy (vl.plugin, "libvirtstats", DATA_MAX_NAME_LEN);
- strncpy (vl.host, domname, DATA_MAX_NAME_LEN);
strncpy (vl.type_instance, devname, DATA_MAX_NAME_LEN);
+ vl.type_instance[DATA_MAX_NAME_LEN-1] = '\0';
plugin_dispatch_values (type, &vl);
}