src/go/plugin/go.d/modules/docker_engine/collect.go
// SPDX-License-Identifier: GPL-3.0-or-later
package docker_engine
import (
"fmt"
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/prometheus"
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/stm"
)
func isDockerEngineMetrics(pms prometheus.Series) bool {
return pms.FindByName("engine_daemon_engine_info").Len() > 0
}
func (de *DockerEngine) collect() (map[string]int64, error) {
pms, err := de.prom.ScrapeSeries()
if err != nil {
return nil, err
}
if !isDockerEngineMetrics(pms) {
return nil, fmt.Errorf("'%s' returned non docker engine metrics", de.URL)
}
mx := de.collectMetrics(pms)
return stm.ToMap(mx), nil
}
func (de *DockerEngine) collectMetrics(pms prometheus.Series) metrics {
var mx metrics
collectHealthChecks(&mx, pms)
collectContainerActions(&mx, pms)
collectBuilderBuildsFails(&mx, pms)
if hasContainerStates(pms) {
de.hasContainerStates = true
mx.Container.States = &containerStates{}
collectContainerStates(&mx, pms)
}
if isSwarmManager(pms) {
de.isSwarmManager = true
mx.SwarmManager = &swarmManager{}
collectSwarmManager(&mx, pms)
}
return mx
}
func isSwarmManager(pms prometheus.Series) bool {
return pms.FindByName("swarm_node_manager").Max() == 1
}
func hasContainerStates(pms prometheus.Series) bool {
return pms.FindByName("engine_daemon_container_states_containers").Len() > 0
}
func collectHealthChecks(mx *metrics, raw prometheus.Series) {
v := raw.FindByName("engine_daemon_health_checks_failed_total").Max()
mx.HealthChecks.Failed = v
}
func collectContainerActions(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName("engine_daemon_container_actions_seconds_count") {
action := metric.Labels.Get("action")
if action == "" {
continue
}
v := metric.Value
switch action {
default:
case "changes":
mx.Container.Actions.Changes = v
case "commit":
mx.Container.Actions.Commit = v
case "create":
mx.Container.Actions.Create = v
case "delete":
mx.Container.Actions.Delete = v
case "start":
mx.Container.Actions.Start = v
}
}
}
func collectContainerStates(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName("engine_daemon_container_states_containers") {
state := metric.Labels.Get("state")
if state == "" {
continue
}
v := metric.Value
switch state {
default:
case "paused":
mx.Container.States.Paused = v
case "running":
mx.Container.States.Running = v
case "stopped":
mx.Container.States.Stopped = v
}
}
}
func collectBuilderBuildsFails(mx *metrics, raw prometheus.Series) {
for _, metric := range raw.FindByName("builder_builds_failed_total") {
reason := metric.Labels.Get("reason")
if reason == "" {
continue
}
v := metric.Value
switch reason {
default:
case "build_canceled":
mx.Builder.FailsByReason.BuildCanceled = v
case "build_target_not_reachable_error":
mx.Builder.FailsByReason.BuildTargetNotReachableError = v
case "command_not_supported_error":
mx.Builder.FailsByReason.CommandNotSupportedError = v
case "dockerfile_empty_error":
mx.Builder.FailsByReason.DockerfileEmptyError = v
case "dockerfile_syntax_error":
mx.Builder.FailsByReason.DockerfileSyntaxError = v
case "error_processing_commands_error":
mx.Builder.FailsByReason.ErrorProcessingCommandsError = v
case "missing_onbuild_arguments_error":
mx.Builder.FailsByReason.MissingOnbuildArgumentsError = v
case "unknown_instruction_error":
mx.Builder.FailsByReason.UnknownInstructionError = v
}
}
}
func collectSwarmManager(mx *metrics, raw prometheus.Series) {
v := raw.FindByName("swarm_manager_configs_total").Max()
mx.SwarmManager.Configs = v
v = raw.FindByName("swarm_manager_networks_total").Max()
mx.SwarmManager.Networks = v
v = raw.FindByName("swarm_manager_secrets_total").Max()
mx.SwarmManager.Secrets = v
v = raw.FindByName("swarm_manager_services_total").Max()
mx.SwarmManager.Services = v
v = raw.FindByName("swarm_manager_leader").Max()
mx.SwarmManager.IsLeader = v
for _, metric := range raw.FindByName("swarm_manager_nodes") {
state := metric.Labels.Get("state")
if state == "" {
continue
}
v := metric.Value
switch state {
default:
case "disconnected":
mx.SwarmManager.Nodes.PerState.Disconnected = v
case "down":
mx.SwarmManager.Nodes.PerState.Down = v
case "ready":
mx.SwarmManager.Nodes.PerState.Ready = v
case "unknown":
mx.SwarmManager.Nodes.PerState.Unknown = v
}
mx.SwarmManager.Nodes.Total += v
}
for _, metric := range raw.FindByName("swarm_manager_tasks_total") {
state := metric.Labels.Get("state")
if state == "" {
continue
}
v := metric.Value
switch state {
default:
case "accepted":
mx.SwarmManager.Tasks.PerState.Accepted = v
case "assigned":
mx.SwarmManager.Tasks.PerState.Assigned = v
case "complete":
mx.SwarmManager.Tasks.PerState.Complete = v
case "failed":
mx.SwarmManager.Tasks.PerState.Failed = v
case "new":
mx.SwarmManager.Tasks.PerState.New = v
case "orphaned":
mx.SwarmManager.Tasks.PerState.Orphaned = v
case "pending":
mx.SwarmManager.Tasks.PerState.Pending = v
case "preparing":
mx.SwarmManager.Tasks.PerState.Preparing = v
case "ready":
mx.SwarmManager.Tasks.PerState.Ready = v
case "rejected":
mx.SwarmManager.Tasks.PerState.Rejected = v
case "remove":
mx.SwarmManager.Tasks.PerState.Remove = v
case "running":
mx.SwarmManager.Tasks.PerState.Running = v
case "shutdown":
mx.SwarmManager.Tasks.PerState.Shutdown = v
case "starting":
mx.SwarmManager.Tasks.PerState.Starting = v
}
mx.SwarmManager.Tasks.Total += v
}
}