package cluster // ClusterStats is used to gather stats for the entire cluster // Combined with StatsDiff, we can get some basic cluster wide stats tracking type ClusterStats struct { // CPU Statistics including number of CPUs CPU CPUStats // Memory provides information about the amount of memory, including free and // allocated memory Memory MemoryStats // Storage provides information about storage pools, Only get's stats for active // pools, and will not activate pools that are not already active. // Trys to sort out shared file systems from local filesystems using the Type parameter // of Host.StoragePoolInfo Storage StorageStats // Volume provides information on allocated volumes used in the cluster Volume VolumeStats // VM provides VM specific counters for the cluster VM VMStats // Host provides Host information for the cluster Host HostStats // Network provices available networks, and how many are shared between hosts Network NetworkStats // NetIF provides information about Libvirt allocated networks, usable by the // libvirt cluster NetIF NetIFStats old *ClusterStats c *Cluster } // CPUStats provides information about the number of CPUs, Cores, // Threads, and Speed available to the cluster. type CPUStats struct { Sockets uint32 Cores uint32 Threads uint32 Allocated uint32 MHz uint64 } // MemoryStats provies information about the amount of memory, including free and // allocated memory. Allocated is the total allocated to Guests type MemoryStats struct { Total uint64 Free uint64 Buffers uint64 Cached uint64 Allocated uint64 } // StorageStats provides information about the available storage pools in the cluster, // including the amount of space available, allocated, and how many pools are shared // between hosts type StorageStats struct { Total uint64 Used uint64 Free uint64 Active uint32 Inactive uint32 Pools uint32 } // VolumeStats provides information about the number of volumes on the cluster. // Counts volumes in shared storage (as detmermined by StorageStats) only once type VolumeStats struct { Total uint32 Active uint32 Inactive uint32 } // VMStats provides information about the defined Virtual Machines on the cluster type VMStats struct { Count uint32 Started uint32 Stopped uint32 } // HostStats provides informatoin about the number of hosts defined, and how many // are currently available. An unavailable host will not have it's statistics counted type HostStats struct { Count uint32 Available uint32 Nodes uint32 } // NetworkStats provides informatoin about the available Host network connections, // including bridges and ethernet devices. type NetworkStats struct { Count uint32 Active uint32 Inactive uint32 } // NetIFStats provides information about Libvirt defined networks type NetIFStats struct { Count uint32 Common uint32 Active uint32 Inactive uint32 } // DeviceStats provides information about the number of allocatable devices in the // cluster. These are PCI and USB devices. type DeviceStats struct { Count uint32 } // SecretStats provides the number of secrets defined throughout the cluster. // Shared secrets are only counted once, and are recognized by their UUID type SecretStats struct { Count uint32 Shared uint32 } // ClusterStats is used to gather stats for the entire cluster type StatDiff struct { CPU CPUDiff Memory MemoryDiff Storage StorageStats Volume VolumeDiff VM VMDiff Host HostDiff Network NetworkDiff } type CPUDiff struct { Sockets int Cores int Threads int Allocated int } type MemoryDiff struct { Total int64 Free int64 Buffers int64 Cached int64 Allocated int64 } type StorageDiff struct { Total int64 Used int64 Free int64 Active int64 Inactive int64 Pools int } type VolumeDiff struct { Total int Active int Inactive int } type VMDiff struct { Count int Started int Stopped int } type HostDiff struct { Count int Available int } type NetworkDiff struct { Count int Active int Inactive int } // InitStats is given a cluster, which it then uses to load the initial statistics // Does not close connections, but uses the host connections available to the // cluster to add statistics together. func InitStats(c *Cluster) *ClusterStats { cs := &ClusterStats{ c: c, } return cs } // Update triggers the stats collector to refresh it's statistics func (cs *ClusterStats) Update() { cs.old = cs.copy() cs.reset() // Start looping through each host in the cluster, adding to the total for _, h := range cs.c.hosts { cs.Host.Count++ cs.Host.Available++ cs.CPU.Sockets += h.HostInfo.Sockets cs.CPU.Cores += h.HostInfo.Cores cs.CPU.Threads += h.HostInfo.Threads cs.Memory.Total += h.NodeMemory.Total cs.Memory.Free += h.NodeMemory.Free cs.Memory.Buffers += h.NodeMemory.Buffers cs.Memory.Cached += h.NodeMemory.Cached // Storage Pool counting cs.Storage.Pools += uint32(len(h.StoragePoolList)) countedSharedPools := map[string]struct{}{} // Loop through available storage pools for _, sp := range h.StoragePoolList { if _, ok := countedSharedPools[sp.Name]; ok { // Already counted this shared pool, move on continue } if sp.HAEnabled { countedSharedPools[sp.Name] = struct{}{} } if !sp.Active { cs.Storage.Inactive++ continue } cs.Storage.Active++ cs.Storage.Total += sp.Capacity cs.Storage.Used += sp.Allocation cs.Storage.Free += sp.Capacity - sp.Allocation // Volumes in the pool cs.Volume.Total += uint32(len(sp.Volumes)) for range sp.Volumes { cs.Volume.Active++ } } // VM Count cs.VM.Count += uint32(len(h.VMList)) for _, vm := range h.VMList { cs.CPU.Allocated += uint32(vm.VCPUs) cs.Memory.Allocated += uint64(vm.Memory) if vm.Active { cs.VM.Started++ continue } cs.VM.Stopped++ } // Network count cs.Network.Count += uint32(len(h.NetworkList)) for _, ni := range h.NetworkList { if ni.Active { cs.Network.Active++ continue } cs.Network.Inactive++ } } } // Diff returns a map of all the field and how they changed func (cs *ClusterStats) Diff() StatDiff { return StatDiff{ CPU: struct { Sockets int Cores int Threads int Allocated int }{ Sockets: int(cs.CPU.Sockets) - int(cs.old.CPU.Sockets), Cores: int(cs.CPU.Cores) - int(cs.old.CPU.Cores), Threads: int(cs.CPU.Threads) - int(cs.old.CPU.Threads), Allocated: int(cs.CPU.Allocated) - int(cs.old.CPU.Allocated), }, Memory: struct { Total int Free int Buffers int Cached int Allocated int }{ Total: int(cs.old.Memory.Total - cs.Memory.Total), Free: int(cs.old.Memory.Free - cs.Memory.Free), Buffers: int(cs.old.Memory.Buffers - cs.Memory.Buffers), Cached: int(cs.old.Memory.Cached - cs.Memory.Cached), Allocated: int(cs.old.Memory.Allocated - cs.Memory.Allocated), }, Storage: struct { Total int Used int Free int Active int Inactive int Pools int Volumes struct { Total int Active int Inactive int } }{ Total: int(cs.old.Storage.Total - cs.Storage.Total), Used: int(cs.old.Storage.Used - cs.Storage.Used), Free: int(cs.old.Storage.Free - cs.Storage.Free), Active: int(cs.old.Storage.Active - cs.Storage.Active), Inactive: int(cs.old.Storage.Inactive - cs.Storage.Inactive), Pools: int(cs.old.Storage.Pools - cs.Storage.Pools), Volumes: struct { Total int Active int Inactive int }{ Total: int(cs.old.Volume.Total - cs.Volume.Total), Active: int(cs.old.Volume.Active - cs.Volume.Active), Inactive: int(cs.old.Volume.Inactive - cs.Volume.Inactive), }, }, VM: struct { Count int Started int Stopped int }{ Count: int(cs.old.VM.Count - cs.VM.Count), Started: int(cs.old.VM.Started - cs.VM.Started), Stopped: int(cs.old.VM.Stopped - cs.VM.Stopped), }, Host: struct { Count int Available int }{ Count: int(cs.old.Host.Count - cs.Host.Count), Available: int(cs.old.Host.Available - cs.Host.Available), }, Network: struct { Count int Active int Inactive int }{ Count: int(cs.old.Network.Count - cs.Network.Count), Active: int(cs.old.Network.Active - cs.Network.Active), Inactive: int(cs.old.Network.Inactive - cs.Network.Inactive), }, } } // copy the clusterstats into a new clusterstatus object for comparison purposes func (cs *ClusterStats) copy() *ClusterStats { ncs := *cs return &ncs } // reset all values to zero value func (cs *ClusterStats) reset() { cs.CPU.Sockets = 0 cs.CPU.Cores = 0 cs.CPU.Threads = 0 cs.CPU.Allocated = 0 cs.Memory.Total = 0 cs.Memory.Free = 0 cs.Memory.Buffers = 0 cs.Memory.Cached = 0 cs.Storage.Total = 0 cs.Storage.Used = 0 cs.Storage.Free = 0 cs.Storage.Active = 0 cs.Storage.Inactive = 0 cs.Storage.Pools = 0 cs.VM.Count = 0 cs.VM.Started = 0 cs.VM.Stopped = 0 cs.Host.Count = 0 cs.Host.Available = 0 cs.Network.Count = 0 cs.Network.Active = 0 cs.Network.Inactive = 0 }