You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2020/11/10 10:20:01 UTC

[camel-k] 01/25: feat: Add build duration histogram metric

This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit c5b45f2f6080e7096487cd695baa0a2a3987cdba
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Mon Oct 12 15:55:02 2020 +0200

    feat: Add build duration histogram metric
---
 go.mod                                   |  1 +
 go.sum                                   |  7 +++++
 pkg/controller/build/metrics.go          | 53 ++++++++++++++++++++++++++++++++
 pkg/controller/build/monitor_pod.go      |  8 +++--
 pkg/controller/build/schedule_routine.go | 19 +++++++-----
 5 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/go.mod b/go.mod
index 12c7fe1..d0ea343 100644
--- a/go.mod
+++ b/go.mod
@@ -24,6 +24,7 @@ require (
 	github.com/operator-framework/operator-lifecycle-manager v0.0.0-20200321030439-57b580e57e88
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.42.1
+	github.com/prometheus/client_golang v1.7.1
 	github.com/radovskyb/watcher v1.0.6
 	github.com/rs/xid v1.2.1
 	github.com/scylladb/go-set v1.0.2
diff --git a/go.sum b/go.sum
index 2a6ab78..b399f5e 100644
--- a/go.sum
+++ b/go.sum
@@ -1012,6 +1012,8 @@ github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh
 github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
 github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
 github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
+github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -1037,6 +1039,8 @@ github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLy
 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
 github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
+github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
 github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -1056,6 +1060,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
 github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
 github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
 github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/statsd_exporter v0.15.0 h1:UiwC1L5HkxEPeapXdm2Ye0u1vUJfTj7uwT5yydYpa1E=
 github.com/prometheus/statsd_exporter v0.15.0/go.mod h1:Dv8HnkoLQkeEjkIE4/2ndAA7WL1zHKK7WMqFQqu72rw=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
@@ -1492,6 +1498,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200802091954-4b90ce9b60b3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/pkg/controller/build/metrics.go b/pkg/controller/build/metrics.go
new file mode 100644
index 0000000..cac2012
--- /dev/null
+++ b/pkg/controller/build/metrics.go
@@ -0,0 +1,53 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package build
+
+import (
+	"time"
+
+	"sigs.k8s.io/controller-runtime/pkg/metrics"
+
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+const buildResult = "result"
+
+var (
+	buildDuration = prometheus.NewHistogramVec(
+		prometheus.HistogramOpts{
+			Name: "camel_k_build_duration_seconds",
+			Help: "Camel K build duration",
+			Buckets: []float64{
+				30 * time.Second.Seconds(),
+				1 * time.Minute.Seconds(),
+				1.5 * time.Minute.Seconds(),
+				2 * time.Minute.Seconds(),
+				5 * time.Minute.Seconds(),
+				10 * time.Minute.Seconds(),
+			},
+		},
+		[]string{
+			buildResult,
+		},
+	)
+)
+
+func init() {
+	// Register custom metrics with the global prometheus registry
+	metrics.Registry.MustRegister(buildDuration)
+}
diff --git a/pkg/controller/build/monitor_pod.go b/pkg/controller/build/monitor_pod.go
index cd6aca1..23ebbee 100644
--- a/pkg/controller/build/monitor_pod.go
+++ b/pkg/controller/build/monitor_pod.go
@@ -67,7 +67,9 @@ func (action *monitorPodAction) Handle(ctx context.Context, build *v1.Build) (*v
 
 	case pod.Status.Phase == corev1.PodSucceeded:
 		build.Status.Phase = v1.BuildPhaseSucceeded
-		build.Status.Duration = metav1.Now().Sub(build.Status.StartedAt.Time).String()
+		duration := metav1.Now().Sub(build.Status.StartedAt.Time)
+		build.Status.Duration = duration.String()
+		buildDuration.WithLabelValues(string(build.Status.Phase)).Observe(duration.Seconds())
 		for _, task := range build.Spec.Tasks {
 			if task.Image != nil {
 				build.Status.Image = task.Image.BuiltImage
@@ -84,7 +86,9 @@ func (action *monitorPodAction) Handle(ctx context.Context, build *v1.Build) (*v
 
 	case pod.Status.Phase == corev1.PodFailed:
 		build.Status.Phase = v1.BuildPhaseFailed
-		build.Status.Duration = metav1.Now().Sub(build.Status.StartedAt.Time).String()
+		duration := metav1.Now().Sub(build.Status.StartedAt.Time)
+		build.Status.Duration = duration.String()
+		buildDuration.WithLabelValues(string(build.Status.Phase)).Observe(duration.Seconds())
 	}
 
 	return build, nil
diff --git a/pkg/controller/build/schedule_routine.go b/pkg/controller/build/schedule_routine.go
index 6edc0f7..86edee6 100644
--- a/pkg/controller/build/schedule_routine.go
+++ b/pkg/controller/build/schedule_routine.go
@@ -22,13 +22,14 @@ import (
 	"fmt"
 	"sync"
 
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/builder"
 	camelevent "github.com/apache/camel-k/pkg/event"
 	"github.com/apache/camel-k/pkg/util/patch"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 // NewScheduleRoutineAction creates a new schedule routine action
@@ -114,13 +115,15 @@ func (action *scheduleRoutineAction) runBuild(ctx context.Context, build *v1.Bui
 
 	for i, task := range build.Spec.Tasks {
 		if task.Builder == nil {
+			duration := metav1.Now().Sub(build.Status.StartedAt.Time)
 			status := v1.BuildStatus{
 				// Error the build directly as we know recovery won't work over ill-defined tasks
 				Phase: v1.BuildPhaseError,
 				Error: fmt.Sprintf("task cannot be executed using the routine strategy: %s",
 					task.GetName()),
-				Duration: metav1.Now().Sub(build.Status.StartedAt.Time).String(),
+				Duration: duration.String(),
 			}
+			buildDuration.WithLabelValues(string(status.Phase)).Observe(duration.Seconds())
 			_ = action.updateBuildStatus(ctx, build, status)
 			break
 		}
@@ -128,12 +131,14 @@ func (action *scheduleRoutineAction) runBuild(ctx context.Context, build *v1.Bui
 		status := action.builder.Run(*task.Builder)
 		lastTask := i == len(build.Spec.Tasks)-1
 		taskFailed := status.Phase == v1.BuildPhaseFailed
-		if lastTask || taskFailed {
-			status.Duration = metav1.Now().Sub(build.Status.StartedAt.Time).String()
-		}
 		if lastTask && !taskFailed {
 			status.Phase = v1.BuildPhaseSucceeded
 		}
+		if lastTask || taskFailed {
+			duration := metav1.Now().Sub(build.Status.StartedAt.Time)
+			status.Duration = duration.String()
+			buildDuration.WithLabelValues(string(status.Phase)).Observe(duration.Seconds())
+		}
 		err := action.updateBuildStatus(ctx, build, status)
 		if err != nil || taskFailed {
 			break