Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: annotate node and instance states with architecture #40

Merged
merged 2 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ For self signed certificates, you can either use `--skip-tls-verification` or pr

Metric name | Description
---- | ----------
anka_instance_state_count | Count of Instances in a particular State (label: state)
anka_instance_state_count | Count of Instances in a particular State (label: arch, state)
anka_instance_state_per_template_count | Count of Instances in a particular state, per Template (label: state, template_uuid, template_name)
anka_instance_state_per_group_count | Count of Instances in a particular state, per Group (label: state, group_name)
-- | --
anka_node_instance_count | Count of Instances running on the Node
anka_node_instance_capacity | Total Instance slots (capacity) on the Node
anka_node_states | Node state (1 = current state) (label: id, name, state)
anka_node_states_count | Count of Nodes in a particular state (label: state)
anka_node_states_count | Count of Nodes in a particular state (label: arch, state)
anka_node_disk_free_space | Amount of free disk space on the Node in Bytes
anka_node_disk_total_space | Amount of total available disk space on the Node in Bytes
anka_node_disk_anka_used_space | Amount of disk space used by Anka on the Node in Bytes
Expand Down
12 changes: 7 additions & 5 deletions src/metrics/instance_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ func (ism InstanceStateMetric) GetEventHandler() func(interface{}) error {
if err != nil {
return err
}
var stateIntMap = intMapFromStringSlice(types.InstanceStates)
var archStateMap = intMapFromTwoStringSlices(types.Architectures, types.InstanceStates)
for _, instance := range instances {
stateIntMap[instance.Vm.State] = stateIntMap[instance.Vm.State] + 1
archStateMap[instance.Vm.Arch][instance.Vm.State] = archStateMap[instance.Vm.Arch][instance.Vm.State] + 1
}
for _, state := range types.InstanceStates {
metric.With(prometheus.Labels{"state": state}).Set(float64(stateIntMap[state]))
for _, arch := range types.Architectures {
for _, state := range types.InstanceStates {
metric.With(prometheus.Labels{"arch": arch, "state": state}).Set(float64(archStateMap[arch][state]))
}
}
return nil
}
Expand All @@ -34,7 +36,7 @@ func (ism InstanceStateMetric) GetEventHandler() func(interface{}) error {
func init() { // runs on exporter init only (updates are made with the above EventHandler; triggered by the Client)

AddMetric(InstanceStateMetric{BaseAnkaMetric{
metric: CreateGaugeMetricVec("anka_instance_state_count", "Count of Instances in a particular State (label: state)", []string{"state"}),
metric: CreateGaugeMetricVec("anka_instance_state_count", "Count of Instances in a particular State (label: arch, state)", []string{"arch", "state"}),
event: events.EVENT_VM_DATA_UPDATED,
}})

Expand Down
12 changes: 7 additions & 5 deletions src/metrics/node_states.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,18 @@ func (nsm NodeStatesMetric) GetEventHandler() func(interface{}) error {
var ankaNodeStatesMetrics = []NodeStatesMetric{
{
BaseAnkaMetric: BaseAnkaMetric{
metric: CreateGaugeMetricVec("anka_node_states_count", "Count of Nodes in a particular State (label: state)", []string{"state"}),
metric: CreateGaugeMetricVec("anka_node_states_count", "Count of Nodes in a particular State (label: arch, state)", []string{"arch", "state"}),
event: events.EVENT_NODE_UPDATED,
},
HandleData: func(nodes []types.Node, metric *prometheus.GaugeVec) {
var stateIntMap = intMapFromStringSlice(types.NodeStates)
var archStateMap = intMapFromTwoStringSlices(types.Architectures, types.NodeStates)
for _, node := range nodes {
stateIntMap[node.State] = stateIntMap[node.State] + 1
archStateMap[node.HostArch][node.State] = archStateMap[node.HostArch][node.State] + 1
}
for _, state := range types.NodeStates {
metric.With(prometheus.Labels{"state": state}).Set(float64(stateIntMap[state]))
for _, arch := range types.Architectures {
for _, state := range types.NodeStates {
metric.With(prometheus.Labels{"arch": arch, "state": state}).Set(float64(archStateMap[arch][state]))
}
}
},
},
Expand Down
13 changes: 8 additions & 5 deletions src/metrics/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import (
"github.com/veertuinc/anka-prometheus-exporter/src/types"
)

func intMapFromStringSlice(stringSlice []string) map[string]int {
intMap := map[string]int{}
for _, item := range stringSlice {
intMap[item] = 0
func intMapFromTwoStringSlices(outerStringSlice []string, innerStringSlice []string) map[string]map[string]int {
outerMap := map[string]map[string]int{}
for _, outerItem := range outerStringSlice {
outerMap[outerItem] = map[string]int{}
for _, innerItem := range innerStringSlice {
outerMap[outerItem][innerItem] = 0
}
}
return intMap
return outerMap
}

func uniqueThisStringArray(arr []string) []string {
Expand Down
7 changes: 7 additions & 0 deletions src/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ var NodeStates = []string{
"Updating",
}

var Architectures = []string{
"amd64",
"arm64",
}

var InstanceStates = []string{
"Scheduling",
"Pulling",
Expand Down Expand Up @@ -34,6 +39,7 @@ type Node struct {
DiskSize uint `json:"disk_size"`
State string `json:"state"`
Capacity uint `json:"capacity"`
HostArch string `json:"host_arch"`
Groups []NodeGroup `json:"groups"`
}

Expand All @@ -60,6 +66,7 @@ type VmData struct {
TemplateName string
GroupUUID string `json:"group_id"`
NodeUUID string `json:"node_id"`
Arch string `json:"arch"`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the arch field always present? According to the docs:

All fields but the following are omitted if empty: vmid, group_id, instance_state, anka_registry, ts, cr_time, progress, vlan and usb_device.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for controller >= 1.22.0. I'm not aware of any customers still on that version, so this should be fine. Though, I'll make a readme note in the main branch

}

type Response interface {
Expand Down
Loading