diff --git a/CHANGELOG.md b/CHANGELOG.md index 1674f72..29b5208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Add libvirt_versions_info metric. ## [2.1.0] - 2021-04-12 ### Added diff --git a/README.md b/README.md index 42fbd77..cef1ab1 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ libvirt_domain_memory_stats_unused_bytes{domain="..."} libvirt_domain_memory_stats_usable_bytes{domain="..."} libvirt_domain_memory_stats_used_percent{domain="..."} +libvirt_versions_info{hypervisor_running="...",libvirtd_running="...",libvirt_library="..."} libvirt_up ``` diff --git a/go.mod b/go.mod index bc9f5e1..a7f892a 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,6 @@ go 1.12 require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect github.com/prometheus/client_golang v1.1.0 gopkg.in/alecthomas/kingpin.v2 v2.2.6 libvirt.org/libvirt-go v7.2.0+incompatible diff --git a/libvirt_exporter.go b/libvirt_exporter.go index e7f9043..b838404 100644 --- a/libvirt_exporter.go +++ b/libvirt_exporter.go @@ -18,15 +18,17 @@ package main import ( "encoding/xml" + "fmt" + "log" + "net/http" + "os" + "strconv" + "github.com/AlexZzz/libvirt-exporter/libvirtSchema" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "gopkg.in/alecthomas/kingpin.v2" "libvirt.org/libvirt-go" - "log" - "net/http" - "os" - "strconv" ) var ( @@ -35,7 +37,11 @@ var ( "Whether scraping libvirt's metrics was successful.", nil, nil) - + libvirtVersionsInfoDesc = prometheus.NewDesc( + prometheus.BuildFQName("libvirt", "", "versions_info"), + "Versions of virtualization components", + []string{"hypervisor_running", "libvirtd_running", "libvirt_library"}, + nil) libvirtDomainInfoMetaDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "meta"), "Domain metadata", @@ -667,6 +673,32 @@ func CollectFromLibvirt(ch chan<- prometheus.Metric, uri string) error { } defer conn.Close() + hypervisorVersionNum, err := conn.GetVersion() // virConnectGetVersion, hypervisor running, e.g. QEMU + if err != nil { + return err + } + hypervisorVersion := fmt.Sprintf("%d.%d.%d", hypervisorVersionNum/1000000%1000, hypervisorVersionNum/1000%1000, hypervisorVersionNum%1000) + + libvirtdVersionNum, err := conn.GetLibVersion() // virConnectGetLibVersion, libvirt daemon running + if err != nil { + return err + } + libvirtdVersion := fmt.Sprintf("%d.%d.%d", libvirtdVersionNum/1000000%1000, libvirtdVersionNum/1000%1000, libvirtdVersionNum%1000) + + libraryVersionNum, err := libvirt.GetVersion() // virGetVersion, version of libvirt (dynamic) library used by this binary (exporter), not the daemon version + if err != nil { + return err + } + libraryVersion := fmt.Sprintf("%d.%d.%d", libraryVersionNum/1000000%1000, libraryVersionNum/1000%1000, libraryVersionNum%1000) + + ch <- prometheus.MustNewConstMetric( + libvirtVersionsInfoDesc, + prometheus.GaugeValue, + 1.0, + hypervisorVersion, + libvirtdVersion, + libraryVersion) + stats, err := conn.GetAllDomainStats([]*libvirt.Domain{}, libvirt.DOMAIN_STATS_STATE|libvirt.DOMAIN_STATS_CPU_TOTAL| libvirt.DOMAIN_STATS_INTERFACE|libvirt.DOMAIN_STATS_BALLOON|libvirt.DOMAIN_STATS_BLOCK| libvirt.DOMAIN_STATS_PERF|libvirt.DOMAIN_STATS_VCPU, @@ -728,8 +760,9 @@ func NewLibvirtExporter(uri string) (*LibvirtExporter, error) { // Describe returns metadata for all Prometheus metrics that may be exported. func (e *LibvirtExporter) Describe(ch chan<- *prometheus.Desc) { - // Status + // Status and versions ch <- libvirtUpDesc + ch <- libvirtVersionsInfoDesc // Domain info ch <- libvirtDomainInfoMetaDesc