converge/cmd/converge/prometheus.go
Erik Brakkee 9d1c6d6616 prometheus support step 1
updates to documentation.
2024-08-07 20:50:17 +02:00

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)
}
}