Use single connection, reconnect if it fails

Change-Id: I772ee98d55e8d6b64551a7d8f4157e387fe4f4f4
This commit is contained in:
Mohammed Naser 2020-08-11 07:28:11 -04:00 committed by okozachenko
parent c126e6c26c
commit 5f09608a4a
3 changed files with 51 additions and 32 deletions

View File

@ -27,7 +27,7 @@ import (
type DomainStatsCollector struct { type DomainStatsCollector struct {
prometheus.Collector prometheus.Collector
LibvirtURI string Connection *libvirt.Connect
Nova bool Nova bool
@ -86,9 +86,9 @@ type NovaMetadata struct {
} }
// nolint:funlen // nolint:funlen
func NewDomainStatsCollector(nova bool, libvirtURI string) (*DomainStatsCollector, error) { func NewDomainStatsCollector(nova bool, connection *libvirt.Connect) (*DomainStatsCollector, error) {
return &DomainStatsCollector{ return &DomainStatsCollector{
LibvirtURI: libvirtURI, Connection: connection,
Nova: nova, Nova: nova,
DomainSeconds: prometheus.NewDesc( DomainSeconds: prometheus.NewDesc(
@ -308,26 +308,32 @@ func (c *DomainStatsCollector) describeBlock(ch chan<- *prometheus.Desc) {
} }
func (c *DomainStatsCollector) Collect(ch chan<- prometheus.Metric) { func (c *DomainStatsCollector) Collect(ch chan<- prometheus.Metric) {
conn, err := libvirt.NewConnect(c.LibvirtURI) alive, err := c.Connection.IsAlive()
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return
} }
defer func() {
alive, err := conn.IsAlive() if !alive {
uri, err := c.Connection.GetURI()
if err != nil {
// NOTE(mnaser): If we get to this point, we don't have
// a URI and we can't reconnect, die
log.Fatalln(err)
return
}
c.Connection.Close()
conn, err := libvirt.NewConnect(uri)
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return
} }
if alive { c.Connection = conn
_, err := conn.Close() }
if err != nil {
log.Errorln(err)
}
}
}()
stats, err := conn.GetAllDomainStats( stats, err := c.Connection.GetAllDomainStats(
[]*libvirt.Domain{}, []*libvirt.Domain{},
libvirt.DOMAIN_STATS_STATE|libvirt.DOMAIN_STATS_CPU_TOTAL|libvirt.DOMAIN_STATS_BALLOON| libvirt.DOMAIN_STATS_STATE|libvirt.DOMAIN_STATS_CPU_TOTAL|libvirt.DOMAIN_STATS_BALLOON|
libvirt.DOMAIN_STATS_VCPU|libvirt.DOMAIN_STATS_INTERFACE|libvirt.DOMAIN_STATS_BLOCK, libvirt.DOMAIN_STATS_VCPU|libvirt.DOMAIN_STATS_INTERFACE|libvirt.DOMAIN_STATS_BLOCK,

View File

@ -25,14 +25,14 @@ import (
type VersionCollector struct { type VersionCollector struct {
prometheus.Collector prometheus.Collector
LibvirtURI string Connection *libvirt.Connect
Version *prometheus.Desc Version *prometheus.Desc
} }
func NewVersionCollector(libvirtURI string) (*VersionCollector, error) { func NewVersionCollector(connection *libvirt.Connect) (*VersionCollector, error) {
return &VersionCollector{ return &VersionCollector{
LibvirtURI: libvirtURI, Connection: connection,
Version: prometheus.NewDesc( Version: prometheus.NewDesc(
"libvirtd_info", "libvirtd_info",
@ -47,38 +47,44 @@ func (c *VersionCollector) Describe(ch chan<- *prometheus.Desc) {
} }
func (c *VersionCollector) Collect(ch chan<- prometheus.Metric) { func (c *VersionCollector) Collect(ch chan<- prometheus.Metric) {
conn, err := libvirt.NewConnect(c.LibvirtURI) alive, err := c.Connection.IsAlive()
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return
} }
defer func() {
alive, err := conn.IsAlive() if !alive {
uri, err := c.Connection.GetURI()
if err != nil {
// NOTE(mnaser): If we get to this point, we don't have
// a URI and we can't reconnect, die
log.Fatalln(err)
return
}
c.Connection.Close()
conn, err := libvirt.NewConnect(uri)
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return
} }
if alive { c.Connection = conn
_, err := conn.Close() }
if err != nil {
log.Errorln(err)
}
}
}()
hypervisorType, err := conn.GetType() hypervisorType, err := c.Connection.GetType()
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return
} }
hypervisorVersion, err := conn.GetVersion() hypervisorVersion, err := c.Connection.GetVersion()
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return
} }
libvirtVersion, err := conn.GetLibVersion() libvirtVersion, err := c.Connection.GetLibVersion()
if err != nil { if err != nil {
log.Errorln(err) log.Errorln(err)
return return

View File

@ -17,6 +17,7 @@ package main
import ( import (
"net/http" "net/http"
"github.com/libvirt/libvirt-go"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/log" "github.com/prometheus/common/log"
@ -50,12 +51,18 @@ func main() {
kingpin.HelpFlag.Short('h') kingpin.HelpFlag.Short('h')
kingpin.Parse() kingpin.Parse()
versionCollector, err := collectors.NewVersionCollector(*libvirtURI) conn, err := libvirt.NewConnect(*libvirtURI)
if err != nil {
log.Fatalln(err)
return
}
versionCollector, err := collectors.NewVersionCollector(conn)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
domainStats, err := collectors.NewDomainStatsCollector(*libvirtNova, *libvirtURI) domainStats, err := collectors.NewDomainStatsCollector(*libvirtNova, conn)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }