Skip to content

Commit

Permalink
Merge pull request #57 from gjasny/add-status
Browse files Browse the repository at this point in the history
feat: add controller and registry state
  • Loading branch information
NorseGaud authored Dec 10, 2024
2 parents 8e3d6bb + a5738d3 commit 29990a3
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ The `-client-tls` flag is not required if your controller certificate is signed

Metric name | Description
---- | ----------
anka_controller_state_count | Status of the Anka Controller (labels: state)
anka_registry_state_count | Status of the Anka Registry (labels: state)
-- | --
anka_instance_state_count | Count of Instances in a particular State (labels: arch, state)
anka_instance_state_per_template_count | Count of Instances in a particular state, per Template (labels: state, template_uuid, template_name)
anka_instance_state_per_group_count | Count of Instances in a particular state, per Group (labels: state, group_name)
Expand Down
2 changes: 2 additions & 0 deletions src/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func NewClient(addr, username, password string, interval int, certs ClientTLSCer
events.EVENT_REGISTRY_DISK_DATA_UPDATED: make([]func(interface{}) error, 0),
events.EVENT_VM_DATA_UPDATED: make([]func(interface{}) error, 0),
events.EVENT_REGISTRY_TEMPLATES_UPDATED: make([]func(interface{}) error, 0),
events.EVENT_STATUS_UPDATED: make([]func(interface{}) error, 0),
},
communicator: communicator,
timeoutSeconds: int64(interval),
Expand All @@ -55,6 +56,7 @@ func (client *Client) Init() {
go client.initDataLoop(client.communicator.GetVmsData, events.EVENT_VM_DATA_UPDATED)
go client.initDataLoop(client.communicator.GetRegistryDiskData, events.EVENT_REGISTRY_DISK_DATA_UPDATED)
go client.initDataLoop(client.communicator.GetRegistryTemplatesData, events.EVENT_REGISTRY_TEMPLATES_UPDATED)
go client.initDataLoop(client.communicator.GetStatus, events.EVENT_STATUS_UPDATED)
}

func (client *Client) Register(ev events.Event, eventHandler func(interface{}) error) error {
Expand Down
12 changes: 12 additions & 0 deletions src/client/communicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ func (comm *Communicator) TestConnection() error {
}
}

func (comm *Communicator) GetStatus() (interface{}, error) {
lock.Lock()
defer lock.Unlock()
endpoint := "/api/v1/status"
resp := &types.StatusResponse{}
d, err := comm.getData(endpoint, resp)
if err != nil {
return nil, fmt.Errorf("getting status error: %s", err)
}
return d, nil
}

func (comm *Communicator) GetNodesData() (interface{}, error) {
lock.Lock()
defer lock.Unlock()
Expand Down
1 change: 1 addition & 0 deletions src/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ const (
EVENT_REGISTRY_DISK_DATA_UPDATED = 2
EVENT_VM_DATA_UPDATED = 3
EVENT_REGISTRY_TEMPLATES_UPDATED = 4
EVENT_STATUS_UPDATED = 5
)
69 changes: 69 additions & 0 deletions src/metrics/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package metrics

import (
"github.com/prometheus/client_golang/prometheus"
"github.com/veertuinc/anka-prometheus-exporter/src/events"
"github.com/veertuinc/anka-prometheus-exporter/src/types"
)

type StatusMetric struct {
BaseAnkaMetric
HandleData func(*types.Status, *prometheus.GaugeVec)
}

func (sm StatusMetric) GetEventHandler() func(interface{}) error {
return func(d interface{}) error {
status, err := ConvertToStatusData(d)
if err != nil {
return err
}
metric, err := ConvertMetricToGaugeVec(sm.metric)
if err != nil {
return err
}
sm.HandleData(
status,
metric,
)
return nil
}
}

var ankaStatusMetrics = []StatusMetric{
{
BaseAnkaMetric: BaseAnkaMetric{
metric: CreateGaugeMetricVec("anka_controller_state_count", "Status of the Anka Controller", []string{"state"}),
event: events.EVENT_STATUS_UPDATED,
},
HandleData: func(status *types.Status, metric *prometheus.GaugeVec) {
for _, state := range types.ControllerStates {
counter := 0
if status.Status == state {
counter++
}
metric.With(prometheus.Labels{"state": state}).Set(float64(counter))
}
},
},
{
BaseAnkaMetric: BaseAnkaMetric{
metric: CreateGaugeMetricVec("anka_registry_state_count", "Status of the Anka Registry", []string{"state"}),
event: events.EVENT_STATUS_UPDATED,
},
HandleData: func(status *types.Status, metric *prometheus.GaugeVec) {
for _, state := range types.RegistryStates {
counter := 0
if status.RegistryStatus == state {
counter++
}
metric.With(prometheus.Labels{"state": state}).Set(float64(counter))
}
},
},
}

func init() { // runs on exporter init only (updates are made with the above EventHandler; triggered by the Client)
for _, statusMetric := range ankaStatusMetrics {
AddMetric(statusMetric)
}
}
8 changes: 8 additions & 0 deletions src/metrics/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ func CreateGaugeMetricVec(name string, help string, labels []string) *prometheus
}, labels)
}

func ConvertToStatusData(d interface{}) (*types.Status, error) {
data, ok := d.(types.Status)
if !ok {
return nil, fmt.Errorf("could not convert incoming data to required status information. original data: %v", d)
}
return &data, nil
}

func ConvertToNodeData(d interface{}) ([]types.Node, error) {
data, ok := d.([]types.Node)
if !ok {
Expand Down
26 changes: 26 additions & 0 deletions src/types/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package types

var ControllerStates = []string{
"Running",
}

var RegistryStates = []string{
"Running",
"FAIL",
}

var NodeStates = []string{
"Offline",
"Inactive (Invalid License)",
Expand All @@ -25,6 +34,14 @@ var InstanceStates = []string{
"Pushing",
}

type Status struct {
Status string `json:"status"`
Version string `json:"version"`
RegistryAddress string `json:"registry_address"`
RegistryStatus string `json:"registry_status"`
License string `json:"license"`
}

type Node struct {
NodeID string `json:"node_id"`
NodeName string `json:"node_name"`
Expand Down Expand Up @@ -89,6 +106,15 @@ func (dr *DefaultResponse) GetMessage() string {
return dr.Message
}

type StatusResponse struct {
DefaultResponse
Body Status `json:"body"`
}

func (sr *StatusResponse) GetBody() interface{} {
return sr.Body
}

type NodesResponse struct {
DefaultResponse
Body []Node `json:"body"`
Expand Down

0 comments on commit 29990a3

Please sign in to comment.