1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

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 // Build starts a new build from a BuildConfig
func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) (*builder.Result, error) { func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) (*builder.Result, error) {
buildsTriggered.Inc()
if config.Options.Dockerfile == "" { if config.Options.Dockerfile == "" {
config.Options.Dockerfile = builder.DefaultDockerfileName 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) addNodesForLabelOption(dockerfile.AST, b.options.Labels)
if err := checkDispatchDockerfile(dockerfile.AST); err != nil { if err := checkDispatchDockerfile(dockerfile.AST); err != nil {
buildsFailed.WithValues(metricsDockerfileSyntaxError).Inc()
return nil, err 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) { 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) return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
} }
b.warnOnUnusedBuildArgs() b.warnOnUnusedBuildArgs()
if dispatchState.imageID == "" { if dispatchState.imageID == "" {
buildsFailed.WithValues(metricsDockerfileEmptyError).Inc()
return nil, errors.New("No image was generated. Is your Dockerfile empty?") return nil, errors.New("No image was generated. Is your Dockerfile empty?")
} }
return &builder.Result{ImageID: dispatchState.imageID, FromImage: dispatchState.baseImage}, nil 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(): case <-b.clientCtx.Done():
logrus.Debug("Builder: build cancelled!") logrus.Debug("Builder: build cancelled!")
fmt.Fprint(b.Stdout, "Build cancelled") fmt.Fprint(b.Stdout, "Build cancelled")
buildsFailed.WithValues(metricsBuildCanceled).Inc()
return nil, errors.New("Build cancelled") return nil, errors.New("Build cancelled")
default: default:
// Not cancelled yet, keep going... // 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 // 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. // on which the daemon is running does not support a builder command.
if err := platformSupports(strings.ToLower(cmd)); err != nil { if err := platformSupports(strings.ToLower(cmd)); err != nil {
buildsFailed.WithValues(metricsCommandNotSupportedError).Inc()
return nil, err return nil, err
} }
@ -155,6 +156,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
processFunc := createProcessWordFunc(options.shlex, cmd, envs) processFunc := createProcessWordFunc(options.shlex, cmd, envs)
words, err := getDispatchArgsFromNode(ast, processFunc, msg) words, err := getDispatchArgsFromNode(ast, processFunc, msg)
if err != nil { if err != nil {
buildsFailed.WithValues(metricsErrorProcessingCommandsError).Inc()
return nil, err return nil, err
} }
args = append(args, words...) args = append(args, words...)
@ -163,6 +165,7 @@ func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
f, ok := evaluateTable[cmd] f, ok := evaluateTable[cmd]
if !ok { if !ok {
buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
return nil, fmt.Errorf("unknown instruction: %s", upperCasedCmd) return nil, fmt.Errorf("unknown instruction: %s", upperCasedCmd)
} }
if err := f(newDispatchRequestFromOptions(options, b, args)); err != nil { if err := f(newDispatchRequestFromOptions(options, b, args)); err != nil {
@ -283,6 +286,7 @@ func checkDispatch(ast *parser.Node) error {
// least one argument // least one argument
if upperCasedCmd == "ONBUILD" { if upperCasedCmd == "ONBUILD" {
if ast.Next == nil { if ast.Next == nil {
buildsFailed.WithValues(metricsMissingOnbuildArgumentsError).Inc()
return errors.New("ONBUILD requires at least one argument") return errors.New("ONBUILD requires at least one argument")
} }
} }
@ -290,6 +294,6 @@ func checkDispatch(ast *parser.Node) error {
if _, ok := evaluateTable[cmd]; ok { if _, ok := evaluateTable[cmd]; ok {
return nil return nil
} }
buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
return errors.Errorf("unknown instruction: %s", upperCasedCmd) 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 // FIXME: this method never returns an error
info, _ := d.SystemInfo() info, _ := d.SystemInfo()
engineVersion.WithValues( engineInfo.WithValues(
dockerversion.Version, dockerversion.Version,
dockerversion.GitCommit, dockerversion.GitCommit,
info.Architecture, info.Architecture,
info.Driver, info.Driver,
info.KernelVersion, info.KernelVersion,
info.OperatingSystem, info.OperatingSystem,
info.OSType,
info.ID,
).Set(1) ).Set(1)
engineCpus.Set(float64(info.NCPU)) engineCpus.Set(float64(info.NCPU))
engineMemory.Set(float64(info.MemTotal)) engineMemory.Set(float64(info.MemTotal))

View file

@ -6,7 +6,7 @@ var (
containerActions metrics.LabeledTimer containerActions metrics.LabeledTimer
imageActions metrics.LabeledTimer imageActions metrics.LabeledTimer
networkActions metrics.LabeledTimer networkActions metrics.LabeledTimer
engineVersion metrics.LabeledGauge engineInfo metrics.LabeledGauge
engineCpus metrics.Gauge engineCpus metrics.Gauge
engineMemory metrics.Gauge engineMemory metrics.Gauge
healthChecksCounter metrics.Counter healthChecksCounter metrics.Counter
@ -26,12 +26,14 @@ func init() {
containerActions.WithValues(a).Update(0) containerActions.WithValues(a).Update(0)
} }
networkActions = ns.NewLabeledTimer("network_actions", "The number of seconds it takes to process each network action", "action") 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", "version",
"commit", "commit",
"architecture", "architecture",
"graph_driver", "kernel", "graphdriver",
"os", "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")) 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) engineMemory = ns.NewGauge("engine_memory", "The number of bytes of memory that the host system of the engine has", metrics.Bytes)