Browse code

Merge pull request #32792 from rogaha/extra_prometheus_metrics

Add extra prometheus metrics

Sebastiaan van Stijn authored on 2017/05/10 04:48:34
Showing 5 changed files
... ...
@@ -50,6 +50,7 @@ func NewBuildManager(b builder.Backend) *BuildManager {
50 50
 
51 51
 // Build starts a new build from a BuildConfig
52 52
 func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) (*builder.Result, error) {
53
+	buildsTriggered.Inc()
53 54
 	if config.Options.Dockerfile == "" {
54 55
 		config.Options.Dockerfile = builder.DefaultDockerfileName
55 56
 	}
... ...
@@ -144,6 +145,7 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil
144 144
 	addNodesForLabelOption(dockerfile.AST, b.options.Labels)
145 145
 
146 146
 	if err := checkDispatchDockerfile(dockerfile.AST); err != nil {
147
+		buildsFailed.WithValues(metricsDockerfileSyntaxError).Inc()
147 148
 		return nil, err
148 149
 	}
149 150
 
... ...
@@ -153,12 +155,14 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil
153 153
 	}
154 154
 
155 155
 	if b.options.Target != "" && !dispatchState.isCurrentStage(b.options.Target) {
156
+		buildsFailed.WithValues(metricsBuildTargetNotReachableError).Inc()
156 157
 		return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
157 158
 	}
158 159
 
159 160
 	b.warnOnUnusedBuildArgs()
160 161
 
161 162
 	if dispatchState.imageID == "" {
163
+		buildsFailed.WithValues(metricsDockerfileEmptyError).Inc()
162 164
 		return nil, errors.New("No image was generated. Is your Dockerfile empty?")
163 165
 	}
164 166
 	return &builder.Result{ImageID: dispatchState.imageID, FromImage: dispatchState.baseImage}, nil
... ...
@@ -181,6 +185,7 @@ func (b *Builder) dispatchDockerfileWithCancellation(dockerfile *parser.Result)
181 181
 		case <-b.clientCtx.Done():
182 182
 			logrus.Debug("Builder: build cancelled!")
183 183
 			fmt.Fprint(b.Stdout, "Build cancelled")
184
+			buildsFailed.WithValues(metricsBuildCanceled).Inc()
184 185
 			return nil, errors.New("Build cancelled")
185 186
 		default:
186 187
 			// Not cancelled yet, keep going...
... ...
@@ -134,6 +134,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
134 134
 	// To ensure the user is given a decent error message if the platform
135 135
 	// on which the daemon is running does not support a builder command.
136 136
 	if err := platformSupports(strings.ToLower(cmd)); err != nil {
137
+		buildsFailed.WithValues(metricsCommandNotSupportedError).Inc()
137 138
 		return nil, err
138 139
 	}
139 140
 
... ...
@@ -155,6 +156,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
155 155
 	processFunc := createProcessWordFunc(options.shlex, cmd, envs)
156 156
 	words, err := getDispatchArgsFromNode(ast, processFunc, msg)
157 157
 	if err != nil {
158
+		buildsFailed.WithValues(metricsErrorProcessingCommandsError).Inc()
158 159
 		return nil, err
159 160
 	}
160 161
 	args = append(args, words...)
... ...
@@ -163,6 +165,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
163 163
 
164 164
 	f, ok := evaluateTable[cmd]
165 165
 	if !ok {
166
+		buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
166 167
 		return nil, fmt.Errorf("unknown instruction: %s", upperCasedCmd)
167 168
 	}
168 169
 	if err := f(newDispatchRequestFromOptions(options, b, args)); err != nil {
... ...
@@ -283,6 +286,7 @@ func checkDispatch(ast *parser.Node) error {
283 283
 	// least one argument
284 284
 	if upperCasedCmd == "ONBUILD" {
285 285
 		if ast.Next == nil {
286
+			buildsFailed.WithValues(metricsMissingOnbuildArgumentsError).Inc()
286 287
 			return errors.New("ONBUILD requires at least one argument")
287 288
 		}
288 289
 	}
... ...
@@ -290,6 +294,6 @@ func checkDispatch(ast *parser.Node) error {
290 290
 	if _, ok := evaluateTable[cmd]; ok {
291 291
 		return nil
292 292
 	}
293
-
293
+	buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
294 294
 	return errors.Errorf("unknown instruction: %s", upperCasedCmd)
295 295
 }
296 296
new file mode 100644
... ...
@@ -0,0 +1,44 @@
0
+package dockerfile
1
+
2
+import (
3
+	"github.com/docker/go-metrics"
4
+)
5
+
6
+var (
7
+	buildsTriggered metrics.Counter
8
+	buildsFailed    metrics.LabeledCounter
9
+)
10
+
11
+// Build metrics prometheus messages, these values must be initialized before
12
+// using them. See the example below in the "builds_failed" metric definition.
13
+const (
14
+	metricsDockerfileSyntaxError        = "dockerfile_syntax_error"
15
+	metricsDockerfileEmptyError         = "dockerfile_empty_error"
16
+	metricsCommandNotSupportedError     = "command_not_supported_error"
17
+	metricsErrorProcessingCommandsError = "error_processing_commands_error"
18
+	metricsBuildTargetNotReachableError = "build_target_not_reachable_error"
19
+	metricsMissingOnbuildArgumentsError = "missing_onbuild_arguments_error"
20
+	metricsUnknownInstructionError      = "unknown_instruction_error"
21
+	metricsBuildCanceled                = "build_canceled"
22
+)
23
+
24
+func init() {
25
+	buildMetrics := metrics.NewNamespace("builder", "", nil)
26
+
27
+	buildsTriggered = buildMetrics.NewCounter("builds_triggered", "Number of triggered image builds")
28
+	buildsFailed = buildMetrics.NewLabeledCounter("builds_failed", "Number of failed image builds", "reason")
29
+	for _, r := range []string{
30
+		metricsDockerfileSyntaxError,
31
+		metricsDockerfileEmptyError,
32
+		metricsCommandNotSupportedError,
33
+		metricsErrorProcessingCommandsError,
34
+		metricsBuildTargetNotReachableError,
35
+		metricsMissingOnbuildArgumentsError,
36
+		metricsUnknownInstructionError,
37
+		metricsBuildCanceled,
38
+	} {
39
+		buildsFailed.WithValues(r)
40
+	}
41
+
42
+	metrics.Register(buildMetrics)
43
+}
... ...
@@ -732,13 +732,15 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
732 732
 	// FIXME: this method never returns an error
733 733
 	info, _ := d.SystemInfo()
734 734
 
735
-	engineVersion.WithValues(
735
+	engineInfo.WithValues(
736 736
 		dockerversion.Version,
737 737
 		dockerversion.GitCommit,
738 738
 		info.Architecture,
739 739
 		info.Driver,
740 740
 		info.KernelVersion,
741 741
 		info.OperatingSystem,
742
+		info.OSType,
743
+		info.ID,
742 744
 	).Set(1)
743 745
 	engineCpus.Set(float64(info.NCPU))
744 746
 	engineMemory.Set(float64(info.MemTotal))
... ...
@@ -12,7 +12,7 @@ var (
12 12
 	containerStates           metrics.LabeledGauge
13 13
 	imageActions              metrics.LabeledTimer
14 14
 	networkActions            metrics.LabeledTimer
15
-	engineVersion             metrics.LabeledGauge
15
+	engineInfo                metrics.LabeledGauge
16 16
 	engineCpus                metrics.Gauge
17 17
 	engineMemory              metrics.Gauge
18 18
 	healthChecksCounter       metrics.Counter
... ...
@@ -35,12 +35,14 @@ func init() {
35 35
 	}
36 36
 
37 37
 	networkActions = ns.NewLabeledTimer("network_actions", "The number of seconds it takes to process each network action", "action")
38
-	engineVersion = ns.NewLabeledGauge("engine", "The version and commit information for the engine process", metrics.Unit("info"),
38
+	engineInfo = ns.NewLabeledGauge("engine", "The information related to the engine and the OS it is running on", metrics.Unit("info"),
39 39
 		"version",
40 40
 		"commit",
41 41
 		"architecture",
42
-		"graph_driver", "kernel",
43
-		"os",
42
+		"graphdriver",
43
+		"kernel", "os",
44
+		"os_type",
45
+		"daemon_id", // ID is a randomly generated unique identifier (e.g. UUID4)
44 46
 	)
45 47
 	engineCpus = ns.NewGauge("engine_cpus", "The number of cpus that the host system of the engine has", metrics.Unit("cpus"))
46 48
 	engineMemory = ns.NewGauge("engine_memory", "The number of bytes of memory that the host system of the engine has", metrics.Bytes)