diff --git a/CHANGELOG.md b/CHANGELOG.md index f5853ac28..ab0f74448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ changed to just run docker commands in the Makefile. See `make docker-run` and - HAProxy plugin tag has changed from `host` to `server` ### Features +- [#357](https://github.com/influxdb/telegraf/pull/357): Libvirt plugin. Thanks @neckhair! - [#325](https://github.com/influxdb/telegraf/pull/325): NSQ output. Thanks @jrxFive! - [#318](https://github.com/influxdb/telegraf/pull/318): Prometheus output. Thanks @oldmantaiter! - [#338](https://github.com/influxdb/telegraf/pull/338): Restart Telegraf on package upgrade. Thanks @linsomniac! diff --git a/README.md b/README.md index 69378adbb..d6b2adebc 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ Telegraf currently has support for collecting metrics from: * jolokia (remote JMX with JSON over HTTP) * kafka_consumer * leofs +* libvirt * lustre2 * memcached * mongodb diff --git a/plugins/all/all.go b/plugins/all/all.go index 977b980b8..c4fcab7f0 100644 --- a/plugins/all/all.go +++ b/plugins/all/all.go @@ -12,6 +12,7 @@ import ( _ "github.com/influxdb/telegraf/plugins/jolokia" _ "github.com/influxdb/telegraf/plugins/kafka_consumer" _ "github.com/influxdb/telegraf/plugins/leofs" + _ "github.com/influxdb/telegraf/plugins/libvirt" _ "github.com/influxdb/telegraf/plugins/lustre2" _ "github.com/influxdb/telegraf/plugins/memcached" _ "github.com/influxdb/telegraf/plugins/mongodb" diff --git a/plugins/libvirt/README.md b/plugins/libvirt/README.md new file mode 100644 index 000000000..7c1a2e24b --- /dev/null +++ b/plugins/libvirt/README.md @@ -0,0 +1,32 @@ +# Telegraf Plugin: libvirt + +#### Description + +The libvirt plugin collects libvirt statistics. + +To test this plugin set the following configuration: + +```toml +[libvirt] + uri = "test:///default" +``` + +This mocks a libvirt deamon with one running domain. The URI for a connection to a local qemu would be +`qemu:///system`. + +## Resources + +* http://wiki.libvirt.org/page/UbuntuKVMWalkthrough +* http://godoc.org/github.com/alexzorin/libvirt-go + +## Measurements: + +Meta: +- units: int64 +- tags: `domain=vader` + +Measurements names: +- libvirt_cpu_time +- libvirt_max_mem +- libvirt_memory +- libvirt_nr_virt_cpu diff --git a/plugins/libvirt/libvirt.go b/plugins/libvirt/libvirt.go new file mode 100644 index 000000000..d5d6a8d91 --- /dev/null +++ b/plugins/libvirt/libvirt.go @@ -0,0 +1,69 @@ +package libvirt + +import ( + lv "github.com/alexzorin/libvirt-go" + "github.com/influxdb/telegraf/plugins" +) + +const sampleConfig = ` + # specify a libvirt connection uri + uri = "qemu:///system" +` + +type Libvirt struct { + Uri string +} + +func (l *Libvirt) SampleConfig() string { + return sampleConfig +} + +func (l *Libvirt) Description() string { + return "Read domain infos from a libvirt deamon" +} + +func (l *Libvirt) Gather(acc plugins.Accumulator) error { + connection, err := lv.NewVirConnectionReadOnly(l.Uri) + if err != nil { + return err + } + defer connection.CloseConnection() + + domains, err := connection.ListDomains() + if err != nil { + return err + } + + for _, domainId := range domains { + domain, err := connection.LookupDomainById(domainId) + if err != nil { + return err + } + + domainName, _ := domain.GetName() + tags := map[string]string{"domain": domainName} + l.gatherDomain(acc, domain, tags) + } + + return nil +} + +func (m *Libvirt) gatherDomain(acc plugins.Accumulator, domain lv.VirDomain, tags map[string]string) error { + domainInfo, err := domain.GetInfo() + if err != nil { + return err + } + + acc.Add("cpu_time", domainInfo.GetCpuTime(), tags) + acc.Add("max_mem", domainInfo.GetMaxMem(), tags) + acc.Add("memory", domainInfo.GetMemory(), tags) + acc.Add("nr_virt_cpu", domainInfo.GetNrVirtCpu(), tags) + + return nil +} + +func init() { + plugins.Add("libvirt", func() plugins.Plugin { + return &Libvirt{} + }) +} diff --git a/plugins/libvirt/libvirt_test.go b/plugins/libvirt/libvirt_test.go new file mode 100644 index 000000000..4cc06d665 --- /dev/null +++ b/plugins/libvirt/libvirt_test.go @@ -0,0 +1,23 @@ +package libvirt + +import ( + "testing" + + "github.com/influxdb/telegraf/testutil" + "github.com/stretchr/testify/assert" +) + +func TestLibvirt(t *testing.T) { + var acc testutil.Accumulator + + l := &Libvirt{Uri: "test:///default"} + l.Gather(&acc) + + assert.True(t, acc.HasUIntValue("cpu_time")) + assert.True(t, acc.HasUIntValue("memory")) + assert.True(t, acc.HasUIntValue("max_mem")) + + expectedTags := map[string]string{"domain": "test"} + expectedNumberOfCpus := uint16(2) + assert.NoError(t, acc.ValidateTaggedValue("nr_virt_cpu", expectedNumberOfCpus, expectedTags)) +}