From 19d909fb50e83196227f65fb6831c95ad7fe282a 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. (cherry picked from commit 76d394951ec3aeb25662c0127c85d2c6c3f37c2c) --- 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 1fa9ac9d6c4f..82b4d7e04388 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -81,6 +81,7 @@ https://github.com/elastic/beats/compare/v6.4.0...6.x[Check the HEAD diff] - Fix issue that would prevent kafka module to find a proper broker when port is not set {pull}8613[8613] - Fix range colors in multiple visualizations. {issue}8633[8633] {pull}8634[8634] - Fix incorrect header parsing on http metricbeat module {issue}8564[8564] {pull}8585[8585] +- 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 05f235344ad3..0f2fbdef32f6 100644 --- a/metricbeat/docs/modules/kvm.asciidoc +++ b/metricbeat/docs/modules/kvm.asciidoc @@ -23,7 +23,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 eecbe3581abe..cddddfeca513 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -426,7 +426,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 8d872cbb54e6..79f754a52cb2 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 cddd5e78cf8f..2df123ca14dc 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 64fb016ac19f..7125ccfedc72 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 6c29927b49ac..67091c0fc04b 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"]