master
go 212 lines 5.49 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package docker_engine
4
5 import (
6 "fmt"
7
8 "github.com/netdata/netdata/go/plugins/pkg/prometheus"
9 "github.com/netdata/netdata/go/plugins/pkg/stm"
10 )
11
12 func isDockerEngineMetrics(pms prometheus.Series) bool {
13 return pms.FindByName("engine_daemon_engine_info").Len() > 0
14 }
15
16 func (c *Collector) collect() (map[string]int64, error) {
17 pms, err := c.prom.ScrapeSeries()
18 if err != nil {
19 return nil, err
20 }
21
22 if !isDockerEngineMetrics(pms) {
23 return nil, fmt.Errorf("'%s' returned non docker engine metrics", c.URL)
24 }
25
26 mx := c.collectMetrics(pms)
27 return stm.ToMap(mx), nil
28 }
29
30 func (c *Collector) collectMetrics(pms prometheus.Series) metrics {
31 var mx metrics
32 collectHealthChecks(&mx, pms)
33 collectContainerActions(&mx, pms)
34 collectBuilderBuildsFails(&mx, pms)
35 if hasContainerStates(pms) {
36 c.hasContainerStates = true
37 mx.Container.States = &containerStates{}
38 collectContainerStates(&mx, pms)
39 }
40 if isSwarmManager(pms) {
41 c.isSwarmManager = true
42 mx.SwarmManager = &swarmManager{}
43 collectSwarmManager(&mx, pms)
44 }
45 return mx
46 }
47
48 func isSwarmManager(pms prometheus.Series) bool {
49 return pms.FindByName("swarm_node_manager").Max() == 1
50 }
51
52 func hasContainerStates(pms prometheus.Series) bool {
53 return pms.FindByName("engine_daemon_container_states_containers").Len() > 0
54 }
55
56 func collectHealthChecks(mx *metrics, raw prometheus.Series) {
57 v := raw.FindByName("engine_daemon_health_checks_failed_total").Max()
58 mx.HealthChecks.Failed = v
59 }
60
61 func collectContainerActions(mx *metrics, raw prometheus.Series) {
62 for _, metric := range raw.FindByName("engine_daemon_container_actions_seconds_count") {
63 action := metric.Labels.Get("action")
64 if action == "" {
65 continue
66 }
67
68 v := metric.Value
69 switch action {
70 default:
71 case "changes":
72 mx.Container.Actions.Changes = v
73 case "commit":
74 mx.Container.Actions.Commit = v
75 case "create":
76 mx.Container.Actions.Create = v
77 case "delete":
78 mx.Container.Actions.Delete = v
79 case "start":
80 mx.Container.Actions.Start = v
81 }
82 }
83 }
84
85 func collectContainerStates(mx *metrics, raw prometheus.Series) {
86 for _, metric := range raw.FindByName("engine_daemon_container_states_containers") {
87 state := metric.Labels.Get("state")
88 if state == "" {
89 continue
90 }
91
92 v := metric.Value
93 switch state {
94 default:
95 case "paused":
96 mx.Container.States.Paused = v
97 case "running":
98 mx.Container.States.Running = v
99 case "stopped":
100 mx.Container.States.Stopped = v
101 }
102 }
103 }
104
105 func collectBuilderBuildsFails(mx *metrics, raw prometheus.Series) {
106 for _, metric := range raw.FindByName("builder_builds_failed_total") {
107 reason := metric.Labels.Get("reason")
108 if reason == "" {
109 continue
110 }
111
112 v := metric.Value
113 switch reason {
114 default:
115 case "build_canceled":
116 mx.Builder.FailsByReason.BuildCanceled = v
117 case "build_target_not_reachable_error":
118 mx.Builder.FailsByReason.BuildTargetNotReachableError = v
119 case "command_not_supported_error":
120 mx.Builder.FailsByReason.CommandNotSupportedError = v
121 case "dockerfile_empty_error":
122 mx.Builder.FailsByReason.DockerfileEmptyError = v
123 case "dockerfile_syntax_error":
124 mx.Builder.FailsByReason.DockerfileSyntaxError = v
125 case "error_processing_commands_error":
126 mx.Builder.FailsByReason.ErrorProcessingCommandsError = v
127 case "missing_onbuild_arguments_error":
128 mx.Builder.FailsByReason.MissingOnbuildArgumentsError = v
129 case "unknown_instruction_error":
130 mx.Builder.FailsByReason.UnknownInstructionError = v
131 }
132 }
133 }
134
135 func collectSwarmManager(mx *metrics, raw prometheus.Series) {
136 v := raw.FindByName("swarm_manager_configs_total").Max()
137 mx.SwarmManager.Configs = v
138
139 v = raw.FindByName("swarm_manager_networks_total").Max()
140 mx.SwarmManager.Networks = v
141
142 v = raw.FindByName("swarm_manager_secrets_total").Max()
143 mx.SwarmManager.Secrets = v
144
145 v = raw.FindByName("swarm_manager_services_total").Max()
146 mx.SwarmManager.Services = v
147
148 v = raw.FindByName("swarm_manager_leader").Max()
149 mx.SwarmManager.IsLeader = v
150
151 for _, metric := range raw.FindByName("swarm_manager_nodes") {
152 state := metric.Labels.Get("state")
153 if state == "" {
154 continue
155 }
156
157 v := metric.Value
158 switch state {
159 default:
160 case "disconnected":
161 mx.SwarmManager.Nodes.PerState.Disconnected = v
162 case "down":
163 mx.SwarmManager.Nodes.PerState.Down = v
164 case "ready":
165 mx.SwarmManager.Nodes.PerState.Ready = v
166 case "unknown":
167 mx.SwarmManager.Nodes.PerState.Unknown = v
168 }
169 mx.SwarmManager.Nodes.Total += v
170 }
171
172 for _, metric := range raw.FindByName("swarm_manager_tasks_total") {
173 state := metric.Labels.Get("state")
174 if state == "" {
175 continue
176 }
177
178 v := metric.Value
179 switch state {
180 default:
181 case "accepted":
182 mx.SwarmManager.Tasks.PerState.Accepted = v
183 case "assigned":
184 mx.SwarmManager.Tasks.PerState.Assigned = v
185 case "complete":
186 mx.SwarmManager.Tasks.PerState.Complete = v
187 case "failed":
188 mx.SwarmManager.Tasks.PerState.Failed = v
189 case "new":
190 mx.SwarmManager.Tasks.PerState.New = v
191 case "orphaned":
192 mx.SwarmManager.Tasks.PerState.Orphaned = v
193 case "pending":
194 mx.SwarmManager.Tasks.PerState.Pending = v
195 case "preparing":
196 mx.SwarmManager.Tasks.PerState.Preparing = v
197 case "ready":
198 mx.SwarmManager.Tasks.PerState.Ready = v
199 case "rejected":
200 mx.SwarmManager.Tasks.PerState.Rejected = v
201 case "remove":
202 mx.SwarmManager.Tasks.PerState.Remove = v
203 case "running":
204 mx.SwarmManager.Tasks.PerState.Running = v
205 case "shutdown":
206 mx.SwarmManager.Tasks.PerState.Shutdown = v
207 case "starting":
208 mx.SwarmManager.Tasks.PerState.Starting = v
209 }
210 mx.SwarmManager.Tasks.Total += v
211 }
212 }