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:
parent
230bc34837
commit
a28b173a78
5 changed files with 63 additions and 6 deletions
|
@ -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...
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
44
builder/dockerfile/metrics.go
Normal file
44
builder/dockerfile/metrics.go
Normal 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)
|
||||
}
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue