Add extra prometheus metrics

- buildsTriggered
 - buildsFailed
    - valid options:
        metricsDockerfileSyntaxError,
        metricsDockerfileEmptyError,
        metricsCommandNotSupportedError,
        metricsErrorProcessingCommandsError,
        metricsBuildTargetNotReachableError,
        metricsMissingOnbuildArgumentsError,
        metricsUnknownInstructionError,
        metricsBuildCanceled,
- engineInfo

Signed-off-by: Roberto Gandolfo Hashioka <roberto_hashioka@hotmail.com>
This commit is contained in:
Roberto Gandolfo Hashioka 2017-04-24 04:32:01 -07:00
parent 230bc34837
commit a28b173a78
5 changed files with 63 additions and 6 deletions

View file

@ -49,6 +49,7 @@ func NewBuildManager(b builder.Backend) *BuildManager {
// Build starts a new build from a BuildConfig
func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) (*builder.Result, error) {
buildsTriggered.Inc()
if config.Options.Dockerfile == "" {
config.Options.Dockerfile = builder.DefaultDockerfileName
}
@ -141,6 +142,7 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil
addNodesForLabelOption(dockerfile.AST, b.options.Labels)
if err := checkDispatchDockerfile(dockerfile.AST); err != nil {
buildsFailed.WithValues(metricsDockerfileSyntaxError).Inc()
return nil, err
}
@ -150,12 +152,14 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil
}
if b.options.Target != "" && !dispatchState.isCurrentStage(b.options.Target) {
buildsFailed.WithValues(metricsBuildTargetNotReachableError).Inc()
return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
}
b.warnOnUnusedBuildArgs()
if dispatchState.imageID == "" {
buildsFailed.WithValues(metricsDockerfileEmptyError).Inc()
return nil, errors.New("No image was generated. Is your Dockerfile empty?")
}
return &builder.Result{ImageID: dispatchState.imageID, FromImage: dispatchState.baseImage}, nil
@ -171,6 +175,7 @@ func (b *Builder) dispatchDockerfileWithCancellation(dockerfile *parser.Result)
case <-b.clientCtx.Done():
logrus.Debug("Builder: build cancelled!")
fmt.Fprint(b.Stdout, "Build cancelled")
buildsFailed.WithValues(metricsBuildCanceled).Inc()
return nil, errors.New("Build cancelled")
default:
// Not cancelled yet, keep going...

View file

@ -134,6 +134,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
// To ensure the user is given a decent error message if the platform
// on which the daemon is running does not support a builder command.
if err := platformSupports(strings.ToLower(cmd)); err != nil {
buildsFailed.WithValues(metricsCommandNotSupportedError).Inc()
return nil, err
}
@ -155,6 +156,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
processFunc := createProcessWordFunc(options.shlex, cmd, envs)
words, err := getDispatchArgsFromNode(ast, processFunc, msg)
if err != nil {
buildsFailed.WithValues(metricsErrorProcessingCommandsError).Inc()
return nil, err
}
args = append(args, words...)
@ -163,6 +165,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
f, ok := evaluateTable[cmd]
if !ok {
buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
return nil, fmt.Errorf("unknown instruction: %s", upperCasedCmd)
}
if err := f(newDispatchRequestFromOptions(options, b, args)); err != nil {
@ -283,6 +286,7 @@ func checkDispatch(ast *parser.Node) error {
// least one argument
if upperCasedCmd == "ONBUILD" {
if ast.Next == nil {
buildsFailed.WithValues(metricsMissingOnbuildArgumentsError).Inc()
return errors.New("ONBUILD requires at least one argument")
}
}
@ -290,6 +294,6 @@ func checkDispatch(ast *parser.Node) error {
if _, ok := evaluateTable[cmd]; ok {
return nil
}
buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
return errors.Errorf("unknown instruction: %s", upperCasedCmd)
}

View file

@ -0,0 +1,44 @@
package dockerfile
import (
"github.com/docker/go-metrics"
)
var (
buildsTriggered metrics.Counter
buildsFailed metrics.LabeledCounter
)
// Build metrics prometheus messages, these values must be initialized before
// using them. See the example below in the "builds_failed" metric definition.
const (
metricsDockerfileSyntaxError = "dockerfile_syntax_error"
metricsDockerfileEmptyError = "dockerfile_empty_error"
metricsCommandNotSupportedError = "command_not_supported_error"
metricsErrorProcessingCommandsError = "error_processing_commands_error"
metricsBuildTargetNotReachableError = "build_target_not_reachable_error"
metricsMissingOnbuildArgumentsError = "missing_onbuild_arguments_error"
metricsUnknownInstructionError = "unknown_instruction_error"
metricsBuildCanceled = "build_canceled"
)
func init() {
buildMetrics := metrics.NewNamespace("builder", "", nil)
buildsTriggered = buildMetrics.NewCounter("builds_triggered", "Number of triggered image builds")
buildsFailed = buildMetrics.NewLabeledCounter("builds_failed", "Number of failed image builds", "reason")
for _, r := range []string{
metricsDockerfileSyntaxError,
metricsDockerfileEmptyError,
metricsCommandNotSupportedError,
metricsErrorProcessingCommandsError,
metricsBuildTargetNotReachableError,
metricsMissingOnbuildArgumentsError,
metricsUnknownInstructionError,
metricsBuildCanceled,
} {
buildsFailed.WithValues(r)
}
metrics.Register(buildMetrics)
}

View file

@ -731,13 +731,15 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
// FIXME: this method never returns an error
info, _ := d.SystemInfo()
engineVersion.WithValues(
engineInfo.WithValues(
dockerversion.Version,
dockerversion.GitCommit,
info.Architecture,
info.Driver,
info.KernelVersion,
info.OperatingSystem,
info.OSType,
info.ID,
).Set(1)
engineCpus.Set(float64(info.NCPU))
engineMemory.Set(float64(info.MemTotal))

View file

@ -6,7 +6,7 @@ var (
containerActions metrics.LabeledTimer
imageActions metrics.LabeledTimer
networkActions metrics.LabeledTimer
engineVersion metrics.LabeledGauge
engineInfo metrics.LabeledGauge
engineCpus metrics.Gauge
engineMemory metrics.Gauge
healthChecksCounter metrics.Counter
@ -26,12 +26,14 @@ func init() {
containerActions.WithValues(a).Update(0)
}
networkActions = ns.NewLabeledTimer("network_actions", "The number of seconds it takes to process each network action", "action")
engineVersion = ns.NewLabeledGauge("engine", "The version and commit information for the engine process", metrics.Unit("info"),
engineInfo = ns.NewLabeledGauge("engine", "The information related to the engine and the OS it is running on", metrics.Unit("info"),
"version",
"commit",
"architecture",
"graph_driver", "kernel",
"os",
"graphdriver",
"kernel", "os",
"os_type",
"daemon_id", // ID is a randomly generated unique identifier (e.g. UUID4)
)
engineCpus = ns.NewGauge("engine_cpus", "The number of cpus that the host system of the engine has", metrics.Unit("cpus"))
engineMemory = ns.NewGauge("engine_memory", "The number of bytes of memory that the host system of the engine has", metrics.Bytes)