Skip to content

Commit 5aa7359

Browse files
CodeJuanzhuangqh
authored andcommitted
feature: pouch metrics
Signed-off-by: codejuan <[email protected]>
1 parent 4002e93 commit 5aa7359

File tree

8 files changed

+327
-3
lines changed

8 files changed

+327
-3
lines changed

apis/metrics/metrics.go

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package metrics
22

33
import (
4+
"fmt"
45
"sync"
56
"time"
67

@@ -13,19 +14,32 @@ func init() {
1314
}
1415

1516
const (
16-
pouchSubsystem = "pouch"
17+
namespace = "engine"
18+
subsystem = "daemon"
1719
)
1820

1921
var (
2022
// ImagePullSummary records the summary of pulling image latency.
2123
ImagePullSummary = prometheus.NewSummaryVec(
2224
prometheus.SummaryOpts{
23-
Subsystem: pouchSubsystem,
25+
Namespace: namespace,
26+
Subsystem: subsystem,
2427
Name: "image_pull_latency_microseconds",
2528
Help: "Latency in microseconds to pull a image.",
2629
},
2730
[]string{"image"},
2831
)
32+
33+
ContainerActionsCounter = newLabelCounter("container_actions_counter", "The number of container operations", "action")
34+
ContainerSuccessActionsCounter = newLabelCounter("container_success_actions_counter", "The number of container success operations", "action")
35+
ImageActionsCounter = newLabelCounter("image_actions_counter", "The number of image operations", "action")
36+
ImageSuccessActionsCounter = newLabelCounter("image_success_actions_counter", "The number of image success operations", "action")
37+
ContainerActionsTimer = newLabelTimer("container_actions", "The number of seconds it takes to process each container action", "action")
38+
ImageActionsTimer = newLabelTimer("image_actions", "The number of seconds it takes to process each image action", "action")
39+
40+
EngineVersion = newLabelGauge("engine", "The version and commit information for the engine process",
41+
"commit",
42+
)
2943
)
3044

3145
var registerMetrics sync.Once
@@ -35,10 +49,51 @@ func Register() {
3549
// Register the metrics.
3650
registerMetrics.Do(func() {
3751
prometheus.MustRegister(ImagePullSummary)
52+
prometheus.MustRegister(EngineVersion)
53+
prometheus.MustRegister(ContainerActionsCounter)
54+
prometheus.MustRegister(ContainerSuccessActionsCounter)
55+
prometheus.MustRegister(ImageActionsCounter)
56+
prometheus.MustRegister(ImageSuccessActionsCounter)
57+
prometheus.MustRegister(ContainerActionsTimer)
58+
prometheus.MustRegister(ImageActionsTimer)
3859
})
3960
}
4061

4162
// SinceInMicroseconds gets the time since the specified start in microseconds.
4263
func SinceInMicroseconds(start time.Time) float64 {
4364
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
4465
}
66+
67+
func newLabelCounter(name, help string, labels ...string) *prometheus.CounterVec {
68+
return prometheus.NewCounterVec(
69+
prometheus.CounterOpts{
70+
Namespace: namespace,
71+
Subsystem: subsystem,
72+
Name: fmt.Sprintf("%s_%s", name, Total),
73+
Help: help,
74+
ConstLabels: nil,
75+
},
76+
labels)
77+
}
78+
79+
func newLabelGauge(name, help string, labels ...string) *prometheus.GaugeVec {
80+
return prometheus.NewGaugeVec(
81+
prometheus.GaugeOpts{
82+
Namespace: namespace,
83+
Subsystem: subsystem,
84+
Name: fmt.Sprintf("%s_%s", name, Unit("info")),
85+
Help: help,
86+
ConstLabels: nil,
87+
}, labels)
88+
}
89+
90+
func newLabelTimer(name, help string, labels ...string) *prometheus.HistogramVec {
91+
return prometheus.NewHistogramVec(
92+
prometheus.HistogramOpts{
93+
Namespace: namespace,
94+
Subsystem: subsystem,
95+
Name: fmt.Sprintf("%s_%s", name, Seconds),
96+
Help: help,
97+
ConstLabels: nil,
98+
}, labels)
99+
}

apis/metrics/unit.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package metrics
2+
3+
// Unit represents the type or precision of a metric that is appended to
4+
// the metrics fully qualified name
5+
type Unit string
6+
7+
const (
8+
Nanoseconds Unit = "nanoseconds"
9+
Seconds Unit = "seconds"
10+
Bytes Unit = "bytes"
11+
Total Unit = "total"
12+
)

apis/server/container_bridge.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strings"
1010
"time"
1111

12+
"github.com/alibaba/pouch/apis/metrics"
1213
"github.com/alibaba/pouch/apis/types"
1314
"github.com/alibaba/pouch/daemon/mgr"
1415
"github.com/alibaba/pouch/pkg/httputils"
@@ -22,6 +23,12 @@ import (
2223
)
2324

2425
func (s *Server) createContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
26+
label := "create"
27+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
28+
defer func(start time.Time) {
29+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
30+
}(time.Now())
31+
2532
config := &types.ContainerCreateConfig{}
2633
reader := req.Body
2734
var ex error
@@ -57,6 +64,8 @@ func (s *Server) createContainer(ctx context.Context, rw http.ResponseWriter, re
5764
return err
5865
}
5966

67+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
68+
6069
return EncodeResponse(rw, http.StatusCreated, container)
6170
}
6271

@@ -150,6 +159,12 @@ func (s *Server) getContainers(ctx context.Context, rw http.ResponseWriter, req
150159
}
151160

152161
func (s *Server) startContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
162+
label := "start"
163+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
164+
defer func(start time.Time) {
165+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
166+
}(time.Now())
167+
153168
name := mux.Vars(req)["name"]
154169

155170
options := &types.ContainerStartOptions{
@@ -162,6 +177,8 @@ func (s *Server) startContainer(ctx context.Context, rw http.ResponseWriter, req
162177
return err
163178
}
164179

180+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
181+
165182
rw.WriteHeader(http.StatusNoContent)
166183
return nil
167184
}
@@ -171,6 +188,11 @@ func (s *Server) restartContainer(ctx context.Context, rw http.ResponseWriter, r
171188
t int
172189
err error
173190
)
191+
label := "restart"
192+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
193+
defer func(start time.Time) {
194+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
195+
}(time.Now())
174196

175197
if v := req.FormValue("t"); v != "" {
176198
if t, err = strconv.Atoi(v); err != nil {
@@ -184,6 +206,8 @@ func (s *Server) restartContainer(ctx context.Context, rw http.ResponseWriter, r
184206
return err
185207
}
186208

209+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
210+
187211
rw.WriteHeader(http.StatusNoContent)
188212
return nil
189213
}
@@ -194,6 +218,12 @@ func (s *Server) stopContainer(ctx context.Context, rw http.ResponseWriter, req
194218
err error
195219
)
196220

221+
label := "stop"
222+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
223+
defer func(start time.Time) {
224+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
225+
}(time.Now())
226+
197227
if v := req.FormValue("t"); v != "" {
198228
if t, err = strconv.Atoi(v); err != nil {
199229
return httputils.NewHTTPError(err, http.StatusBadRequest)
@@ -206,6 +236,8 @@ func (s *Server) stopContainer(ctx context.Context, rw http.ResponseWriter, req
206236
return err
207237
}
208238

239+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
240+
209241
rw.WriteHeader(http.StatusNoContent)
210242
return nil
211243
}
@@ -233,13 +265,21 @@ func (s *Server) unpauseContainer(ctx context.Context, rw http.ResponseWriter, r
233265
}
234266

235267
func (s *Server) renameContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
268+
label := "rename"
269+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
270+
defer func(start time.Time) {
271+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
272+
}(time.Now())
273+
236274
oldName := mux.Vars(req)["name"]
237275
newName := req.FormValue("name")
238276

239277
if err := s.ContainerMgr.Rename(ctx, oldName, newName); err != nil {
240278
return err
241279
}
242280

281+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
282+
243283
rw.WriteHeader(http.StatusNoContent)
244284
return nil
245285
}
@@ -270,6 +310,12 @@ func (s *Server) attachContainer(ctx context.Context, rw http.ResponseWriter, re
270310
}
271311

272312
func (s *Server) updateContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
313+
label := "update"
314+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
315+
defer func(start time.Time) {
316+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
317+
}(time.Now())
318+
273319
config := &types.UpdateConfig{}
274320

275321
// set pre update hook plugin
@@ -293,11 +339,19 @@ func (s *Server) updateContainer(ctx context.Context, rw http.ResponseWriter, re
293339
return httputils.NewHTTPError(err, http.StatusInternalServerError)
294340
}
295341

342+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
343+
296344
rw.WriteHeader(http.StatusOK)
297345
return nil
298346
}
299347

300348
func (s *Server) upgradeContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
349+
label := "upgrade"
350+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
351+
defer func(start time.Time) {
352+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
353+
}(time.Now())
354+
301355
config := &types.ContainerUpgradeConfig{}
302356
// decode request body
303357
if err := json.NewDecoder(req.Body).Decode(config); err != nil {
@@ -314,6 +368,8 @@ func (s *Server) upgradeContainer(ctx context.Context, rw http.ResponseWriter, r
314368
return err
315369
}
316370

371+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
372+
317373
rw.WriteHeader(http.StatusOK)
318374
return nil
319375
}
@@ -399,6 +455,12 @@ func (s *Server) resizeContainer(ctx context.Context, rw http.ResponseWriter, re
399455
}
400456

401457
func (s *Server) removeContainers(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
458+
label := "delete"
459+
metrics.ContainerActionsCounter.WithLabelValues(label).Inc()
460+
defer func(start time.Time) {
461+
metrics.ContainerActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
462+
}(time.Now())
463+
402464
name := mux.Vars(req)["name"]
403465

404466
option := &types.ContainerRemoveOptions{
@@ -412,6 +474,8 @@ func (s *Server) removeContainers(ctx context.Context, rw http.ResponseWriter, r
412474
return err
413475
}
414476

477+
metrics.ContainerSuccessActionsCounter.WithLabelValues(label).Inc()
478+
415479
rw.WriteHeader(http.StatusNoContent)
416480
return nil
417481
}

apis/server/image_bridge.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ func (s *Server) pullImage(ctx context.Context, rw http.ResponseWriter, req *htt
3434
image = image + ":" + tag
3535
}
3636

37+
label := "pull"
38+
metrics.ImageActionsCounter.WithLabelValues(label).Inc()
39+
3740
// record the time spent during image pull procedure.
3841
defer func(start time.Time) {
3942
metrics.ImagePullSummary.WithLabelValues(image).Observe(metrics.SinceInMicroseconds(start))
43+
metrics.ImageActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
4044
}(time.Now())
4145

4246
// get registry auth from Request header
@@ -53,6 +57,7 @@ func (s *Server) pullImage(ctx context.Context, rw http.ResponseWriter, req *htt
5357
logrus.Errorf("failed to pull image %s: %v", image, err)
5458
return nil
5559
}
60+
metrics.ImageSuccessActionsCounter.WithLabelValues(label).Inc()
5661
return nil
5762
}
5863

@@ -105,6 +110,12 @@ func (s *Server) removeImage(ctx context.Context, rw http.ResponseWriter, req *h
105110
return err
106111
}
107112

113+
label := "delete"
114+
metrics.ImageActionsCounter.WithLabelValues(label).Inc()
115+
defer func(start time.Time) {
116+
metrics.ImageActionsTimer.WithLabelValues(label).Observe(time.Since(start).Seconds())
117+
}(time.Now())
118+
108119
isForce := httputils.BoolValue(req, "force")
109120
// We only should check the image whether used by container when there is only one primary reference.
110121
if len(refs) == 1 {
@@ -126,6 +137,7 @@ func (s *Server) removeImage(ctx context.Context, rw http.ResponseWriter, req *h
126137
return err
127138
}
128139

140+
metrics.ImageSuccessActionsCounter.WithLabelValues(label).Inc()
129141
rw.WriteHeader(http.StatusNoContent)
130142
return nil
131143
}

main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"syscall"
1010
"time"
1111

12+
"github.com/alibaba/pouch/apis/metrics"
1213
"github.com/alibaba/pouch/apis/opts"
1314
optscfg "github.com/alibaba/pouch/apis/opts/config"
1415
"github.com/alibaba/pouch/apis/types"
@@ -150,7 +151,7 @@ func runDaemon(cmd *cobra.Command) error {
150151
fmt.Printf("pouchd version: %s, build: %s, build at: %s\n", version.Version, version.GitCommit, version.BuildTime)
151152
return nil
152153
}
153-
154+
metrics.EngineVersion.WithLabelValues(version.GitCommit).Set(1)
154155
// initialize log.
155156
initLog()
156157

0 commit comments

Comments
 (0)