Skip to content

Commit 8510512

Browse files
committed
Add test for client metrics
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
1 parent f45269b commit 8510512

File tree

6 files changed

+187
-40
lines changed

6 files changed

+187
-40
lines changed

api/next.pb.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2926,9 +2926,16 @@ file {
29262926
json_name: "timestamp"
29272927
}
29282928
field {
2929-
name: "data"
2929+
name: "id"
29302930
number: 2
29312931
label: LABEL_OPTIONAL
2932+
type: TYPE_STRING
2933+
json_name: "id"
2934+
}
2935+
field {
2936+
name: "data"
2937+
number: 3
2938+
label: LABEL_OPTIONAL
29322939
type: TYPE_MESSAGE
29332940
type_name: ".google.protobuf.Any"
29342941
json_name: "data"

api/types/metrics.pb.go

Lines changed: 64 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/types/metrics.proto

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ message MetricsResponse {
1818

1919
message Metric {
2020
google.protobuf.Timestamp timestamp = 1 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
21-
google.protobuf.Any data = 2;
21+
string id = 2;
22+
google.protobuf.Any data = 3;
2223
}

container_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,3 +1307,61 @@ func TestDeleteContainerExecCreated(t *testing.T) {
13071307
}
13081308
<-finished
13091309
}
1310+
1311+
func TestContainerMetrics(t *testing.T) {
1312+
t.Parallel()
1313+
1314+
client, err := newClient(t, address)
1315+
if err != nil {
1316+
t.Fatal(err)
1317+
}
1318+
defer client.Close()
1319+
1320+
var (
1321+
image Image
1322+
ctx, cancel = testContext()
1323+
id = t.Name()
1324+
)
1325+
defer cancel()
1326+
1327+
if runtime.GOOS != "windows" {
1328+
image, err = client.GetImage(ctx, testImage)
1329+
if err != nil {
1330+
t.Error(err)
1331+
return
1332+
}
1333+
}
1334+
container, err := client.NewContainer(ctx, id, WithNewSpec(withImageConfig(image), WithProcessArgs("sleep", "30")), withNewSnapshot(id, image))
1335+
if err != nil {
1336+
t.Error(err)
1337+
return
1338+
}
1339+
defer container.Delete(ctx, WithSnapshotCleanup)
1340+
1341+
task, err := container.NewTask(ctx, empty())
1342+
if err != nil {
1343+
t.Error(err)
1344+
return
1345+
}
1346+
defer task.Delete(ctx)
1347+
1348+
statusC, err := task.Wait(ctx)
1349+
if err != nil {
1350+
t.Error(err)
1351+
return
1352+
}
1353+
1354+
metric, err := task.Metrics(ctx)
1355+
if err != nil {
1356+
t.Error(err)
1357+
}
1358+
if metric.ID != id {
1359+
t.Errorf("expected metric id %q but received %q", id, metric.ID)
1360+
}
1361+
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
1362+
t.Error(err)
1363+
return
1364+
}
1365+
1366+
<-statusC
1367+
}

services/tasks/service.go

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/containerd/containerd/content"
1919
"github.com/containerd/containerd/errdefs"
2020
"github.com/containerd/containerd/events"
21+
"github.com/containerd/containerd/filters"
2122
"github.com/containerd/containerd/images"
2223
"github.com/containerd/containerd/log"
2324
"github.com/containerd/containerd/metadata"
@@ -457,31 +458,55 @@ func (s *Service) Update(ctx context.Context, r *api.UpdateTaskRequest) (*google
457458
}
458459

459460
func (s *Service) Metrics(ctx context.Context, r *types.MetricsRequest) (*types.MetricsResponse, error) {
461+
filter, err := filters.ParseAll(r.Filters...)
462+
if err != nil {
463+
return nil, err
464+
}
460465
var resp types.MetricsResponse
461466
for _, r := range s.runtimes {
462467
tasks, err := r.Tasks(ctx)
463468
if err != nil {
464469
return nil, err
465470
}
466-
for _, t := range tasks {
467-
collected := time.Now()
468-
metrics, err := t.Metrics(ctx)
469-
if err != nil {
470-
log.G(ctx).WithError(err).Errorf("collecting metrics for %s", t.ID())
471-
continue
472-
}
473-
data, err := typeurl.MarshalAny(metrics)
474-
if err != nil {
475-
log.G(ctx).WithError(err).Errorf("marshal metrics for %s", t.ID())
476-
continue
471+
getTasksMetrics(ctx, filter, tasks, &resp)
472+
}
473+
return &resp, nil
474+
}
475+
476+
func getTasksMetrics(ctx context.Context, filter filters.Filter, tasks []runtime.Task, r *types.MetricsResponse) {
477+
for _, tk := range tasks {
478+
if !filter.Match(filters.AdapterFunc(func(fieldpath []string) (string, bool) {
479+
t := tk
480+
switch fieldpath[0] {
481+
case "id":
482+
return t.ID(), true
483+
case "namespace":
484+
return t.Info().Namespace, true
485+
case "runtime":
486+
return t.Info().Runtime, true
477487
}
478-
resp.Metrics = append(resp.Metrics, &types.Metric{
479-
Timestamp: collected,
480-
Data: data,
481-
})
488+
return "", false
489+
})) {
490+
continue
491+
}
492+
493+
collected := time.Now()
494+
metrics, err := tk.Metrics(ctx)
495+
if err != nil {
496+
log.G(ctx).WithError(err).Errorf("collecting metrics for %s", tk.ID())
497+
continue
482498
}
499+
data, err := typeurl.MarshalAny(metrics)
500+
if err != nil {
501+
log.G(ctx).WithError(err).Errorf("marshal metrics for %s", tk.ID())
502+
continue
503+
}
504+
r.Metrics = append(r.Metrics, &types.Metric{
505+
ID: tk.ID(),
506+
Timestamp: collected,
507+
Data: data,
508+
})
483509
}
484-
return &resp, nil
485510
}
486511

487512
func (s *Service) writeContent(ctx context.Context, mediaType, ref string, r io.Reader) (*types.Descriptor, error) {

task.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ type Task interface {
118118
Update(context.Context, ...UpdateTaskOpts) error
119119
// LoadProcess loads a previously created exec'd process
120120
LoadProcess(context.Context, string, IOAttach) (Process, error)
121+
// Metrics returns task metrics for runtime specific metrics
122+
Metrics(context.Context) (*types.Metric, error)
121123
}
122124

123125
var _ = (Task)(&task{})
@@ -472,6 +474,18 @@ func (t *task) LoadProcess(ctx context.Context, id string, ioAttach IOAttach) (P
472474
}, nil
473475
}
474476

477+
func (t *task) Metrics(ctx context.Context) (*types.Metric, error) {
478+
response, err := t.client.TaskService().Metrics(ctx, &types.MetricsRequest{
479+
Filters: []string{
480+
"id==" + t.id,
481+
},
482+
})
483+
if err != nil {
484+
return nil, errdefs.FromGRPC(err)
485+
}
486+
return response.Metrics[0], nil
487+
}
488+
475489
func (t *task) checkpointTask(ctx context.Context, index *v1.Index, request *tasks.CheckpointTaskRequest) error {
476490
response, err := t.client.TaskService().Checkpoint(ctx, request)
477491
if err != nil {

0 commit comments

Comments
 (0)