From 6de03f7b7b23849a3655574910d9e40faba9848a Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Tue, 31 Jul 2018 12:34:17 +0200 Subject: [PATCH] Fixes to metricbeat's KVM module (#7793) Improper error handling caused a panic when connection to libvirtd couldn't be stablished. Cleaned up error handling a little bit. Fixes #7792 The default settings for the kvm module didn't work. Updated to connect to the unix socket by default, and provide a hint on how to setup access to libvirtd running on remote hosts. --- CHANGELOG.asciidoc | 1 + metricbeat/docs/modules/kvm.asciidoc | 5 ++- metricbeat/metricbeat.reference.yml | 5 ++- .../module/kvm/_meta/config.reference.yml | 5 ++- metricbeat/module/kvm/_meta/config.yml | 2 +- .../module/kvm/dommemstat/dommemstat.go | 35 +++++++++++-------- metricbeat/modules.d/kvm.yml.disabled | 2 +- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index d2c75ff3568..b445f78795e 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -42,6 +42,7 @@ https://github.com/elastic/beats/compare/v6.4.0...master[Check the HEAD diff] *Metricbeat* - Fix golang.heap.gc.cpu_fraction type from long to float in Golang module. {pull}7789[7789] +- Fixed a panic when the kvm module cannot establish a connection to libvirtd. {issue}7792[7792]. *Packetbeat* diff --git a/metricbeat/docs/modules/kvm.asciidoc b/metricbeat/docs/modules/kvm.asciidoc index b5acf8877dc..d7418bf75ae 100644 --- a/metricbeat/docs/modules/kvm.asciidoc +++ b/metricbeat/docs/modules/kvm.asciidoc @@ -24,7 +24,10 @@ metricbeat.modules: metricsets: ["dommemstat"] enabled: true period: 10s - hosts: ["localhost"] + hosts: ["unix:///var/run/libvirt/libvirt-sock"] + # For remote hosts, setup network access in libvirtd.conf + # and use the tcp scheme: + # hosts: [ "tcp://:16509" ] # Timeout to connect to Libvirt server #timeout: 1s diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 825c00e916e..eac84d30017 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -423,7 +423,10 @@ metricbeat.modules: metricsets: ["dommemstat"] enabled: true period: 10s - hosts: ["localhost"] + hosts: ["unix:///var/run/libvirt/libvirt-sock"] + # For remote hosts, setup network access in libvirtd.conf + # and use the tcp scheme: + # hosts: [ "tcp://:16509" ] # Timeout to connect to Libvirt server #timeout: 1s diff --git a/metricbeat/module/kvm/_meta/config.reference.yml b/metricbeat/module/kvm/_meta/config.reference.yml index 8d872cbb54e..79f754a52cb 100644 --- a/metricbeat/module/kvm/_meta/config.reference.yml +++ b/metricbeat/module/kvm/_meta/config.reference.yml @@ -2,7 +2,10 @@ metricsets: ["dommemstat"] enabled: true period: 10s - hosts: ["localhost"] + hosts: ["unix:///var/run/libvirt/libvirt-sock"] + # For remote hosts, setup network access in libvirtd.conf + # and use the tcp scheme: + # hosts: [ "tcp://:16509" ] # Timeout to connect to Libvirt server #timeout: 1s diff --git a/metricbeat/module/kvm/_meta/config.yml b/metricbeat/module/kvm/_meta/config.yml index cddd5e78cf8..2df123ca14d 100644 --- a/metricbeat/module/kvm/_meta/config.yml +++ b/metricbeat/module/kvm/_meta/config.yml @@ -2,4 +2,4 @@ #metricsets: # - dommemstat period: 10s - hosts: ["localhost"] + hosts: ["unix:///var/run/libvirt/libvirt-sock"] diff --git a/metricbeat/module/kvm/dommemstat/dommemstat.go b/metricbeat/module/kvm/dommemstat/dommemstat.go index 64fb016ac19..7125ccfedc7 100644 --- a/metricbeat/module/kvm/dommemstat/dommemstat.go +++ b/metricbeat/module/kvm/dommemstat/dommemstat.go @@ -18,17 +18,18 @@ package dommemstat import ( - "errors" "net" "net/url" "time" - "github.com/elastic/beats/libbeat/common" - "github.com/elastic/beats/libbeat/common/cfgwarn" - "github.com/elastic/beats/metricbeat/mb" + "github.com/pkg/errors" "github.com/digitalocean/go-libvirt" "github.com/digitalocean/go-libvirt/libvirttest" + + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/common/cfgwarn" + "github.com/elastic/beats/metricbeat/mb" ) const ( @@ -101,30 +102,40 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) { c, err = net.DialTimeout(u.Scheme, address, m.Timeout) if err != nil { - report.Error(err) + report.Error(errors.Wrapf(err, "cannot connect to %v", u)) + return } } defer c.Close() l := libvirt.New(c) - if err := l.Connect(); err != nil { - report.Error(err) + if err = l.Connect(); err != nil { + report.Error(errors.Wrap(err, "error connecting to libvirtd")) + return } + defer func() { + if err = l.Disconnect(); err != nil { + report.Error(errors.Wrap(err, "failed to disconnect")) + } + }() domains, err := l.Domains() if err != nil { - report.Error(err) + report.Error(errors.Wrap(err, "error listing domains")) + return } for _, d := range domains { gotDomainMemoryStats, err := l.DomainMemoryStats(d, maximumStats, flags) if err != nil { - report.Error(err) + report.Error(errors.Wrapf(err, "error fetching memory stats for domain %s", d.Name)) + continue } if len(gotDomainMemoryStats) == 0 { - report.Error(errors.New("no domain memory stats found")) + report.Error(errors.Errorf("no memory stats for domain %s", d.Name)) + continue } for i := range gotDomainMemoryStats { @@ -140,10 +151,6 @@ func (m *MetricSet) Fetch(report mb.ReporterV2) { }) } } - - if err := l.Disconnect(); err != nil { - report.Error(errors.New("failed to disconnect")) - } } func getDomainMemoryStatName(tag int32) string { diff --git a/metricbeat/modules.d/kvm.yml.disabled b/metricbeat/modules.d/kvm.yml.disabled index 56d087a191a..878e279b969 100644 --- a/metricbeat/modules.d/kvm.yml.disabled +++ b/metricbeat/modules.d/kvm.yml.disabled @@ -5,4 +5,4 @@ #metricsets: # - dommemstat period: 10s - hosts: ["localhost"] + hosts: ["unix:///var/run/libvirt/libvirt-sock"]