From 62b2f6bffc5dad6fcb26af9bf64af7b08cd51979 Mon Sep 17 00:00:00 2001 From: Maksim Kiselev Date: Sun, 5 Jun 2022 13:33:23 +0300 Subject: [PATCH 1/2] Export node total CPUs, total memory. And node name as metric label --- libvirt_exporter.go | 235 +++++++++++++++++++++++++++++++------------- 1 file changed, 167 insertions(+), 68 deletions(-) diff --git a/libvirt_exporter.go b/libvirt_exporter.go index fb3bd27..53466ae 100644 --- a/libvirt_exporter.go +++ b/libvirt_exporter.go @@ -40,63 +40,73 @@ var ( "Whether scraping libvirt's metrics was successful.", nil, nil) + libvirtNodeCpu = prometheus.NewDesc( + prometheus.BuildFQName("libvirt", "", "node_cpu"), + "Number of CPUs on node.", + []string{"host"}, + nil) + libvirtNodeMemory = prometheus.NewDesc( + prometheus.BuildFQName("libvirt", "", "node_memory_bytes"), + "Total memory on node.", + []string{"host"}, + nil) libvirtPoolInfoCapacity = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "pool_info", "capacity_bytes"), "Pool capacity, in bytes", - []string{"pool"}, + []string{"host", "pool"}, nil) libvirtPoolInfoAllocation = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "pool_info", "allocation_bytes"), "Pool allocation, in bytes", - []string{"pool"}, + []string{"host", "pool"}, nil) libvirtPoolInfoAvailable = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "pool_info", "available_bytes"), "Pool available, in bytes", - []string{"pool"}, + []string{"host", "pool"}, nil) libvirtVersionsInfoDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "", "versions_info"), "Versions of virtualization components", - []string{"hypervisor_running", "libvirtd_running", "libvirt_library"}, + []string{"host","hypervisor_running", "libvirtd_running", "libvirt_library"}, nil) libvirtDomainInfoMetaDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "meta"), "Domain metadata", - []string{"domain", "uuid", "instance_name", "flavor", "user_name", "user_uuid", "project_name", "project_uuid", "root_type", "root_uuid"}, + []string{"host", "domain", "uuid", "instance_name", "flavor", "user_name", "user_uuid", "project_name", "project_uuid", "root_type", "root_uuid"}, nil) libvirtDomainInfoMaxMemBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "maximum_memory_bytes"), "Maximum allowed memory of the domain, in bytes.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainInfoMemoryUsageBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "memory_usage_bytes"), "Memory usage of the domain, in bytes.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainInfoNrVirtCPUDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "virtual_cpus"), "Number of virtual CPUs for the domain.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainInfoCPUTimeDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "cpu_time_seconds_total"), "Amount of CPU time used by the domain, in seconds.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainInfoVirDomainState = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_info", "vstate"), "Virtual domain state. 0: no state, 1: the domain is running, 2: the domain is blocked on resource,"+ " 3: the domain is paused by user, 4: the domain is being shut down, 5: the domain is shut off,"+ "6: the domain is crashed, 7: the domain is suspended by guest power management", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainVcpuTimeDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_vcpu", "time_seconds_total"), "Amount of CPU time used by the domain's VCPU, in seconds.", - []string{"domain", "vcpu"}, + []string{"host", "domain", "vcpu"}, nil) libvirtDomainVcpuDelayDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_vcpu", "delay_seconds_total"), @@ -104,83 +114,83 @@ var ( "Vcpu's delay metric. Time the vcpu thread was enqueued by the "+ "host scheduler, but was waiting in the queue instead of running. "+ "Exposed to the VM as a steal time.", - []string{"domain", "vcpu"}, + []string{"host", "domain", "vcpu"}, nil) libvirtDomainVcpuStateDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_vcpu", "state"), "VCPU state. 0: offline, 1: running, 2: blocked", - []string{"domain", "vcpu"}, + []string{"host", "domain", "vcpu"}, nil) libvirtDomainVcpuCPUDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_vcpu", "cpu"), "Real CPU number, or one of the values from virVcpuHostCpuState", - []string{"domain", "vcpu"}, + []string{"host", "domain", "vcpu"}, nil) libvirtDomainVcpuWaitDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_vcpu", "wait_seconds_total"), "Vcpu's wait_sum metric. CONFIG_SCHEDSTATS has to be enabled", - []string{"domain", "vcpu"}, + []string{"host", "domain", "vcpu"}, nil) libvirtDomainMetaBlockDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block", "meta"), "Block device metadata info. Device name, source file, serial.", - []string{"domain", "target_device", "source_file", "serial", "bus", "disk_type", "driver_type", "cache", "discard"}, + []string{"host", "domain", "target_device", "source_file", "serial", "bus", "disk_type", "driver_type", "cache", "discard"}, nil) libvirtDomainBlockRdBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "read_bytes_total"), "Number of bytes read from a block device, in bytes.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockRdReqDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "read_requests_total"), "Number of read requests from a block device.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockRdTotalTimeSecondsDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "read_time_seconds_total"), "Total time spent on reads from a block device, in seconds.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWrBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "write_bytes_total"), "Number of bytes written to a block device, in bytes.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWrReqDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "write_requests_total"), "Number of write requests to a block device.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWrTotalTimesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "write_time_seconds_total"), "Total time spent on writes on a block device, in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockFlushReqDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "flush_requests_total"), "Total flush requests from a block device.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockFlushTotalTimeSecondsDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "flush_time_seconds_total"), "Total time in seconds spent on cache flushing to a block device", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockAllocationDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "allocation"), "Offset of the highest written sector on a block device.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockCapacityBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "capacity_bytes"), "Logical size in bytes of the block device backing image.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockPhysicalSizeBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "physicalsize_bytes"), "Physical size in bytes of the container of the backing image.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) // Block IO tune parameters @@ -188,197 +198,197 @@ var ( libvirtDomainBlockTotalBytesSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_total_bytes"), "Total throughput limit in bytes per second", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWriteBytesSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_write_bytes"), "Write throughput limit in bytes per second", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockReadBytesSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_read_bytes"), "Read throughput limit in bytes per second", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockTotalIopsSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_total_requests"), "Total requests per second limit", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWriteIopsSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_write_requests"), "Write requests per second limit", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockReadIopsSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_read_requests"), "Read requests per second limit", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) // Burst limits libvirtDomainBlockTotalBytesSecMaxDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_total_bytes"), "Total throughput burst limit in bytes per second", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWriteBytesSecMaxDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_write_bytes"), "Write throughput burst limit in bytes per second", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockReadBytesSecMaxDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_read_bytes"), "Read throughput burst limit in bytes per second", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockTotalIopsSecMaxDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_total_requests"), "Total requests per second burst limit", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWriteIopsSecMaxDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_write_requests"), "Write requests per second burst limit", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockReadIopsSecMaxDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_read_requests"), "Read requests per second burst limit", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockTotalBytesSecMaxLengthDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_total_bytes_length_seconds"), "Total throughput burst time in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWriteBytesSecMaxLengthDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_write_bytes_length_seconds"), "Write throughput burst time in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockReadBytesSecMaxLengthDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_read_bytes_length_seconds"), "Read throughput burst time in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockTotalIopsSecMaxLengthDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_length_total_requests_seconds"), "Total requests per second burst time in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockWriteIopsSecMaxLengthDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_length_write_requests_seconds"), "Write requests per second burst time in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockReadIopsSecMaxLengthDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "limit_burst_length_read_requests_seconds"), "Read requests per second burst time in seconds", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainBlockSizeIopsSecDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_block_stats", "size_iops_bytes"), "The size of IO operations per second permitted through a block device", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainMetaInterfacesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface", "meta"), "Interfaces metadata. Source bridge, target device, interface uuid", - []string{"domain", "source_bridge", "target_device", "virtual_interface"}, + []string{"host", "domain", "source_bridge", "target_device", "virtual_interface"}, nil) libvirtDomainInterfaceRxBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "receive_bytes_total"), "Number of bytes received on a network interface, in bytes.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceRxPacketsDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "receive_packets_total"), "Number of packets received on a network interface.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceRxErrsDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "receive_errors_total"), "Number of packet receive errors on a network interface.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceRxDropDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "receive_drops_total"), "Number of packet receive drops on a network interface.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceTxBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "transmit_bytes_total"), "Number of bytes transmitted on a network interface, in bytes.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceTxPacketsDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "transmit_packets_total"), "Number of packets transmitted on a network interface.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceTxErrsDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "transmit_errors_total"), "Number of packet transmit errors on a network interface.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainInterfaceTxDropDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_interface_stats", "transmit_drops_total"), "Number of packet transmit drops on a network interface.", - []string{"domain", "target_device"}, + []string{"host", "domain", "target_device"}, nil) libvirtDomainMemoryStatMajorFaultTotalDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "major_fault_total"), "Page faults occur when a process makes a valid access to virtual memory that is not available. "+ "When servicing the page fault, if disk IO is required, it is considered a major fault.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatMinorFaultTotalDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "minor_fault_total"), "Page faults occur when a process makes a valid access to virtual memory that is not available. "+ "When servicing the page not fault, if disk IO is required, it is considered a minor fault.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatUnusedBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "unused_bytes"), "The amount of memory left completely unused by the system. Memory that is available but used for "+ "reclaimable caches should NOT be reported as free. This value is expressed in bytes.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatAvailableBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "available_bytes"), "The total amount of usable memory as seen by the domain. This value may be less than the amount of "+ "memory assigned to the domain if a balloon driver is in use or if the guest OS does not initialize all "+ "assigned pages. This value is expressed in bytes.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatActualBaloonBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "actual_balloon_bytes"), "Current balloon value (in bytes).", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatRssBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "rss_bytes"), "Resident Set Size of the process running the domain. This value is in bytes", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatUsableBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "usable_bytes"), "How much the balloon can be inflated without pushing the guest system to swap, corresponds "+ "to 'Available' in /proc/meminfo", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatDiskCachesBytesDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "disk_cache_bytes"), "The amount of memory, that can be quickly reclaimed without additional I/O (in bytes)."+ "Typically these pages are used for caching files from disk.", - []string{"domain"}, + []string{"host", "domain"}, nil) libvirtDomainMemoryStatUsedPercentDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_memory_stats", "used_percent"), "The amount of memory in percent, that used by domain.", - []string{"domain"}, + []string{"host", "domain"}, nil) errorsMap map[string]struct{} @@ -396,7 +406,7 @@ func WriteErrorOnce(err string, name string) { } // CollectDomain extracts Prometheus metrics from a libvirt domain. -func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error { +func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats, hostName string) error { domainName, err := stat.Domain.GetName() if err != nil { return err @@ -423,10 +433,12 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error if err != nil { return err } + ch <- prometheus.MustNewConstMetric( libvirtDomainInfoMetaDesc, prometheus.GaugeValue, float64(1), + hostName, domainName, domainUUID, desc.Metadata.NovaInstance.NovaName, @@ -441,26 +453,31 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInfoMaxMemBytesDesc, prometheus.GaugeValue, float64(info.MaxMem)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainInfoMemoryUsageBytesDesc, prometheus.GaugeValue, float64(info.Memory)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainInfoNrVirtCPUDesc, prometheus.GaugeValue, float64(info.NrVirtCpu), + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainInfoCPUTimeDesc, prometheus.CounterValue, float64(info.CpuTime)/1000/1000/1000, // From nsec to sec + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainInfoVirDomainState, prometheus.GaugeValue, float64(info.State), + hostName, domainName) domainStatsVcpu, err := stat.Domain.GetVcpus() @@ -475,6 +492,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainVcpuStateDesc, prometheus.GaugeValue, float64(vcpu.State), + hostName, domainName, strconv.FormatInt(int64(vcpu.Number), 10)) @@ -482,6 +500,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainVcpuTimeDesc, prometheus.CounterValue, float64(vcpu.CpuTime)/1000/1000/1000, // From nsec to sec + hostName, domainName, strconv.FormatInt(int64(vcpu.Number), 10)) @@ -489,6 +508,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainVcpuCPUDesc, prometheus.GaugeValue, float64(vcpu.Cpu), + hostName, domainName, strconv.FormatInt(int64(vcpu.Number), 10)) } @@ -503,6 +523,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainVcpuWaitDesc, prometheus.CounterValue, float64(vcpu.Wait)/1000/1000/1000, + hostName, domainName, strconv.FormatInt(int64(cpuNum), 10)) } @@ -511,6 +532,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainVcpuDelayDesc, prometheus.CounterValue, float64(vcpu.Delay)/1e9, + hostName, domainName, strconv.FormatInt(int64(cpuNum), 10)) } @@ -546,6 +568,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainMetaBlockDesc, prometheus.GaugeValue, float64(1), + hostName, domainName, disk.Name, DiskSource, @@ -563,6 +586,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockRdBytesDesc, prometheus.CounterValue, float64(disk.RdBytes), + hostName, domainName, disk.Name) } @@ -571,6 +595,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockRdReqDesc, prometheus.CounterValue, float64(disk.RdReqs), + hostName, domainName, disk.Name) } @@ -579,6 +604,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockRdTotalTimeSecondsDesc, prometheus.CounterValue, float64(disk.RdTimes)/1e9, + hostName, domainName, disk.Name) } @@ -587,6 +613,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWrBytesDesc, prometheus.CounterValue, float64(disk.WrBytes), + hostName, domainName, disk.Name) } @@ -595,6 +622,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWrReqDesc, prometheus.CounterValue, float64(disk.WrReqs), + hostName, domainName, disk.Name) } @@ -603,6 +631,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWrTotalTimesDesc, prometheus.CounterValue, float64(disk.WrTimes)/1e9, + hostName, domainName, disk.Name) } @@ -611,6 +640,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockFlushReqDesc, prometheus.CounterValue, float64(disk.FlReqs), + hostName, domainName, disk.Name) } @@ -619,6 +649,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockFlushTotalTimeSecondsDesc, prometheus.CounterValue, float64(disk.FlTimes)/1e9, + hostName, domainName, disk.Name) } @@ -627,6 +658,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockAllocationDesc, prometheus.GaugeValue, float64(disk.Allocation), + hostName, domainName, disk.Name) } @@ -635,6 +667,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockCapacityBytesDesc, prometheus.GaugeValue, float64(disk.Capacity), + hostName, domainName, disk.Name) } @@ -643,6 +676,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockPhysicalSizeBytesDesc, prometheus.GaugeValue, float64(disk.Physical), + hostName, domainName, disk.Name) } @@ -667,6 +701,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockTotalBytesSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.TotalBytesSec), + hostName, domainName, disk.Name) } @@ -675,6 +710,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockReadBytesSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.ReadBytesSec), + hostName, domainName, disk.Name) } @@ -683,6 +719,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWriteBytesSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.WriteBytesSec), + hostName, domainName, disk.Name) } @@ -691,6 +728,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockTotalIopsSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.TotalIopsSec), + hostName, domainName, disk.Name) } @@ -699,6 +737,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockReadIopsSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.ReadIopsSec), + hostName, domainName, disk.Name) } @@ -707,6 +746,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWriteIopsSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.WriteIopsSec), + hostName, domainName, disk.Name) } @@ -715,6 +755,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockTotalBytesSecMaxDesc, prometheus.GaugeValue, float64(blockIOTuneParams.TotalBytesSecMax), + hostName, domainName, disk.Name) } @@ -723,6 +764,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockReadBytesSecMaxDesc, prometheus.GaugeValue, float64(blockIOTuneParams.ReadBytesSecMax), + hostName, domainName, disk.Name) } @@ -731,6 +773,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWriteBytesSecMaxDesc, prometheus.GaugeValue, float64(blockIOTuneParams.WriteBytesSecMax), + hostName, domainName, disk.Name) } @@ -739,6 +782,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockTotalIopsSecMaxDesc, prometheus.GaugeValue, float64(blockIOTuneParams.TotalIopsSecMax), + hostName, domainName, disk.Name) } @@ -747,6 +791,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockReadIopsSecMaxDesc, prometheus.GaugeValue, float64(blockIOTuneParams.ReadIopsSecMax), + hostName, domainName, disk.Name) } @@ -755,6 +800,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWriteIopsSecMaxDesc, prometheus.GaugeValue, float64(blockIOTuneParams.WriteIopsSecMax), + hostName, domainName, disk.Name) } @@ -763,6 +809,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockTotalBytesSecMaxLengthDesc, prometheus.GaugeValue, float64(blockIOTuneParams.TotalBytesSecMaxLength), + hostName, domainName, disk.Name) } @@ -771,6 +818,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockReadBytesSecMaxLengthDesc, prometheus.GaugeValue, float64(blockIOTuneParams.ReadBytesSecMaxLength), + hostName, domainName, disk.Name) } @@ -779,6 +827,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWriteBytesSecMaxLengthDesc, prometheus.GaugeValue, float64(blockIOTuneParams.WriteBytesSecMaxLength), + hostName, domainName, disk.Name) } @@ -787,6 +836,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockTotalIopsSecMaxLengthDesc, prometheus.GaugeValue, float64(blockIOTuneParams.TotalIopsSecMaxLength), + hostName, domainName, disk.Name) } @@ -795,6 +845,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockReadIopsSecMaxLengthDesc, prometheus.GaugeValue, float64(blockIOTuneParams.ReadIopsSecMaxLength), + hostName, domainName, disk.Name) } @@ -803,6 +854,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockWriteIopsSecMaxLengthDesc, prometheus.GaugeValue, float64(blockIOTuneParams.WriteIopsSecMaxLength), + hostName, domainName, disk.Name) } @@ -811,6 +863,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainBlockSizeIopsSecDesc, prometheus.GaugeValue, float64(blockIOTuneParams.SizeIopsSec), + hostName, domainName, disk.Name) } @@ -834,6 +887,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainMetaInterfacesDesc, prometheus.GaugeValue, float64(1), + hostName, domainName, SourceBridge, iface.Name, @@ -844,6 +898,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceRxBytesDesc, prometheus.CounterValue, float64(iface.RxBytes), + hostName, domainName, iface.Name) } @@ -852,6 +907,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceRxPacketsDesc, prometheus.CounterValue, float64(iface.RxPkts), + hostName, domainName, iface.Name) } @@ -860,6 +916,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceRxErrsDesc, prometheus.CounterValue, float64(iface.RxErrs), + hostName, domainName, iface.Name) } @@ -868,6 +925,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceRxDropDesc, prometheus.CounterValue, float64(iface.RxDrop), + hostName, domainName, iface.Name) } @@ -876,6 +934,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceTxBytesDesc, prometheus.CounterValue, float64(iface.TxBytes), + hostName, domainName, iface.Name) } @@ -884,6 +943,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceTxPacketsDesc, prometheus.CounterValue, float64(iface.TxPkts), + hostName, domainName, iface.Name) } @@ -892,6 +952,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceTxErrsDesc, prometheus.CounterValue, float64(iface.TxErrs), + hostName, domainName, iface.Name) } @@ -900,6 +961,7 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainInterfaceTxDropDesc, prometheus.CounterValue, float64(iface.TxDrop), + hostName, domainName, iface.Name) } @@ -920,53 +982,62 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats) error libvirtDomainMemoryStatMajorFaultTotalDesc, prometheus.CounterValue, float64(MemoryStats.MajorFault), + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatMinorFaultTotalDesc, prometheus.CounterValue, float64(MemoryStats.MinorFault), + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatUnusedBytesDesc, prometheus.GaugeValue, float64(MemoryStats.Unused)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatAvailableBytesDesc, prometheus.GaugeValue, float64(MemoryStats.Available)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatActualBaloonBytesDesc, prometheus.GaugeValue, float64(MemoryStats.ActualBalloon)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatRssBytesDesc, prometheus.GaugeValue, float64(MemoryStats.Rss)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatUsableBytesDesc, prometheus.GaugeValue, float64(MemoryStats.Usable)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatDiskCachesBytesDesc, prometheus.GaugeValue, float64(MemoryStats.DiskCaches)*1024, + hostName, domainName) ch <- prometheus.MustNewConstMetric( libvirtDomainMemoryStatUsedPercentDesc, prometheus.GaugeValue, float64(usedPercent), + hostName, domainName) return nil } // Collect Storage pool stats -func CollectStoragePool(ch chan<- prometheus.Metric, pool libvirt.StoragePool) error { +func CollectStoragePool(ch chan<- prometheus.Metric, pool libvirt.StoragePool, hostName string) error { // Refresh pool err := pool.Refresh(0) if err != nil { @@ -985,16 +1056,19 @@ func CollectStoragePool(ch chan<- prometheus.Metric, pool libvirt.StoragePool) e libvirtPoolInfoCapacity, prometheus.GaugeValue, float64(pool_info.Capacity), + hostName, pool_name) ch <- prometheus.MustNewConstMetric( libvirtPoolInfoAllocation, prometheus.GaugeValue, float64(pool_info.Allocation), + hostName, pool_name) ch <- prometheus.MustNewConstMetric( libvirtPoolInfoAvailable, prometheus.GaugeValue, float64(pool_info.Available), + hostName, pool_name) return nil } @@ -1026,10 +1100,33 @@ func CollectFromLibvirt(ch chan<- prometheus.Metric, uri string) error { } libraryVersion := fmt.Sprintf("%d.%d.%d", libraryVersionNum/1000000%1000, libraryVersionNum/1000%1000, libraryVersionNum%1000) + hostName, err := conn.GetHostname(); + if err != nil { + return err + } + + nodeInfo, err := conn.GetNodeInfo(); + if err != nil { + return err + } + + ch <- prometheus.MustNewConstMetric( + libvirtNodeCpu, + prometheus.GaugeValue, + float64(nodeInfo.GetMaxCPUs()), + hostName) + + ch <- prometheus.MustNewConstMetric( + libvirtNodeMemory, + prometheus.GaugeValue, + float64(nodeInfo.Memory * 1024), + hostName) + ch <- prometheus.MustNewConstMetric( libvirtVersionsInfoDesc, prometheus.GaugeValue, 1.0, + hostName, hypervisorVersion, libvirtdVersion, libraryVersion) @@ -1048,7 +1145,7 @@ func CollectFromLibvirt(ch chan<- prometheus.Metric, uri string) error { return err } for _, stat := range stats { - err = CollectDomain(ch, stat) + err = CollectDomain(ch, stat, hostName) if err != nil { log.Printf("Failed to scrape metrics: %s", err) } @@ -1060,7 +1157,7 @@ func CollectFromLibvirt(ch chan<- prometheus.Metric, uri string) error { return err } for _, pool := range pools { - err = CollectStoragePool(ch, pool) + err = CollectStoragePool(ch, pool, hostName) pool.Free() if err != nil { return err @@ -1111,6 +1208,8 @@ func (e *LibvirtExporter) Describe(ch chan<- *prometheus.Desc) { // Status and versions ch <- libvirtUpDesc ch <- libvirtVersionsInfoDesc + ch <- libvirtNodeCpu + ch <- libvirtNodeMemory // Pool info ch <- libvirtPoolInfoCapacity From 5c66e30ac2d6dd3deba6fff02021f603d98b4857 Mon Sep 17 00:00:00 2001 From: Maksim Kiselev Date: Tue, 14 Jun 2022 20:11:38 +0300 Subject: [PATCH 2/2] Export domain autostart --- libvirt_exporter.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/libvirt_exporter.go b/libvirt_exporter.go index 53466ae..6fe6148 100644 --- a/libvirt_exporter.go +++ b/libvirt_exporter.go @@ -102,6 +102,12 @@ var ( "6: the domain is crashed, 7: the domain is suspended by guest power management", []string{"host", "domain"}, nil) + libvirtDomainInfoAutoStart = prometheus.NewDesc( + prometheus.BuildFQName("libvirt", "domain_info", "autostart_enabled"), + "Is autostart enabled for domain.", + []string{"host", "domain"}, + nil) + libvirtDomainVcpuTimeDesc = prometheus.NewDesc( prometheus.BuildFQName("libvirt", "domain_vcpu", "time_seconds_total"), @@ -434,6 +440,16 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats, hostNa return err } + // Report domain autostart. + autostart, err := stat.Domain.GetAutostart() + if err != nil { + return err + } + autostart_int := 0 + if autostart { + autostart_int = 1 + } + ch <- prometheus.MustNewConstMetric( libvirtDomainInfoMetaDesc, prometheus.GaugeValue, @@ -479,6 +495,12 @@ func CollectDomain(ch chan<- prometheus.Metric, stat libvirt.DomainStats, hostNa float64(info.State), hostName, domainName) + ch <- prometheus.MustNewConstMetric( + libvirtDomainInfoAutoStart, + prometheus.GaugeValue, + float64(autostart_int), + hostName, + domainName) domainStatsVcpu, err := stat.Domain.GetVcpus() if err != nil { @@ -1223,6 +1245,7 @@ func (e *LibvirtExporter) Describe(ch chan<- *prometheus.Desc) { ch <- libvirtDomainInfoNrVirtCPUDesc ch <- libvirtDomainInfoCPUTimeDesc ch <- libvirtDomainInfoVirDomainState + ch <- libvirtDomainInfoAutoStart // VCPU info ch <- libvirtDomainVcpuStateDesc