96 lines
2.4 KiB
Go
96 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"converge/pkg/models"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
const NAMESPACE = "converge"
|
|
|
|
var (
|
|
agentCount = promauto.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: NAMESPACE,
|
|
Name: "agent_count",
|
|
Help: "Current number of agents",
|
|
})
|
|
clientCount = promauto.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: NAMESPACE,
|
|
Name: "client_count",
|
|
Help: "Current number of clients",
|
|
})
|
|
|
|
agentInfo = promauto.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Namespace: NAMESPACE,
|
|
Name: "agent_info",
|
|
Help: "A flexible gauge with dynamic labels, always set to 1",
|
|
},
|
|
[]string{"id", "os"}, // Label names
|
|
)
|
|
clientInfo = promauto.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Namespace: NAMESPACE,
|
|
Name: "client_info",
|
|
Help: "A flexible gauge with dynamic labels, always set to 1",
|
|
},
|
|
[]string{"id", "agentid"}, // Label names
|
|
)
|
|
)
|
|
|
|
func agentLabels(agent models.Agent) prometheus.Labels {
|
|
return prometheus.Labels{
|
|
"id": agent.PublicId,
|
|
"os": agent.AgentInfo.OS,
|
|
}
|
|
}
|
|
|
|
func clientLabels(client models.Client) prometheus.Labels {
|
|
return prometheus.Labels{
|
|
"id": strconv.Itoa(client.ClientId),
|
|
"agentid": client.PublicId,
|
|
}
|
|
}
|
|
|
|
func agentActive(agent models.Agent) {
|
|
agentInfo.With(agentLabels(agent)).Set(1)
|
|
}
|
|
|
|
func clientActive(client models.Client) {
|
|
clientInfo.With(clientLabels(client)).Set(1)
|
|
}
|
|
|
|
func setupPrometheus(notifications chan *models.State) {
|
|
go func() {
|
|
for {
|
|
state := <-notifications
|
|
updateMetrics(state)
|
|
}
|
|
}()
|
|
http.Handle("/metrics", promhttp.Handler())
|
|
}
|
|
|
|
func updateMetrics(state *models.State) {
|
|
// This implemnetation has a small probability that the metric will be in a partially
|
|
// initialized state. This is however unlikely. It would lead to in incorrect determination
|
|
// that an agent or client is not available. However, each agent and client will have a UID
|
|
// so that is still possible to identify the client or agent even though some values might
|
|
// become 0.
|
|
|
|
log.Printf("Got notification %v", *state)
|
|
agentCount.Set(float64(len(state.Agents)))
|
|
agentInfo.Reset()
|
|
for _, agent := range state.Agents {
|
|
agentActive(agent)
|
|
}
|
|
clientCount.Set(float64(len(state.Clients)))
|
|
clientInfo.Reset()
|
|
for _, client := range state.Clients {
|
|
clientActive(client)
|
|
}
|
|
}
|