diff --git a/cmd/converge/prometheus.go b/cmd/converge/prometheus.go index f8f46ad..9c355e9 100644 --- a/cmd/converge/prometheus.go +++ b/cmd/converge/prometheus.go @@ -12,10 +12,30 @@ import ( const NAMESPACE = "converge" +// more efficient state representation for state +type PrometheusState struct { + agents map[string]*models.Agent + clients map[string]*models.Client +} + +func NewPrometheusState(state *models.State) *PrometheusState { + res := PrometheusState{ + agents: make(map[string]*models.Agent), + clients: make(map[string]*models.Client), + } + for i, _ := range state.Agents { + res.agents[state.Agents[i].Guid] = &state.Agents[i] + } + for i, _ := range state.Clients { + res.clients[state.Clients[i].Guid] = &state.Clients[i] + } + return &res +} + var ( // remember previous values of agent guids and clients so that we can increment // the cumulative counters. - lastState *models.State = &models.State{} + lastState *PrometheusState = NewPrometheusState(&models.State{}) cumulativeAgentCount = promauto.NewCounter(prometheus.CounterOpts{ Namespace: NAMESPACE, @@ -129,7 +149,7 @@ func clientLabels(client *models.Client) prometheus.Labels { } func agentActive(agent *models.Agent) { - prevAgent, ok := findAgent(lastState, agent.Guid) + prevAgent, ok := lastState.agents[agent.Guid] if ok && *prevAgent != *agent { removeAgentInfoMetrics(prevAgent) } @@ -142,26 +162,8 @@ func agentActive(agent *models.Agent) { Set(float64(time.Now().Sub(agent.StartTime).Seconds())) } -func findAgent(state *models.State, guid string) (*models.Agent, bool) { - for i := range state.Agents { - if state.Agents[i].Guid == guid { - return &state.Agents[i], true - } - } - return nil, false -} - -func findClient(state *models.State, guid string) (*models.Client, bool) { - for i := range state.Clients { - if state.Clients[i].Guid == guid { - return &state.Clients[i], true - } - } - return nil, false -} - func clientActive(client *models.Client) { - prevClient, ok := findClient(lastState, client.Guid) + prevClient, ok := lastState.clients[client.Guid] if ok && *prevClient != *client { removeClientInfoMetrics(prevClient) } @@ -214,38 +216,35 @@ var prometheusChannel = make(chan func()) func updateMetrics(state *models.State) { prometheusChannel <- func() { - updateMetricsImpl(state) + updateMetricsImpl(NewPrometheusState(state)) } } func updateDurations() { - for i := range lastState.Agents { - agent := &lastState.Agents[i] + for _, agent := range lastState.agents { agentDuration. With(prometheus.Labels{"agent_guid": agent.Guid}). Set(float64(time.Now().Sub(agent.StartTime).Seconds())) } - for i := range lastState.Clients { - client := &lastState.Clients[i] + for _, client := range lastState.clients { clientDuration. With(prometheus.Labels{"client_guid": client.Guid}). Set(float64(time.Now().Sub(client.StartTime).Seconds())) } } -func updateMetricsImpl(state *models.State) { +func updateMetricsImpl(state *PrometheusState) { + agentGuids := make(map[string]*models.Agent) clientGuids := make(map[string]*models.Client) - agentCount.Set(float64(len(state.Agents))) + agentCount.Set(float64(len(state.agents))) disconnectedAgents := make(map[string]*models.Agent) - for i := range lastState.Agents { - agent := &lastState.Agents[i] + for _, agent := range lastState.agents { disconnectedAgents[agent.Guid] = agent } - for i := range state.Agents { - agent := &state.Agents[i] - if _, ok := findAgent(lastState, agent.Guid); !ok { + for _, agent := range state.agents { + if lastState.agents[agent.Guid] == nil { cumulativeAgentCount.Inc() } delete(disconnectedAgents, agent.Guid) @@ -256,17 +255,15 @@ func updateMetricsImpl(state *models.State) { removeAgentMetrics(agent) } - clientCount.Set(float64(len(state.Clients))) + clientCount.Set(float64(len(state.clients))) // with this app disconnectedClients := make(map[string]*models.Client) - for i := range lastState.Clients { - client := &lastState.Clients[i] + for _, client := range lastState.clients { disconnectedClients[client.Guid] = client } - for i := range state.Clients { - client := &state.Clients[i] - if _, ok := findClient(lastState, client.Guid); !ok { + for _, client := range state.clients { + if lastState.clients[client.Guid] == nil { cumulativeClientCount.Inc() } delete(disconnectedClients, client.Guid)