Merge pull request #1468 from crosbymichael/stats

Add Metrics endpoint to tasks
This commit is contained in:
Kenfe-Mickaël Laventure 2017-09-06 14:59:55 -07:00 committed by GitHub
commit e66d1a7961
37 changed files with 5270 additions and 367 deletions

View File

@ -2884,10 +2884,52 @@ file {
} }
syntax: "proto3" syntax: "proto3"
} }
file {
name: "github.com/containerd/containerd/api/types/metrics.proto"
package: "containerd.types"
dependency: "gogoproto/gogo.proto"
dependency: "google/protobuf/any.proto"
dependency: "google/protobuf/timestamp.proto"
message_type {
name: "Metric"
field {
name: "timestamp"
number: 1
label: LABEL_OPTIONAL
type: TYPE_MESSAGE
type_name: ".google.protobuf.Timestamp"
options {
65010: 1
65001: 0
}
json_name: "timestamp"
}
field {
name: "id"
number: 2
label: LABEL_OPTIONAL
type: TYPE_STRING
json_name: "id"
}
field {
name: "data"
number: 3
label: LABEL_OPTIONAL
type: TYPE_MESSAGE
type_name: ".google.protobuf.Any"
json_name: "data"
}
}
options {
go_package: "github.com/containerd/containerd/api/types;types"
}
syntax: "proto3"
}
file { file {
name: "github.com/containerd/containerd/api/types/task/task.proto" name: "github.com/containerd/containerd/api/types/task/task.proto"
package: "containerd.v1.types" package: "containerd.v1.types"
dependency: "gogoproto/gogo.proto" dependency: "gogoproto/gogo.proto"
dependency: "google/protobuf/timestamp.proto"
message_type { message_type {
name: "Process" name: "Process"
field { field {
@ -2954,6 +2996,18 @@ file {
type: TYPE_UINT32 type: TYPE_UINT32
json_name: "exitStatus" json_name: "exitStatus"
} }
field {
name: "exited_at"
number: 10
label: LABEL_OPTIONAL
type: TYPE_MESSAGE
type_name: ".google.protobuf.Timestamp"
options {
65010: 1
65001: 0
}
json_name: "exitedAt"
}
} }
enum_type { enum_type {
name: "Status" name: "Status"
@ -3013,6 +3067,7 @@ file {
dependency: "google/protobuf/any.proto" dependency: "google/protobuf/any.proto"
dependency: "gogoproto/gogo.proto" dependency: "gogoproto/gogo.proto"
dependency: "github.com/containerd/containerd/api/types/mount.proto" dependency: "github.com/containerd/containerd/api/types/mount.proto"
dependency: "github.com/containerd/containerd/api/types/metrics.proto"
dependency: "github.com/containerd/containerd/api/types/descriptor.proto" dependency: "github.com/containerd/containerd/api/types/descriptor.proto"
dependency: "github.com/containerd/containerd/api/types/task/task.proto" dependency: "github.com/containerd/containerd/api/types/task/task.proto"
dependency: "google/protobuf/timestamp.proto" dependency: "google/protobuf/timestamp.proto"
@ -3474,6 +3529,27 @@ file {
json_name: "resources" json_name: "resources"
} }
} }
message_type {
name: "MetricsRequest"
field {
name: "filters"
number: 1
label: LABEL_REPEATED
type: TYPE_STRING
json_name: "filters"
}
}
message_type {
name: "MetricsResponse"
field {
name: "metrics"
number: 1
label: LABEL_REPEATED
type: TYPE_MESSAGE
type_name: ".containerd.types.Metric"
json_name: "metrics"
}
}
service { service {
name: "Tasks" name: "Tasks"
method { method {
@ -3551,6 +3627,11 @@ file {
input_type: ".containerd.services.tasks.v1.UpdateTaskRequest" input_type: ".containerd.services.tasks.v1.UpdateTaskRequest"
output_type: ".google.protobuf.Empty" output_type: ".google.protobuf.Empty"
} }
method {
name: "Metrics"
input_type: ".containerd.services.tasks.v1.MetricsRequest"
output_type: ".containerd.services.tasks.v1.MetricsResponse"
}
} }
options { options {
go_package: "github.com/containerd/containerd/api/services/tasks/v1;tasks" go_package: "github.com/containerd/containerd/api/services/tasks/v1;tasks"

View File

@ -32,6 +32,8 @@
CheckpointTaskRequest CheckpointTaskRequest
CheckpointTaskResponse CheckpointTaskResponse
UpdateTaskRequest UpdateTaskRequest
MetricsRequest
MetricsResponse
*/ */
package tasks package tasks
@ -43,6 +45,7 @@ import google_protobuf1 "github.com/gogo/protobuf/types"
import _ "github.com/gogo/protobuf/gogoproto" import _ "github.com/gogo/protobuf/gogoproto"
import containerd_types "github.com/containerd/containerd/api/types" import containerd_types "github.com/containerd/containerd/api/types"
import containerd_types1 "github.com/containerd/containerd/api/types" import containerd_types1 "github.com/containerd/containerd/api/types"
import containerd_types2 "github.com/containerd/containerd/api/types"
import containerd_v1_types "github.com/containerd/containerd/api/types/task" import containerd_v1_types "github.com/containerd/containerd/api/types/task"
import _ "github.com/gogo/protobuf/types" import _ "github.com/gogo/protobuf/types"
@ -86,7 +89,7 @@ type CreateTaskRequest struct {
Stdout string `protobuf:"bytes,5,opt,name=stdout,proto3" json:"stdout,omitempty"` Stdout string `protobuf:"bytes,5,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,6,opt,name=stderr,proto3" json:"stderr,omitempty"` Stderr string `protobuf:"bytes,6,opt,name=stderr,proto3" json:"stderr,omitempty"`
Terminal bool `protobuf:"varint,7,opt,name=terminal,proto3" json:"terminal,omitempty"` Terminal bool `protobuf:"varint,7,opt,name=terminal,proto3" json:"terminal,omitempty"`
Checkpoint *containerd_types1.Descriptor `protobuf:"bytes,8,opt,name=checkpoint" json:"checkpoint,omitempty"` Checkpoint *containerd_types2.Descriptor `protobuf:"bytes,8,opt,name=checkpoint" json:"checkpoint,omitempty"`
Options *google_protobuf1.Any `protobuf:"bytes,9,opt,name=options" json:"options,omitempty"` Options *google_protobuf1.Any `protobuf:"bytes,9,opt,name=options" json:"options,omitempty"`
} }
@ -281,7 +284,7 @@ func (*CheckpointTaskRequest) ProtoMessage() {}
func (*CheckpointTaskRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{20} } func (*CheckpointTaskRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{20} }
type CheckpointTaskResponse struct { type CheckpointTaskResponse struct {
Descriptors []*containerd_types1.Descriptor `protobuf:"bytes,1,rep,name=descriptors" json:"descriptors,omitempty"` Descriptors []*containerd_types2.Descriptor `protobuf:"bytes,1,rep,name=descriptors" json:"descriptors,omitempty"`
} }
func (m *CheckpointTaskResponse) Reset() { *m = CheckpointTaskResponse{} } func (m *CheckpointTaskResponse) Reset() { *m = CheckpointTaskResponse{} }
@ -297,6 +300,22 @@ func (m *UpdateTaskRequest) Reset() { *m = UpdateTaskRequest{
func (*UpdateTaskRequest) ProtoMessage() {} func (*UpdateTaskRequest) ProtoMessage() {}
func (*UpdateTaskRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{22} } func (*UpdateTaskRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{22} }
type MetricsRequest struct {
Filters []string `protobuf:"bytes,1,rep,name=filters" json:"filters,omitempty"`
}
func (m *MetricsRequest) Reset() { *m = MetricsRequest{} }
func (*MetricsRequest) ProtoMessage() {}
func (*MetricsRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{23} }
type MetricsResponse struct {
Metrics []*containerd_types1.Metric `protobuf:"bytes,1,rep,name=metrics" json:"metrics,omitempty"`
}
func (m *MetricsResponse) Reset() { *m = MetricsResponse{} }
func (*MetricsResponse) ProtoMessage() {}
func (*MetricsResponse) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{24} }
func init() { func init() {
proto.RegisterType((*CreateTaskRequest)(nil), "containerd.services.tasks.v1.CreateTaskRequest") proto.RegisterType((*CreateTaskRequest)(nil), "containerd.services.tasks.v1.CreateTaskRequest")
proto.RegisterType((*CreateTaskResponse)(nil), "containerd.services.tasks.v1.CreateTaskResponse") proto.RegisterType((*CreateTaskResponse)(nil), "containerd.services.tasks.v1.CreateTaskResponse")
@ -321,6 +340,8 @@ func init() {
proto.RegisterType((*CheckpointTaskRequest)(nil), "containerd.services.tasks.v1.CheckpointTaskRequest") proto.RegisterType((*CheckpointTaskRequest)(nil), "containerd.services.tasks.v1.CheckpointTaskRequest")
proto.RegisterType((*CheckpointTaskResponse)(nil), "containerd.services.tasks.v1.CheckpointTaskResponse") proto.RegisterType((*CheckpointTaskResponse)(nil), "containerd.services.tasks.v1.CheckpointTaskResponse")
proto.RegisterType((*UpdateTaskRequest)(nil), "containerd.services.tasks.v1.UpdateTaskRequest") proto.RegisterType((*UpdateTaskRequest)(nil), "containerd.services.tasks.v1.UpdateTaskRequest")
proto.RegisterType((*MetricsRequest)(nil), "containerd.services.tasks.v1.MetricsRequest")
proto.RegisterType((*MetricsResponse)(nil), "containerd.services.tasks.v1.MetricsResponse")
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -353,6 +374,7 @@ type TasksClient interface {
ListPids(ctx context.Context, in *ListPidsRequest, opts ...grpc.CallOption) (*ListPidsResponse, error) ListPids(ctx context.Context, in *ListPidsRequest, opts ...grpc.CallOption) (*ListPidsResponse, error)
Checkpoint(ctx context.Context, in *CheckpointTaskRequest, opts ...grpc.CallOption) (*CheckpointTaskResponse, error) Checkpoint(ctx context.Context, in *CheckpointTaskRequest, opts ...grpc.CallOption) (*CheckpointTaskResponse, error)
Update(ctx context.Context, in *UpdateTaskRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error) Update(ctx context.Context, in *UpdateTaskRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
Metrics(ctx context.Context, in *MetricsRequest, opts ...grpc.CallOption) (*MetricsResponse, error)
} }
type tasksClient struct { type tasksClient struct {
@ -498,6 +520,15 @@ func (c *tasksClient) Update(ctx context.Context, in *UpdateTaskRequest, opts ..
return out, nil return out, nil
} }
func (c *tasksClient) Metrics(ctx context.Context, in *MetricsRequest, opts ...grpc.CallOption) (*MetricsResponse, error) {
out := new(MetricsResponse)
err := grpc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Metrics", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Tasks service // Server API for Tasks service
type TasksServer interface { type TasksServer interface {
@ -520,6 +551,7 @@ type TasksServer interface {
ListPids(context.Context, *ListPidsRequest) (*ListPidsResponse, error) ListPids(context.Context, *ListPidsRequest) (*ListPidsResponse, error)
Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error) Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error)
Update(context.Context, *UpdateTaskRequest) (*google_protobuf.Empty, error) Update(context.Context, *UpdateTaskRequest) (*google_protobuf.Empty, error)
Metrics(context.Context, *MetricsRequest) (*MetricsResponse, error)
} }
func RegisterTasksServer(s *grpc.Server, srv TasksServer) { func RegisterTasksServer(s *grpc.Server, srv TasksServer) {
@ -796,6 +828,24 @@ func _Tasks_Update_Handler(srv interface{}, ctx context.Context, dec func(interf
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Tasks_Metrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MetricsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TasksServer).Metrics(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/containerd.services.tasks.v1.Tasks/Metrics",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TasksServer).Metrics(ctx, req.(*MetricsRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Tasks_serviceDesc = grpc.ServiceDesc{ var _Tasks_serviceDesc = grpc.ServiceDesc{
ServiceName: "containerd.services.tasks.v1.Tasks", ServiceName: "containerd.services.tasks.v1.Tasks",
HandlerType: (*TasksServer)(nil), HandlerType: (*TasksServer)(nil),
@ -860,6 +910,10 @@ var _Tasks_serviceDesc = grpc.ServiceDesc{
MethodName: "Update", MethodName: "Update",
Handler: _Tasks_Update_Handler, Handler: _Tasks_Update_Handler,
}, },
{
MethodName: "Metrics",
Handler: _Tasks_Metrics_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "github.com/containerd/containerd/api/services/tasks/v1/tasks.proto", Metadata: "github.com/containerd/containerd/api/services/tasks/v1/tasks.proto",
@ -1661,6 +1715,69 @@ func (m *UpdateTaskRequest) MarshalTo(dAtA []byte) (int, error) {
return i, nil return i, nil
} }
func (m *MetricsRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *MetricsRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Filters) > 0 {
for _, s := range m.Filters {
dAtA[i] = 0xa
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
func (m *MetricsResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *MetricsResponse) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Metrics) > 0 {
for _, msg := range m.Metrics {
dAtA[i] = 0xa
i++
i = encodeVarintTasks(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
func encodeFixed64Tasks(dAtA []byte, offset int, v uint64) int { func encodeFixed64Tasks(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v) dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8) dAtA[offset+1] = uint8(v >> 8)
@ -2034,6 +2151,30 @@ func (m *UpdateTaskRequest) Size() (n int) {
return n return n
} }
func (m *MetricsRequest) Size() (n int) {
var l int
_ = l
if len(m.Filters) > 0 {
for _, s := range m.Filters {
l = len(s)
n += 1 + l + sovTasks(uint64(l))
}
}
return n
}
func (m *MetricsResponse) Size() (n int) {
var l int
_ = l
if len(m.Metrics) > 0 {
for _, e := range m.Metrics {
l = e.Size()
n += 1 + l + sovTasks(uint64(l))
}
}
return n
}
func sovTasks(x uint64) (n int) { func sovTasks(x uint64) (n int) {
for { for {
n++ n++
@ -2058,7 +2199,7 @@ func (this *CreateTaskRequest) String() string {
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`, `Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`, `Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
`Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`, `Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`,
`Checkpoint:` + strings.Replace(fmt.Sprintf("%v", this.Checkpoint), "Descriptor", "containerd_types1.Descriptor", 1) + `,`, `Checkpoint:` + strings.Replace(fmt.Sprintf("%v", this.Checkpoint), "Descriptor", "containerd_types2.Descriptor", 1) + `,`,
`Options:` + strings.Replace(fmt.Sprintf("%v", this.Options), "Any", "google_protobuf1.Any", 1) + `,`, `Options:` + strings.Replace(fmt.Sprintf("%v", this.Options), "Any", "google_protobuf1.Any", 1) + `,`,
`}`, `}`,
}, "") }, "")
@ -2291,7 +2432,7 @@ func (this *CheckpointTaskResponse) String() string {
return "nil" return "nil"
} }
s := strings.Join([]string{`&CheckpointTaskResponse{`, s := strings.Join([]string{`&CheckpointTaskResponse{`,
`Descriptors:` + strings.Replace(fmt.Sprintf("%v", this.Descriptors), "Descriptor", "containerd_types1.Descriptor", 1) + `,`, `Descriptors:` + strings.Replace(fmt.Sprintf("%v", this.Descriptors), "Descriptor", "containerd_types2.Descriptor", 1) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -2307,6 +2448,26 @@ func (this *UpdateTaskRequest) String() string {
}, "") }, "")
return s return s
} }
func (this *MetricsRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&MetricsRequest{`,
`Filters:` + fmt.Sprintf("%v", this.Filters) + `,`,
`}`,
}, "")
return s
}
func (this *MetricsResponse) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&MetricsResponse{`,
`Metrics:` + strings.Replace(fmt.Sprintf("%v", this.Metrics), "Metric", "containerd_types1.Metric", 1) + `,`,
`}`,
}, "")
return s
}
func valueToStringTasks(v interface{}) string { func valueToStringTasks(v interface{}) string {
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if rv.IsNil() { if rv.IsNil() {
@ -2538,7 +2699,7 @@ func (m *CreateTaskRequest) Unmarshal(dAtA []byte) error {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if m.Checkpoint == nil { if m.Checkpoint == nil {
m.Checkpoint = &containerd_types1.Descriptor{} m.Checkpoint = &containerd_types2.Descriptor{}
} }
if err := m.Checkpoint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Checkpoint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
@ -4822,7 +4983,7 @@ func (m *CheckpointTaskResponse) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Descriptors = append(m.Descriptors, &containerd_types1.Descriptor{}) m.Descriptors = append(m.Descriptors, &containerd_types2.Descriptor{})
if err := m.Descriptors[len(m.Descriptors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.Descriptors[len(m.Descriptors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
@ -4960,6 +5121,166 @@ func (m *UpdateTaskRequest) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *MetricsRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: MetricsRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MetricsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Filters = append(m.Filters, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTasks(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTasks
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *MetricsResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: MetricsResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MetricsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Metrics", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Metrics = append(m.Metrics, &containerd_types1.Metric{})
if err := m.Metrics[len(m.Metrics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTasks(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTasks
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTasks(dAtA []byte) (n int, err error) { func skipTasks(dAtA []byte) (n int, err error) {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
@ -5070,81 +5391,85 @@ func init() {
} }
var fileDescriptorTasks = []byte{ var fileDescriptorTasks = []byte{
// 1207 bytes of a gzipped FileDescriptorProto // 1274 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x6f, 0x1b, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xef, 0xfa, 0x63, 0x6d, 0x3f, 0x37, 0x6d, 0x32, 0xa4, 0xc1, 0x2c, 0x95, 0x1d, 0x16, 0x09, 0x14, 0xef, 0xc6, 0xf6, 0xda, 0x7e, 0x6e, 0xda, 0x64, 0x48, 0xc3, 0xb2, 0x54, 0x71, 0x58, 0x24,
0x99, 0x42, 0x77, 0xa9, 0x8b, 0x7a, 0xa0, 0x15, 0x52, 0x13, 0x87, 0xc8, 0x02, 0xd4, 0x74, 0x53, 0x64, 0x02, 0xdd, 0xa5, 0x2e, 0xaa, 0x10, 0xad, 0x90, 0x9a, 0x3f, 0x44, 0x16, 0x54, 0x4d, 0xb7,
0x10, 0xca, 0xc5, 0x6c, 0xbc, 0x13, 0x67, 0x14, 0x7b, 0x77, 0xbb, 0x33, 0x4e, 0x13, 0x38, 0xc0, 0x05, 0xa1, 0x5e, 0xc2, 0x76, 0x77, 0xe2, 0x8c, 0x62, 0xef, 0x6e, 0x77, 0xc6, 0x69, 0x03, 0x07,
0x9f, 0xd0, 0x0b, 0x07, 0x2e, 0xfc, 0x3d, 0x39, 0x72, 0x44, 0x08, 0x05, 0xea, 0xff, 0x82, 0x1b, 0xf8, 0x08, 0xbd, 0x72, 0xe1, 0xf3, 0xe4, 0xc8, 0x11, 0x21, 0x14, 0xa8, 0xbf, 0x05, 0x07, 0x24,
0x9a, 0x0f, 0x6f, 0x36, 0x76, 0xfc, 0x91, 0xba, 0xe1, 0x92, 0xcc, 0xcc, 0xbe, 0xaf, 0xf9, 0xbd, 0x34, 0x7f, 0x76, 0xb3, 0xb1, 0xe3, 0xd8, 0xa9, 0x1b, 0x2e, 0xed, 0xcc, 0xec, 0xef, 0xbd, 0x79,
0x37, 0xbf, 0xf7, 0x12, 0x58, 0x6b, 0x13, 0xb6, 0xdf, 0xdb, 0xb5, 0x5a, 0x41, 0xd7, 0x6e, 0x05, 0xf3, 0x9b, 0x37, 0xef, 0xfd, 0x1c, 0x58, 0x6d, 0x13, 0xb6, 0xdb, 0x7b, 0x6a, 0xfb, 0x51, 0xd7,
0x3e, 0x73, 0x89, 0x8f, 0x23, 0x2f, 0xb9, 0x74, 0x43, 0x62, 0x53, 0x1c, 0x1d, 0x92, 0x16, 0xa6, 0xf1, 0xa3, 0x90, 0x79, 0x24, 0xc4, 0x49, 0x90, 0x1f, 0x7a, 0x31, 0x71, 0x28, 0x4e, 0xf6, 0x89,
0x36, 0x73, 0xe9, 0x01, 0xb5, 0x0f, 0xef, 0xc9, 0x85, 0x15, 0x46, 0x01, 0x0b, 0xd0, 0xed, 0x33, 0x8f, 0xa9, 0xc3, 0x3c, 0xba, 0x47, 0x9d, 0xfd, 0x9b, 0x72, 0x60, 0xc7, 0x49, 0xc4, 0x22, 0x74,
0x69, 0x6b, 0x20, 0x69, 0x49, 0x81, 0xc3, 0x7b, 0xc6, 0xbb, 0xed, 0x20, 0x68, 0x77, 0xb0, 0x2d, 0xfd, 0x18, 0x6d, 0xa7, 0x48, 0x5b, 0x02, 0xf6, 0x6f, 0x9a, 0xef, 0xb6, 0xa3, 0xa8, 0xdd, 0xc1,
0x64, 0x77, 0x7b, 0x7b, 0x36, 0xee, 0x86, 0xec, 0x58, 0xaa, 0x1a, 0xef, 0x0c, 0x7f, 0x74, 0xfd, 0x8e, 0xc0, 0x3e, 0xed, 0xed, 0x38, 0xb8, 0x1b, 0xb3, 0x03, 0x69, 0x6a, 0xbe, 0x33, 0xf8, 0xd1,
0xc1, 0xa7, 0xe5, 0x76, 0xd0, 0x0e, 0xc4, 0xd2, 0xe6, 0x2b, 0x75, 0xfa, 0x60, 0xa6, 0x78, 0xd9, 0x0b, 0xd3, 0x4f, 0x0b, 0xed, 0xa8, 0x1d, 0x89, 0xa1, 0xc3, 0x47, 0x6a, 0xf5, 0xf6, 0x44, 0xf1,
0x71, 0x88, 0xa9, 0xdd, 0x0d, 0x7a, 0x3e, 0x53, 0x7a, 0x0f, 0x2f, 0xa1, 0xe7, 0x61, 0xda, 0x8a, 0xb2, 0x83, 0x18, 0x53, 0xa7, 0x1b, 0xf5, 0x42, 0xa6, 0xec, 0x3e, 0x3b, 0x8f, 0x1d, 0x66, 0x09,
0x48, 0xc8, 0x82, 0x48, 0x29, 0x7f, 0x76, 0x09, 0x65, 0x7e, 0x6f, 0xf1, 0x43, 0xe9, 0x56, 0x86, 0xf1, 0xd5, 0xe9, 0xcc, 0x3b, 0xe7, 0xb0, 0x0c, 0x30, 0xf5, 0x13, 0x12, 0xb3, 0x28, 0x51, 0xc6,
0x6f, 0xc8, 0x48, 0x17, 0x53, 0xe6, 0x76, 0x43, 0x29, 0x60, 0x9e, 0xa4, 0x60, 0x69, 0x3d, 0xc2, 0x9f, 0x9f, 0xc3, 0x98, 0x33, 0x26, 0xfe, 0x51, 0xb6, 0xf5, 0x41, 0x6e, 0x18, 0xe9, 0x62, 0xca,
0x2e, 0xc3, 0xcf, 0x5c, 0x7a, 0xe0, 0xe0, 0xe7, 0x3d, 0x4c, 0x19, 0xaa, 0xc1, 0xf5, 0xd8, 0x7c, 0xbc, 0x6e, 0x2c, 0x01, 0xd6, 0xe1, 0x0c, 0xcc, 0xaf, 0x25, 0xd8, 0x63, 0xf8, 0xb1, 0x47, 0xf7,
0x93, 0x78, 0x25, 0x6d, 0x55, 0xab, 0x16, 0xd6, 0x6e, 0xf6, 0x4f, 0x2b, 0xc5, 0xf5, 0xc1, 0x79, 0x5c, 0xfc, 0xac, 0x87, 0x29, 0x43, 0x4d, 0xb8, 0x9c, 0xb9, 0xdf, 0x26, 0x81, 0xa1, 0x2d, 0x6b,
0xa3, 0xee, 0x14, 0x63, 0xa1, 0x86, 0x87, 0x6c, 0xd0, 0xa3, 0x20, 0x60, 0x7b, 0xb4, 0x94, 0x5e, 0x8d, 0xea, 0xea, 0xd5, 0xfe, 0x51, 0xbd, 0xb6, 0x96, 0xae, 0xb7, 0xd6, 0xdd, 0x5a, 0x06, 0x6a,
0x4d, 0x57, 0x8b, 0xb5, 0xb7, 0xad, 0x44, 0x62, 0x44, 0x74, 0xd6, 0xd7, 0x1c, 0x12, 0x47, 0x89, 0x05, 0xc8, 0x01, 0x3d, 0x89, 0x22, 0xb6, 0x43, 0x8d, 0xc2, 0x72, 0xa1, 0x51, 0x6b, 0xbe, 0x6d,
0xa1, 0x65, 0xc8, 0x52, 0xe6, 0x11, 0xbf, 0x94, 0xe1, 0xd6, 0x1d, 0xb9, 0x41, 0x2b, 0xa0, 0x53, 0xe7, 0xae, 0x54, 0x44, 0x67, 0xdf, 0xe7, 0x64, 0xba, 0x0a, 0x86, 0x16, 0xa0, 0x44, 0x59, 0x40,
0xe6, 0x05, 0x3d, 0x56, 0xca, 0x8a, 0x63, 0xb5, 0x53, 0xe7, 0x38, 0x8a, 0x4a, 0x7a, 0x7c, 0x8e, 0x42, 0xa3, 0xc8, 0xbd, 0xbb, 0x72, 0x82, 0x16, 0x41, 0xa7, 0x2c, 0x88, 0x7a, 0xcc, 0x28, 0x89,
0xa3, 0x08, 0x19, 0x90, 0x67, 0x38, 0xea, 0x12, 0xdf, 0xed, 0x94, 0x72, 0xab, 0x5a, 0x35, 0xef, 0x65, 0x35, 0x53, 0xeb, 0x38, 0x49, 0x0c, 0x3d, 0x5b, 0xc7, 0x49, 0x82, 0x4c, 0xa8, 0x30, 0x9c,
0xc4, 0x7b, 0xf4, 0x08, 0xa0, 0xb5, 0x8f, 0x5b, 0x07, 0x61, 0x40, 0x7c, 0x56, 0xca, 0xaf, 0x6a, 0x74, 0x49, 0xe8, 0x75, 0x8c, 0xf2, 0xb2, 0xd6, 0xa8, 0xb8, 0xd9, 0x1c, 0xdd, 0x05, 0xf0, 0x77,
0xd5, 0x62, 0xed, 0xf6, 0x68, 0x58, 0xf5, 0x18, 0x71, 0x27, 0x21, 0x8f, 0x2c, 0xc8, 0x05, 0x21, 0xb1, 0xbf, 0x17, 0x47, 0x24, 0x64, 0x46, 0x65, 0x59, 0x6b, 0xd4, 0x9a, 0xd7, 0x87, 0xc3, 0x5a,
0x23, 0x81, 0x4f, 0x4b, 0x05, 0xa1, 0xba, 0x6c, 0x49, 0x34, 0xad, 0x01, 0x9a, 0xd6, 0x63, 0xff, 0xcf, 0x18, 0x77, 0x73, 0x78, 0x64, 0x43, 0x39, 0x8a, 0x19, 0x89, 0x42, 0x6a, 0x54, 0x85, 0xe9,
0xd8, 0x19, 0x08, 0x99, 0x3b, 0x80, 0x92, 0x48, 0xd2, 0x30, 0xf0, 0x29, 0x7e, 0x2d, 0x28, 0x17, 0x82, 0x2d, 0xd9, 0xb4, 0x53, 0x36, 0xed, 0x7b, 0xe1, 0x81, 0x9b, 0x82, 0xac, 0x27, 0x80, 0xf2,
0x21, 0x1d, 0x12, 0xaf, 0x94, 0x5a, 0xd5, 0xaa, 0x0b, 0x0e, 0x5f, 0x9a, 0x6d, 0xb8, 0xbe, 0xcd, 0x4c, 0xd2, 0x38, 0x0a, 0x29, 0x7e, 0x2d, 0x2a, 0xe7, 0xa0, 0x10, 0x93, 0xc0, 0x98, 0x59, 0xd6,
0xdc, 0x88, 0xcd, 0x93, 0xa0, 0xf7, 0x21, 0x87, 0x8f, 0x70, 0xab, 0xa9, 0x2c, 0x17, 0xd6, 0xa0, 0x1a, 0xb3, 0x2e, 0x1f, 0x5a, 0x6d, 0xb8, 0xfc, 0x88, 0x79, 0x09, 0x9b, 0xe6, 0x82, 0xde, 0x87,
0x7f, 0x5a, 0xd1, 0x37, 0x8e, 0x70, 0xab, 0x51, 0x77, 0x74, 0xfe, 0xa9, 0xe1, 0x99, 0xef, 0xc1, 0x32, 0x7e, 0x81, 0xfd, 0x6d, 0xe5, 0xb9, 0xba, 0x0a, 0xfd, 0xa3, 0xba, 0xbe, 0xf1, 0x02, 0xfb,
0x82, 0x72, 0xa4, 0xe2, 0x57, 0xb1, 0x68, 0x67, 0xb1, 0x6c, 0xc2, 0x52, 0x1d, 0x77, 0xf0, 0xdc, 0xad, 0x75, 0x57, 0xe7, 0x9f, 0x5a, 0x81, 0xf5, 0x1e, 0xcc, 0xaa, 0x8d, 0x54, 0xfc, 0x2a, 0x16,
0x15, 0x63, 0xfe, 0xa6, 0xc1, 0x0d, 0x69, 0x29, 0xf6, 0xb6, 0x02, 0xa9, 0x58, 0x59, 0xef, 0x9f, 0xed, 0x38, 0x96, 0x4d, 0x98, 0x5f, 0xc7, 0x1d, 0x3c, 0x75, 0xc6, 0x58, 0xbf, 0x6a, 0x70, 0x45,
0x56, 0x52, 0x8d, 0xba, 0x93, 0x22, 0x17, 0x20, 0x82, 0x2a, 0x50, 0xc4, 0x47, 0x84, 0x35, 0x29, 0x7a, 0xca, 0x76, 0x5b, 0x84, 0x99, 0xcc, 0x58, 0xef, 0x1f, 0xd5, 0x67, 0x5a, 0xeb, 0xee, 0x0c,
0x73, 0x59, 0x8f, 0xd7, 0x1c, 0xff, 0x02, 0xfc, 0x68, 0x5b, 0x9c, 0xa0, 0xc7, 0x50, 0xe0, 0x3b, 0x39, 0x85, 0x11, 0x54, 0x87, 0x1a, 0x7e, 0x41, 0xd8, 0x36, 0x65, 0x1e, 0xeb, 0xf1, 0x9c, 0xe3,
0xec, 0x35, 0x5d, 0x26, 0x4a, 0xac, 0x58, 0x33, 0x46, 0x12, 0xf8, 0x6c, 0xf0, 0x1c, 0xd6, 0xf2, 0x5f, 0x80, 0x2f, 0x3d, 0x12, 0x2b, 0xe8, 0x1e, 0x54, 0xf9, 0x0c, 0x07, 0xdb, 0x1e, 0x13, 0x29,
0x27, 0xa7, 0x95, 0x6b, 0x2f, 0xff, 0xae, 0x68, 0x4e, 0x5e, 0xaa, 0x3d, 0x66, 0x66, 0x00, 0xcb, 0x56, 0x6b, 0x9a, 0x43, 0x17, 0xf8, 0x38, 0x7d, 0x0e, 0xab, 0x95, 0xc3, 0xa3, 0xfa, 0xa5, 0x97,
0x32, 0xbe, 0xad, 0x28, 0x68, 0x61, 0x4a, 0xaf, 0x1c, 0x7d, 0x0c, 0xb0, 0x89, 0xaf, 0x3e, 0xc9, 0x7f, 0xd5, 0x35, 0xb7, 0x22, 0xcd, 0xee, 0x31, 0x2b, 0x82, 0x05, 0x19, 0xdf, 0x56, 0x12, 0xf9,
0x1b, 0x50, 0x14, 0x6e, 0x14, 0xe8, 0x0f, 0x20, 0x17, 0xca, 0x0b, 0x0a, 0x17, 0x43, 0x6f, 0xe4, 0x98, 0xd2, 0x0b, 0x67, 0x1f, 0x03, 0x6c, 0xe2, 0x8b, 0xbf, 0xe4, 0x0d, 0xa8, 0x89, 0x6d, 0x14,
0xf0, 0x9e, 0x7a, 0x26, 0x03, 0x10, 0x06, 0xc2, 0xe6, 0x1d, 0x58, 0xfc, 0x8a, 0x50, 0xc6, 0xcb, 0xe9, 0xb7, 0xa1, 0x1c, 0xcb, 0x03, 0x8a, 0x2d, 0x06, 0xde, 0xc8, 0xfe, 0x4d, 0xf5, 0x4c, 0x52,
0x20, 0x86, 0x66, 0x05, 0xf4, 0x3d, 0xd2, 0x61, 0x38, 0x92, 0xd1, 0x3a, 0x6a, 0xc7, 0x8b, 0x26, 0x12, 0x52, 0xb0, 0xb5, 0x02, 0x73, 0x5f, 0x13, 0xca, 0x78, 0x1a, 0x64, 0xd4, 0x2c, 0x82, 0xbe,
0x21, 0x1b, 0xbf, 0x8d, 0xac, 0x20, 0xea, 0x92, 0x26, 0x18, 0x63, 0xb2, 0x5b, 0x29, 0x6a, 0xbe, 0x43, 0x3a, 0x0c, 0x27, 0x32, 0x5a, 0x57, 0xcd, 0x78, 0xd2, 0xe4, 0xb0, 0xd9, 0xdb, 0x28, 0x89,
0xd4, 0xa0, 0xf8, 0x25, 0xe9, 0x74, 0xae, 0x1a, 0x24, 0x41, 0x38, 0xa4, 0xcd, 0x69, 0x45, 0xd6, 0x12, 0x6f, 0x68, 0xa2, 0x62, 0x9c, 0xbd, 0xad, 0x84, 0x5a, 0x2f, 0x35, 0xa8, 0x7d, 0x45, 0x3a,
0x96, 0xda, 0xf1, 0x52, 0x74, 0x3b, 0x1d, 0x51, 0x51, 0x79, 0x87, 0x2f, 0xcd, 0x7f, 0x35, 0x40, 0x9d, 0x8b, 0x26, 0x49, 0x14, 0x1c, 0xd2, 0xe6, 0x65, 0x45, 0xe6, 0x96, 0x9a, 0xf1, 0x54, 0xf4,
0x5c, 0xf9, 0x0d, 0x54, 0x49, 0xcc, 0x89, 0xa9, 0x8b, 0x39, 0x31, 0x3d, 0x86, 0x13, 0x33, 0x63, 0x3a, 0x1d, 0x91, 0x51, 0x15, 0x97, 0x0f, 0xad, 0x7f, 0x34, 0x40, 0xdc, 0xf8, 0x0d, 0x64, 0x49,
0x39, 0x31, 0x3b, 0xc4, 0x89, 0x55, 0xc8, 0xd0, 0x10, 0xb7, 0x04, 0x8b, 0x8e, 0xa3, 0x34, 0x21, 0x56, 0x13, 0x67, 0x4e, 0xaf, 0x89, 0x85, 0x11, 0x35, 0xb1, 0x38, 0xb2, 0x26, 0x96, 0x06, 0x6a,
0x91, 0x44, 0x29, 0x37, 0xb6, 0x94, 0x6e, 0xc1, 0x5b, 0xe7, 0xae, 0x2e, 0x33, 0x6b, 0xfe, 0xaa, 0x62, 0x03, 0x8a, 0x34, 0xc6, 0xbe, 0xa8, 0xa2, 0xa3, 0x4a, 0x9a, 0x40, 0xe4, 0x59, 0x2a, 0x8f,
0xc1, 0xa2, 0x83, 0x29, 0xf9, 0x01, 0x6f, 0xb1, 0xe3, 0x2b, 0x4f, 0xd5, 0x32, 0x64, 0x5f, 0x10, 0x4c, 0xa5, 0x6b, 0xf0, 0xd6, 0x89, 0xa3, 0xcb, 0x9b, 0xb5, 0x7e, 0xd1, 0x60, 0xce, 0xc5, 0x94,
0x8f, 0xed, 0xab, 0x4c, 0xc9, 0x0d, 0x47, 0x67, 0x1f, 0x93, 0xf6, 0xbe, 0x7c, 0xfd, 0x0b, 0x8e, 0xfc, 0x80, 0xb7, 0xd8, 0xc1, 0x85, 0x5f, 0xd5, 0x02, 0x94, 0x9e, 0x93, 0x80, 0xed, 0xaa, 0x9b,
0xda, 0x99, 0x3f, 0xc1, 0x8d, 0xf5, 0x4e, 0x40, 0x71, 0xe3, 0xc9, 0xff, 0x11, 0x98, 0x4c, 0x67, 0x92, 0x13, 0xce, 0xce, 0x2e, 0x26, 0xed, 0x5d, 0xf9, 0xfa, 0x67, 0x5d, 0x35, 0xb3, 0x7e, 0x82,
0x5a, 0x64, 0x41, 0x6e, 0xcc, 0x2f, 0x60, 0x71, 0xcb, 0xed, 0xd1, 0xb9, 0xf9, 0x73, 0x13, 0x96, 0x2b, 0x6b, 0x9d, 0x88, 0xe2, 0xd6, 0x83, 0xff, 0x23, 0x30, 0x79, 0x9d, 0x05, 0x71, 0x0b, 0x72,
0x1c, 0x4c, 0x7b, 0xdd, 0xb9, 0x0d, 0x6d, 0xc0, 0x4d, 0xfe, 0x38, 0xb7, 0x88, 0x37, 0x4f, 0xf1, 0x62, 0x7d, 0x09, 0x73, 0x5b, 0x5e, 0x8f, 0x4e, 0x5d, 0x3f, 0x37, 0x61, 0xde, 0xc5, 0xb4, 0xd7,
0x9a, 0x1f, 0x48, 0x3e, 0x90, 0x66, 0xd4, 0x13, 0x47, 0x90, 0x09, 0x89, 0x27, 0x5f, 0xf8, 0x82, 0x9d, 0xda, 0xd1, 0x06, 0x5c, 0xe5, 0x8f, 0x73, 0x8b, 0x04, 0xd3, 0x24, 0xaf, 0xf5, 0x81, 0xac,
0x23, 0xd6, 0xe6, 0x5f, 0x1a, 0xdc, 0x5a, 0x8f, 0xfb, 0xec, 0xbc, 0x73, 0x47, 0x13, 0x96, 0x42, 0x07, 0xd2, 0x8d, 0x7a, 0xe2, 0x08, 0x8a, 0x31, 0x09, 0xe4, 0x0b, 0x9f, 0x75, 0xc5, 0xd8, 0xfa,
0x37, 0xc2, 0x3e, 0x6b, 0x26, 0x7a, 0xbd, 0x4c, 0x49, 0x8d, 0x73, 0xfa, 0x9f, 0xa7, 0x95, 0x3b, 0x53, 0x83, 0x6b, 0x6b, 0x59, 0x9f, 0x9d, 0x56, 0x77, 0x6c, 0xc3, 0x7c, 0xec, 0x25, 0x38, 0x64,
0x89, 0x09, 0x2a, 0x08, 0xb1, 0x1f, 0xab, 0x53, 0xbb, 0x1d, 0xdc, 0xf5, 0x48, 0x1b, 0x53, 0x66, 0xdb, 0xb9, 0x5e, 0x2f, 0xaf, 0xa4, 0xc9, 0x6b, 0xfa, 0x1f, 0x47, 0xf5, 0x95, 0x9c, 0x82, 0x8a,
0xd5, 0xc5, 0x2f, 0x67, 0x51, 0x1a, 0x5b, 0xbf, 0x70, 0x0e, 0x48, 0xcf, 0x32, 0x07, 0x7c, 0x07, 0x62, 0x1c, 0x66, 0xe6, 0xd4, 0x69, 0x47, 0x37, 0x02, 0xd2, 0xc6, 0x94, 0xd9, 0xeb, 0xe2, 0x3f,
0x2b, 0xc3, 0xb7, 0x53, 0x60, 0x7c, 0x0e, 0xc5, 0xb3, 0xe9, 0xee, 0x42, 0xd6, 0x1b, 0x19, 0x48, 0x77, 0x4e, 0x3a, 0x5b, 0x3b, 0x55, 0x07, 0x14, 0x26, 0xd1, 0x01, 0xdf, 0xc1, 0xe2, 0xe0, 0xe9,
0x92, 0x0a, 0xe6, 0x8f, 0xb0, 0xf4, 0x4d, 0xe8, 0xbd, 0x81, 0x59, 0xad, 0x06, 0x85, 0x08, 0xd3, 0x14, 0x19, 0x5f, 0x40, 0xed, 0x58, 0xdd, 0x9d, 0x5a, 0xf5, 0x86, 0x04, 0x49, 0xde, 0xc0, 0xfa,
0xa0, 0x17, 0xb5, 0x30, 0x15, 0x58, 0x8d, 0xbb, 0xd4, 0x99, 0x58, 0xed, 0x97, 0x22, 0x64, 0x05, 0x11, 0xe6, 0xbf, 0x89, 0x83, 0x37, 0xa0, 0xd5, 0x9a, 0x50, 0x4d, 0x30, 0x8d, 0x7a, 0x89, 0x8f,
0x7d, 0xa3, 0x03, 0xd0, 0xe5, 0xa0, 0x83, 0x6c, 0x6b, 0xd2, 0xf0, 0x6d, 0x8d, 0x0c, 0x96, 0xc6, 0xa9, 0xe0, 0x6a, 0xd4, 0xa1, 0x8e, 0x61, 0xd6, 0x0a, 0x5c, 0xb9, 0x2f, 0x45, 0x6d, 0xba, 0xb3,
0x27, 0xb3, 0x2b, 0x28, 0xcc, 0xbe, 0x87, 0xac, 0x18, 0x48, 0xd0, 0x9d, 0xc9, 0xaa, 0xc9, 0xf1, 0x01, 0x65, 0x59, 0xdd, 0xe5, 0x51, 0xaa, 0x6e, 0x3a, 0xe5, 0x09, 0x95, 0x61, 0xb3, 0x5a, 0x5f,
0xc8, 0xf8, 0x68, 0x26, 0x59, 0xe5, 0xa1, 0x0d, 0xba, 0xec, 0xf2, 0xd3, 0xae, 0x33, 0x32, 0xf5, 0x56, 0x9a, 0x58, 0x9d, 0xdb, 0x38, 0x45, 0x1f, 0x0a, 0x80, 0x9b, 0x02, 0x9b, 0xff, 0xd6, 0xa0,
0x18, 0x1f, 0xcf, 0xa2, 0x10, 0x3b, 0x7a, 0x0e, 0x0b, 0xe7, 0xc6, 0x09, 0x54, 0x9b, 0x45, 0xfd, 0x24, 0x3a, 0x06, 0xda, 0x03, 0x5d, 0x6a, 0x2b, 0xe4, 0xd8, 0x67, 0xfd, 0x52, 0xb0, 0x87, 0xb4,
0x7c, 0x57, 0xb9, 0xa4, 0xcb, 0x1d, 0x48, 0x6f, 0x62, 0x86, 0xaa, 0x93, 0x95, 0xce, 0x66, 0x0e, 0xac, 0xf9, 0xc9, 0xe4, 0x06, 0x2a, 0xd4, 0xef, 0xa1, 0x24, 0x34, 0x10, 0x5a, 0x39, 0xdb, 0x34,
0xe3, 0xc3, 0x19, 0x24, 0x63, 0xdc, 0x32, 0xfc, 0xb9, 0x23, 0x6b, 0xb2, 0xca, 0xf0, 0x88, 0x60, 0xaf, 0xc8, 0xcc, 0x8f, 0x26, 0xc2, 0xaa, 0x1d, 0xda, 0xa0, 0x4b, 0x61, 0x31, 0xee, 0x38, 0x43,
0xd8, 0x33, 0xcb, 0x2b, 0x47, 0x0d, 0xc8, 0xf0, 0x8e, 0x8f, 0xa6, 0xc4, 0x96, 0x98, 0x0a, 0x8c, 0x42, 0xcb, 0xfc, 0x78, 0x12, 0x83, 0x6c, 0xa3, 0x67, 0x30, 0x7b, 0x42, 0xc1, 0xa0, 0xe6, 0x24,
0x95, 0x91, 0x6a, 0xde, 0xe0, 0x7f, 0xf7, 0xa1, 0x2d, 0xc8, 0x70, 0x8a, 0x46, 0x53, 0xea, 0x70, 0xe6, 0x27, 0x1b, 0xd9, 0x39, 0xb7, 0x7c, 0x02, 0x85, 0x4d, 0xcc, 0x50, 0xe3, 0x6c, 0xa3, 0x63,
0xb4, 0x9b, 0x8f, 0xb5, 0xb8, 0x0d, 0x85, 0xb8, 0xd1, 0x4d, 0x83, 0x62, 0xb8, 0x23, 0x8e, 0x35, 0x99, 0x63, 0x7e, 0x38, 0x01, 0x32, 0xe3, 0xad, 0xc8, 0x2b, 0x0c, 0xb2, 0xcf, 0x36, 0x19, 0x54,
0xfa, 0x04, 0x72, 0xaa, 0x45, 0xa1, 0x29, 0xf9, 0x3e, 0xdf, 0xc9, 0x26, 0x18, 0xcc, 0x8a, 0x96, 0x25, 0xa6, 0x33, 0x31, 0x5e, 0x6d, 0xd4, 0x82, 0x22, 0x17, 0x19, 0x68, 0x4c, 0x6c, 0x39, 0x21,
0x33, 0x2d, 0xc2, 0xe1, 0xbe, 0x34, 0xd6, 0xe0, 0x53, 0xd0, 0x65, 0xef, 0x99, 0xf6, 0x68, 0x46, 0x62, 0x2e, 0x0e, 0x3d, 0xa0, 0x0d, 0xfe, 0x23, 0x15, 0x6d, 0x41, 0x91, 0x77, 0x05, 0x34, 0x26,
0x3a, 0xd4, 0x58, 0x93, 0x04, 0xf2, 0x83, 0xf6, 0x81, 0xee, 0x4e, 0xaf, 0x91, 0x44, 0xb7, 0x32, 0x0f, 0x87, 0x05, 0xc4, 0x48, 0x8f, 0x8f, 0xa0, 0x9a, 0xf5, 0xd6, 0x71, 0x54, 0x0c, 0x36, 0xe1,
0xac, 0x59, 0xc5, 0x55, 0x45, 0xbd, 0x00, 0x48, 0x10, 0xfc, 0xfd, 0x29, 0x10, 0x5f, 0xd4, 0xaa, 0x91, 0x4e, 0x1f, 0x40, 0x59, 0x75, 0x45, 0x34, 0xe6, 0xbe, 0x4f, 0x36, 0xcf, 0x33, 0x1c, 0x96,
0x8c, 0x4f, 0x2f, 0xa7, 0xa4, 0x1c, 0x3f, 0x05, 0x5d, 0x32, 0xf8, 0x34, 0xd8, 0x46, 0x78, 0x7e, 0x44, 0x97, 0x1b, 0x17, 0xe1, 0x60, 0x2b, 0x1c, 0xe9, 0xf0, 0x21, 0xe8, 0xb2, 0xdd, 0x8d, 0x7b,
0x1c, 0x6c, 0x6b, 0xdf, 0x9e, 0xbc, 0x2a, 0x5f, 0xfb, 0xe3, 0x55, 0xf9, 0xda, 0xcf, 0xfd, 0xb2, 0x34, 0x43, 0x4d, 0x71, 0xa4, 0x4b, 0x02, 0x95, 0xb4, 0x63, 0xa1, 0x1b, 0xe3, 0x73, 0x24, 0xd7,
0x76, 0xd2, 0x2f, 0x6b, 0xbf, 0xf7, 0xcb, 0xda, 0x3f, 0xfd, 0xb2, 0xb6, 0xf3, 0xe8, 0xf5, 0xfe, 0x20, 0x4d, 0x7b, 0x52, 0xb8, 0xca, 0xa8, 0xe7, 0x00, 0xb9, 0x9e, 0x72, 0x6b, 0x0c, 0xc5, 0xa7,
0xbb, 0xf2, 0x50, 0x2c, 0x76, 0x75, 0xe1, 0xe7, 0xfe, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x17, 0x75, 0x47, 0xf3, 0xd3, 0xf3, 0x19, 0xa9, 0x8d, 0x1f, 0x82, 0x2e, 0x9b, 0xc6, 0x38, 0xda, 0x86,
0xec, 0xf8, 0x44, 0xa4, 0x11, 0x00, 0x00, 0x5a, 0xcb, 0x48, 0xda, 0x76, 0xa0, 0xac, 0xca, 0xfb, 0xb8, 0x5c, 0x39, 0xd9, 0x31, 0xcc, 0x1b,
0x13, 0xa2, 0x65, 0xe8, 0xab, 0xdf, 0x1e, 0xbe, 0x5a, 0xba, 0xf4, 0xfb, 0xab, 0xa5, 0x4b, 0x3f,
0xf7, 0x97, 0xb4, 0xc3, 0xfe, 0x92, 0xf6, 0x5b, 0x7f, 0x49, 0xfb, 0xbb, 0xbf, 0xa4, 0x3d, 0xb9,
0xfb, 0x7a, 0x7f, 0x72, 0xba, 0x23, 0x06, 0x4f, 0x75, 0x71, 0x9e, 0x5b, 0xff, 0x05, 0x00, 0x00,
0xff, 0xff, 0x5e, 0xf6, 0xae, 0x85, 0xb9, 0x12, 0x00, 0x00,
} }

View File

@ -6,6 +6,7 @@ import "google/protobuf/empty.proto";
import "google/protobuf/any.proto"; import "google/protobuf/any.proto";
import "gogoproto/gogo.proto"; import "gogoproto/gogo.proto";
import "github.com/containerd/containerd/api/types/mount.proto"; import "github.com/containerd/containerd/api/types/mount.proto";
import "github.com/containerd/containerd/api/types/metrics.proto";
import "github.com/containerd/containerd/api/types/descriptor.proto"; import "github.com/containerd/containerd/api/types/descriptor.proto";
import "github.com/containerd/containerd/api/types/task/task.proto"; import "github.com/containerd/containerd/api/types/task/task.proto";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
@ -46,6 +47,8 @@ service Tasks {
rpc Checkpoint(CheckpointTaskRequest) returns (CheckpointTaskResponse); rpc Checkpoint(CheckpointTaskRequest) returns (CheckpointTaskResponse);
rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty); rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty);
rpc Metrics(MetricsRequest) returns (MetricsResponse);
} }
message CreateTaskRequest { message CreateTaskRequest {
@ -183,3 +186,11 @@ message UpdateTaskRequest {
string container_id = 1; string container_id = 1;
google.protobuf.Any resources = 2; google.protobuf.Any resources = 2;
} }
message MetricsRequest {
repeated string filters = 1;
}
message MetricsResponse {
repeated types.Metric metrics = 1;
}

View File

@ -7,10 +7,12 @@
It is generated from these files: It is generated from these files:
github.com/containerd/containerd/api/types/descriptor.proto github.com/containerd/containerd/api/types/descriptor.proto
github.com/containerd/containerd/api/types/metrics.proto
github.com/containerd/containerd/api/types/mount.proto github.com/containerd/containerd/api/types/mount.proto
It has these top-level messages: It has these top-level messages:
Descriptor Descriptor
Metric
Mount Mount
*/ */
package types package types

429
api/types/metrics.pb.go Normal file
View File

@ -0,0 +1,429 @@
// Code generated by protoc-gen-gogo.
// source: github.com/containerd/containerd/api/types/metrics.proto
// DO NOT EDIT!
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import google_protobuf1 "github.com/gogo/protobuf/types"
import _ "github.com/gogo/protobuf/types"
import time "time"
import github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
import strings "strings"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
var _ = time.Kitchen
type Metric struct {
Timestamp time.Time `protobuf:"bytes,1,opt,name=timestamp,stdtime" json:"timestamp"`
ID string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
Data *google_protobuf1.Any `protobuf:"bytes,3,opt,name=data" json:"data,omitempty"`
}
func (m *Metric) Reset() { *m = Metric{} }
func (*Metric) ProtoMessage() {}
func (*Metric) Descriptor() ([]byte, []int) { return fileDescriptorMetrics, []int{0} }
func init() {
proto.RegisterType((*Metric)(nil), "containerd.types.Metric")
}
func (m *Metric) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Metric) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintMetrics(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp)))
n1, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i:])
if err != nil {
return 0, err
}
i += n1
if len(m.ID) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintMetrics(dAtA, i, uint64(len(m.ID)))
i += copy(dAtA[i:], m.ID)
}
if m.Data != nil {
dAtA[i] = 0x1a
i++
i = encodeVarintMetrics(dAtA, i, uint64(m.Data.Size()))
n2, err := m.Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n2
}
return i, nil
}
func encodeFixed64Metrics(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Metrics(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *Metric) Size() (n int) {
var l int
_ = l
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp)
n += 1 + l + sovMetrics(uint64(l))
l = len(m.ID)
if l > 0 {
n += 1 + l + sovMetrics(uint64(l))
}
if m.Data != nil {
l = m.Data.Size()
n += 1 + l + sovMetrics(uint64(l))
}
return n
}
func sovMetrics(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozMetrics(x uint64) (n int) {
return sovMetrics(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *Metric) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Metric{`,
`Timestamp:` + strings.Replace(strings.Replace(this.Timestamp.String(), "Timestamp", "google_protobuf2.Timestamp", 1), `&`, ``, 1) + `,`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`Data:` + strings.Replace(fmt.Sprintf("%v", this.Data), "Any", "google_protobuf1.Any", 1) + `,`,
`}`,
}, "")
return s
}
func valueToStringMetrics(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *Metric) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Metric: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Metric: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMetrics
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthMetrics
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMetrics
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthMetrics
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Data == nil {
m.Data = &google_protobuf1.Any{}
}
if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipMetrics(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthMetrics
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipMetrics(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowMetrics
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowMetrics
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowMetrics
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthMetrics
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowMetrics
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipMetrics(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthMetrics = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowMetrics = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("github.com/containerd/containerd/api/types/metrics.proto", fileDescriptorMetrics)
}
var fileDescriptorMetrics = []byte{
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d,
0x4a, 0x41, 0x66, 0x26, 0x16, 0x64, 0xea, 0x97, 0x54, 0x16, 0xa4, 0x16, 0xeb, 0xe7, 0xa6, 0x96,
0x14, 0x65, 0x26, 0x17, 0xeb, 0x15, 0x14, 0xe5, 0x97, 0xe4, 0x0b, 0x09, 0x20, 0xd4, 0xe8, 0x81,
0xe5, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x92, 0xfa, 0x20, 0x16, 0x44, 0x9d, 0x94, 0x64,
0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x3e, 0x98, 0x97, 0x54, 0x9a, 0xa6, 0x9f, 0x98, 0x57, 0x09,
0x95, 0x92, 0x47, 0x97, 0x2a, 0xc9, 0xcc, 0x4d, 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0x80, 0x28, 0x50,
0xea, 0x63, 0xe4, 0x62, 0xf3, 0x05, 0xdb, 0x2a, 0xe4, 0xc4, 0xc5, 0x09, 0x97, 0x95, 0x60, 0x54,
0x60, 0xd4, 0xe0, 0x36, 0x92, 0xd2, 0x83, 0xe8, 0xd7, 0x83, 0xe9, 0xd7, 0x0b, 0x81, 0xa9, 0x70,
0xe2, 0x38, 0x71, 0x4f, 0x9e, 0x61, 0xc2, 0x7d, 0x79, 0xc6, 0x20, 0x84, 0x36, 0x21, 0x31, 0x2e,
0xa6, 0xcc, 0x14, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x4e, 0x27, 0xb6, 0x47, 0xf7, 0xe4, 0x99, 0x3c,
0x5d, 0x82, 0x98, 0x32, 0x53, 0x84, 0x34, 0xb8, 0x58, 0x52, 0x12, 0x4b, 0x12, 0x25, 0x98, 0xc1,
0xc6, 0x8a, 0x60, 0x18, 0xeb, 0x98, 0x57, 0x19, 0x04, 0x56, 0xe1, 0xe4, 0x75, 0xe2, 0xa1, 0x1c,
0xc3, 0x8d, 0x87, 0x72, 0x0c, 0x0d, 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48,
0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x28, 0x03, 0xe2, 0x03, 0xd2, 0x1a, 0x4c, 0x26, 0xb1, 0x81,
0xcd, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x51, 0x36, 0x74, 0x83, 0x01, 0x00, 0x00,
}

15
api/types/metrics.proto Normal file
View File

@ -0,0 +1,15 @@
syntax = "proto3";
package containerd.types;
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/containerd/containerd/api/types;types";
message Metric {
google.protobuf.Timestamp timestamp = 1 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
string id = 2;
google.protobuf.Any data = 3;
}

View File

@ -1307,3 +1307,64 @@ func TestDeleteContainerExecCreated(t *testing.T) {
} }
<-finished <-finished
} }
func TestContainerMetrics(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("metrics are currently not supported on windows")
}
t.Parallel()
client, err := newClient(t, address)
if err != nil {
t.Fatal(err)
}
defer client.Close()
var (
image Image
ctx, cancel = testContext()
id = t.Name()
)
defer cancel()
if runtime.GOOS != "windows" {
image, err = client.GetImage(ctx, testImage)
if err != nil {
t.Error(err)
return
}
}
container, err := client.NewContainer(ctx, id, WithNewSpec(withImageConfig(image), WithProcessArgs("sleep", "30")), withNewSnapshot(id, image))
if err != nil {
t.Error(err)
return
}
defer container.Delete(ctx, WithSnapshotCleanup)
task, err := container.NewTask(ctx, empty())
if err != nil {
t.Error(err)
return
}
defer task.Delete(ctx)
statusC, err := task.Wait(ctx)
if err != nil {
t.Error(err)
return
}
metric, err := task.Metrics(ctx)
if err != nil {
t.Error(err)
}
if metric.ID != id {
t.Errorf("expected metric id %q but received %q", id, metric.ID)
}
if err := task.Kill(ctx, syscall.SIGKILL); err != nil {
t.Error(err)
return
}
<-statusC
}

View File

@ -5,17 +5,31 @@ file {
message_type { message_type {
name: "RuncOptions" name: "RuncOptions"
field { field {
name: "criu_path" name: "runtime"
number: 1 number: 1
label: LABEL_OPTIONAL label: LABEL_OPTIONAL
type: TYPE_STRING type: TYPE_STRING
json_name: "runtime"
}
field {
name: "runtime_root"
number: 2
label: LABEL_OPTIONAL
type: TYPE_STRING
json_name: "runtimeRoot"
}
field {
name: "criu_path"
number: 3
label: LABEL_OPTIONAL
type: TYPE_STRING
json_name: "criuPath" json_name: "criuPath"
} }
field { field {
name: "systemd_cgroup" name: "systemd_cgroup"
number: 2 number: 4
label: LABEL_OPTIONAL label: LABEL_OPTIONAL
type: TYPE_STRING type: TYPE_BOOL
json_name: "systemdCgroup" json_name: "systemdCgroup"
} }
} }

View File

@ -245,7 +245,10 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
if err != nil { if err != nil {
return nil, errdefs.FromGRPC(err) return nil, errdefs.FromGRPC(err)
} }
t := newTask(id, namespace, int(cr.Pid), s) t, err := newTask(id, namespace, int(cr.Pid), s)
if err != nil {
return nil, err
}
if err := r.tasks.Add(ctx, t); err != nil { if err := r.tasks.Add(ctx, t); err != nil {
return nil, err return nil, err
} }
@ -341,13 +344,13 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
filepath.Join(r.state, ns, id), filepath.Join(r.state, ns, id),
filepath.Join(r.root, ns, id), filepath.Join(r.root, ns, id),
) )
pid, _ := runc.ReadPidFile(filepath.Join(bundle.path, client.InitPidFile))
s, err := bundle.NewShimClient(ctx, ns, ShimConnect(), nil) s, err := bundle.NewShimClient(ctx, ns, ShimConnect(), nil)
if err != nil { if err != nil {
log.G(ctx).WithError(err).WithFields(logrus.Fields{ log.G(ctx).WithError(err).WithFields(logrus.Fields{
"id": id, "id": id,
"namespace": ns, "namespace": ns,
}).Error("connecting to shim") }).Error("connecting to shim")
pid, _ := runc.ReadPidFile(filepath.Join(bundle.path, client.InitPidFile))
err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid, nil) err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid, nil)
if err != nil { if err != nil {
log.G(ctx).WithError(err).WithField("bundle", bundle.path). log.G(ctx).WithError(err).WithField("bundle", bundle.path).
@ -355,11 +358,13 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
} }
continue continue
} }
o = append(o, &Task{
id: id, t, err := newTask(id, ns, pid, s)
shim: s, if err != nil {
namespace: ns, log.G(ctx).WithError(err).Error("loading task type")
}) continue
}
o = append(o, t)
} }
return o, nil return o, nil
} }

View File

@ -5,6 +5,7 @@ package linux
import ( import (
"context" "context"
"github.com/containerd/cgroups"
"github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/api/types/task"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
client "github.com/containerd/containerd/linux/shim" client "github.com/containerd/containerd/linux/shim"
@ -18,15 +19,21 @@ type Task struct {
pid int pid int
shim *client.Client shim *client.Client
namespace string namespace string
cg cgroups.Cgroup
} }
func newTask(id, namespace string, pid int, shim *client.Client) *Task { func newTask(id, namespace string, pid int, shim *client.Client) (*Task, error) {
cg, err := cgroups.Load(cgroups.V1, cgroups.PidPath(pid))
if err != nil {
return nil, err
}
return &Task{ return &Task{
id: id, id: id,
pid: pid, pid: pid,
shim: shim, shim: shim,
namespace: namespace, namespace: namespace,
} cg: cg,
}, nil
} }
func (t *Task) ID() string { func (t *Task) ID() string {
@ -201,3 +208,15 @@ func (t *Task) Process(ctx context.Context, id string) (runtime.Process, error)
t: t, t: t,
}, nil }, nil
} }
func (t *Task) Metrics(ctx context.Context) (interface{}, error) {
stats, err := t.cg.Stat(cgroups.IgnoreNotExist)
if err != nil {
return nil, err
}
return stats, nil
}
func (t *Task) Cgroup() cgroups.Cgroup {
return t.cg
}

View File

@ -15,7 +15,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -28,7 +28,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -41,7 +41,7 @@ var blkioMetrics = []*metric{
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -54,7 +54,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -67,7 +67,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -80,7 +80,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }
@ -93,7 +93,7 @@ var blkioMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"op", "device", "major", "minor"}, labels: []string{"op", "device", "major", "minor"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Blkio == nil { if stats.Blkio == nil {
return nil return nil
} }

View File

@ -6,12 +6,12 @@ import (
"github.com/containerd/cgroups" "github.com/containerd/cgroups"
eventsapi "github.com/containerd/containerd/api/services/events/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/events" "github.com/containerd/containerd/events"
"github.com/containerd/containerd/linux"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/pkg/errors"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -50,18 +50,11 @@ type cgroupsMonitor struct {
func (m *cgroupsMonitor) Monitor(c runtime.Task) error { func (m *cgroupsMonitor) Monitor(c runtime.Task) error {
info := c.Info() info := c.Info()
state, err := c.State(m.context) t := c.(*linux.Task)
if err != nil { if err := m.collector.Add(info.ID, info.Namespace, t.Cgroup()); err != nil {
return err return err
} }
cg, err := cgroups.Load(cgroups.V1, cgroups.PidPath(int(state.Pid))) return m.oom.Add(info.ID, info.Namespace, t.Cgroup(), m.trigger)
if err != nil {
return errors.Wrapf(err, "load cgroup for %d", state.Pid)
}
if err := m.collector.Add(info.ID, info.Namespace, cg); err != nil {
return err
}
return m.oom.Add(info.ID, info.Namespace, cg, m.trigger)
} }
func (m *cgroupsMonitor) Stop(c runtime.Task) error { func (m *cgroupsMonitor) Stop(c runtime.Task) error {

View File

@ -16,13 +16,13 @@ var cpuMetrics = []*metric{
help: "The total cpu time", help: "The total cpu time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
return []value{ return []value{
{ {
v: float64(stats.Cpu.Usage.Total), v: float64(stats.CPU.Usage.Total),
}, },
} }
}, },
@ -32,13 +32,13 @@ var cpuMetrics = []*metric{
help: "The total kernel cpu time", help: "The total kernel cpu time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
return []value{ return []value{
{ {
v: float64(stats.Cpu.Usage.Kernel), v: float64(stats.CPU.Usage.Kernel),
}, },
} }
}, },
@ -48,13 +48,13 @@ var cpuMetrics = []*metric{
help: "The total user cpu time", help: "The total user cpu time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
return []value{ return []value{
{ {
v: float64(stats.Cpu.Usage.User), v: float64(stats.CPU.Usage.User),
}, },
} }
}, },
@ -65,12 +65,12 @@ var cpuMetrics = []*metric{
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"cpu"}, labels: []string{"cpu"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
var out []value var out []value
for i, v := range stats.Cpu.Usage.PerCpu { for i, v := range stats.CPU.Usage.PerCPU {
out = append(out, value{ out = append(out, value{
v: float64(v), v: float64(v),
l: []string{strconv.Itoa(i)}, l: []string{strconv.Itoa(i)},
@ -84,13 +84,13 @@ var cpuMetrics = []*metric{
help: "The total cpu throttle periods", help: "The total cpu throttle periods",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
return []value{ return []value{
{ {
v: float64(stats.Cpu.Throttling.Periods), v: float64(stats.CPU.Throttling.Periods),
}, },
} }
}, },
@ -100,13 +100,13 @@ var cpuMetrics = []*metric{
help: "The total cpu throttled periods", help: "The total cpu throttled periods",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
return []value{ return []value{
{ {
v: float64(stats.Cpu.Throttling.ThrottledPeriods), v: float64(stats.CPU.Throttling.ThrottledPeriods),
}, },
} }
}, },
@ -116,13 +116,13 @@ var cpuMetrics = []*metric{
help: "The total cpu throttled time", help: "The total cpu throttled time",
unit: metrics.Nanoseconds, unit: metrics.Nanoseconds,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Cpu == nil { if stats.CPU == nil {
return nil return nil
} }
return []value{ return []value{
{ {
v: float64(stats.Cpu.Throttling.ThrottledTime), v: float64(stats.CPU.Throttling.ThrottledTime),
}, },
} }
}, },

View File

@ -15,15 +15,15 @@ var hugetlbMetrics = []*metric{
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"page"}, labels: []string{"page"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Hugetlb == nil { if stats.Hugetlb == nil {
return nil return nil
} }
var out []value var out []value
for page, v := range stats.Hugetlb { for _, v := range stats.Hugetlb {
out = append(out, value{ out = append(out, value{
v: float64(v.Usage), v: float64(v.Usage),
l: []string{page}, l: []string{v.Pagesize},
}) })
} }
return out return out
@ -35,15 +35,15 @@ var hugetlbMetrics = []*metric{
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"page"}, labels: []string{"page"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Hugetlb == nil { if stats.Hugetlb == nil {
return nil return nil
} }
var out []value var out []value
for page, v := range stats.Hugetlb { for _, v := range stats.Hugetlb {
out = append(out, value{ out = append(out, value{
v: float64(v.Failcnt), v: float64(v.Failcnt),
l: []string{page}, l: []string{v.Pagesize},
}) })
} }
return out return out
@ -55,15 +55,15 @@ var hugetlbMetrics = []*metric{
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
labels: []string{"page"}, labels: []string{"page"},
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Hugetlb == nil { if stats.Hugetlb == nil {
return nil return nil
} }
var out []value var out []value
for page, v := range stats.Hugetlb { for _, v := range stats.Hugetlb {
out = append(out, value{ out = append(out, value{
v: float64(v.Max), v: float64(v.Max),
l: []string{page}, l: []string{v.Pagesize},
}) })
} }
return out return out

View File

@ -14,7 +14,7 @@ var memoryMetrics = []*metric{
help: "The cache amount used", help: "The cache amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -30,7 +30,7 @@ var memoryMetrics = []*metric{
help: "The rss amount used", help: "The rss amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -46,7 +46,7 @@ var memoryMetrics = []*metric{
help: "The rss_huge amount used", help: "The rss_huge amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -62,7 +62,7 @@ var memoryMetrics = []*metric{
help: "The mapped_file amount used", help: "The mapped_file amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -78,7 +78,7 @@ var memoryMetrics = []*metric{
help: "The dirty amount", help: "The dirty amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -94,7 +94,7 @@ var memoryMetrics = []*metric{
help: "The writeback amount", help: "The writeback amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -110,7 +110,7 @@ var memoryMetrics = []*metric{
help: "The pgpgin amount", help: "The pgpgin amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -126,7 +126,7 @@ var memoryMetrics = []*metric{
help: "The pgpgout amount", help: "The pgpgout amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -142,7 +142,7 @@ var memoryMetrics = []*metric{
help: "The pgfault amount", help: "The pgfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -158,7 +158,7 @@ var memoryMetrics = []*metric{
help: "The pgmajfault amount", help: "The pgmajfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -174,7 +174,7 @@ var memoryMetrics = []*metric{
help: "The inactive_anon amount", help: "The inactive_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -190,7 +190,7 @@ var memoryMetrics = []*metric{
help: "The active_anon amount", help: "The active_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -206,7 +206,7 @@ var memoryMetrics = []*metric{
help: "The inactive_file amount", help: "The inactive_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -222,7 +222,7 @@ var memoryMetrics = []*metric{
help: "The active_file amount", help: "The active_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -238,7 +238,7 @@ var memoryMetrics = []*metric{
help: "The unevictable amount", help: "The unevictable amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -254,7 +254,7 @@ var memoryMetrics = []*metric{
help: "The hierarchical_memory_limit amount", help: "The hierarchical_memory_limit amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -270,7 +270,7 @@ var memoryMetrics = []*metric{
help: "The hierarchical_memsw_limit amount", help: "The hierarchical_memsw_limit amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -286,7 +286,7 @@ var memoryMetrics = []*metric{
help: "The total_cache amount used", help: "The total_cache amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -302,7 +302,7 @@ var memoryMetrics = []*metric{
help: "The total_rss amount used", help: "The total_rss amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -318,7 +318,7 @@ var memoryMetrics = []*metric{
help: "The total_rss_huge amount used", help: "The total_rss_huge amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -334,7 +334,7 @@ var memoryMetrics = []*metric{
help: "The total_mapped_file amount used", help: "The total_mapped_file amount used",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -350,7 +350,7 @@ var memoryMetrics = []*metric{
help: "The total_dirty amount", help: "The total_dirty amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -366,7 +366,7 @@ var memoryMetrics = []*metric{
help: "The total_writeback amount", help: "The total_writeback amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -382,7 +382,7 @@ var memoryMetrics = []*metric{
help: "The total_pgpgin amount", help: "The total_pgpgin amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -398,7 +398,7 @@ var memoryMetrics = []*metric{
help: "The total_pgpgout amount", help: "The total_pgpgout amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -414,7 +414,7 @@ var memoryMetrics = []*metric{
help: "The total_pgfault amount", help: "The total_pgfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -430,7 +430,7 @@ var memoryMetrics = []*metric{
help: "The total_pgmajfault amount", help: "The total_pgmajfault amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -446,7 +446,7 @@ var memoryMetrics = []*metric{
help: "The total_inactive_anon amount", help: "The total_inactive_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -462,7 +462,7 @@ var memoryMetrics = []*metric{
help: "The total_active_anon amount", help: "The total_active_anon amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -478,7 +478,7 @@ var memoryMetrics = []*metric{
help: "The total_inactive_file amount", help: "The total_inactive_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -494,7 +494,7 @@ var memoryMetrics = []*metric{
help: "The total_active_file amount", help: "The total_active_file amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -510,7 +510,7 @@ var memoryMetrics = []*metric{
help: "The total_unevictable amount", help: "The total_unevictable amount",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -526,7 +526,7 @@ var memoryMetrics = []*metric{
help: "The usage failcnt", help: "The usage failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -542,7 +542,7 @@ var memoryMetrics = []*metric{
help: "The memory limit", help: "The memory limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -558,7 +558,7 @@ var memoryMetrics = []*metric{
help: "The memory maximum usage", help: "The memory maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -574,7 +574,7 @@ var memoryMetrics = []*metric{
help: "The memory usage", help: "The memory usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -590,7 +590,7 @@ var memoryMetrics = []*metric{
help: "The swap failcnt", help: "The swap failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -606,7 +606,7 @@ var memoryMetrics = []*metric{
help: "The swap limit", help: "The swap limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -622,7 +622,7 @@ var memoryMetrics = []*metric{
help: "The swap maximum usage", help: "The swap maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -638,7 +638,7 @@ var memoryMetrics = []*metric{
help: "The swap usage", help: "The swap usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -654,7 +654,7 @@ var memoryMetrics = []*metric{
help: "The kernel failcnt", help: "The kernel failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -670,7 +670,7 @@ var memoryMetrics = []*metric{
help: "The kernel limit", help: "The kernel limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -686,7 +686,7 @@ var memoryMetrics = []*metric{
help: "The kernel maximum usage", help: "The kernel maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -702,7 +702,7 @@ var memoryMetrics = []*metric{
help: "The kernel usage", help: "The kernel usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -718,7 +718,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp failcnt", help: "The kerneltcp failcnt",
unit: metrics.Total, unit: metrics.Total,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -734,7 +734,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp limit", help: "The kerneltcp limit",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -750,7 +750,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp maximum usage", help: "The kerneltcp maximum usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }
@ -766,7 +766,7 @@ var memoryMetrics = []*metric{
help: "The kerneltcp usage", help: "The kerneltcp usage",
unit: metrics.Bytes, unit: metrics.Bytes,
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Memory == nil { if stats.Memory == nil {
return nil return nil
} }

View File

@ -20,7 +20,7 @@ type metric struct {
vt prometheus.ValueType vt prometheus.ValueType
labels []string labels []string
// getValues returns the value and labels for the data // getValues returns the value and labels for the data
getValues func(stats *cgroups.Stats) []value getValues func(stats *cgroups.Metrics) []value
} }
func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc { func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
@ -28,7 +28,7 @@ func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...) return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...)
} }
func (m *metric) collect(id, namespace string, stats *cgroups.Stats, ns *metrics.Namespace, ch chan<- prometheus.Metric) { func (m *metric) collect(id, namespace string, stats *cgroups.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric) {
values := m.getValues(stats) values := m.getValues(stats)
for _, v := range values { for _, v := range values {
ch <- prometheus.MustNewConstMetric(m.desc(ns), m.vt, v.v, append([]string{id, namespace}, v.l...)...) ch <- prometheus.MustNewConstMetric(m.desc(ns), m.vt, v.v, append([]string{id, namespace}, v.l...)...)

View File

@ -123,7 +123,7 @@ func (c *Collector) Remove(id, namespace string) {
delete(c.cgroups, taskID(id, namespace)) delete(c.cgroups, taskID(id, namespace))
} }
func blkioValues(l []cgroups.BlkioEntry) []value { func blkioValues(l []*cgroups.BlkIOEntry) []value {
var out []value var out []value
for _, e := range l { for _, e := range l {
out = append(out, value{ out = append(out, value{

View File

@ -14,7 +14,7 @@ var pidMetrics = []*metric{
help: "The limit to the number of pids allowed", help: "The limit to the number of pids allowed",
unit: metrics.Unit("limit"), unit: metrics.Unit("limit"),
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Pids == nil { if stats.Pids == nil {
return nil return nil
} }
@ -30,7 +30,7 @@ var pidMetrics = []*metric{
help: "The current number of pids", help: "The current number of pids",
unit: metrics.Unit("current"), unit: metrics.Unit("current"),
vt: prometheus.GaugeValue, vt: prometheus.GaugeValue,
getValues: func(stats *cgroups.Stats) []value { getValues: func(stats *cgroups.Metrics) []value {
if stats.Pids == nil { if stats.Pids == nil {
return nil return nil
} }

View File

@ -49,6 +49,8 @@ type Task interface {
Update(context.Context, *types.Any) error Update(context.Context, *types.Any) error
// Process returns a process within the task for the provided id // Process returns a process within the task for the provided id
Process(context.Context, string) (Process, error) Process(context.Context, string) (Process, error)
// Metrics returns runtime specific metrics for a task
Metrics(context.Context) (interface{}, error)
} }
type ExecOpts struct { type ExecOpts struct {

View File

@ -7,6 +7,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"time"
"github.com/boltdb/bolt" "github.com/boltdb/bolt"
api "github.com/containerd/containerd/api/services/tasks/v1" api "github.com/containerd/containerd/api/services/tasks/v1"
@ -17,12 +18,14 @@ import (
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events" "github.com/containerd/containerd/events"
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/metadata" "github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/typeurl"
google_protobuf "github.com/golang/protobuf/ptypes/empty" google_protobuf "github.com/golang/protobuf/ptypes/empty"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -454,6 +457,58 @@ func (s *Service) Update(ctx context.Context, r *api.UpdateTaskRequest) (*google
return empty, nil return empty, nil
} }
func (s *Service) Metrics(ctx context.Context, r *api.MetricsRequest) (*api.MetricsResponse, error) {
filter, err := filters.ParseAll(r.Filters...)
if err != nil {
return nil, err
}
var resp api.MetricsResponse
for _, r := range s.runtimes {
tasks, err := r.Tasks(ctx)
if err != nil {
return nil, err
}
getTasksMetrics(ctx, filter, tasks, &resp)
}
return &resp, nil
}
func getTasksMetrics(ctx context.Context, filter filters.Filter, tasks []runtime.Task, r *api.MetricsResponse) {
for _, tk := range tasks {
if !filter.Match(filters.AdapterFunc(func(fieldpath []string) (string, bool) {
t := tk
switch fieldpath[0] {
case "id":
return t.ID(), true
case "namespace":
return t.Info().Namespace, true
case "runtime":
return t.Info().Runtime, true
}
return "", false
})) {
continue
}
collected := time.Now()
metrics, err := tk.Metrics(ctx)
if err != nil {
log.G(ctx).WithError(err).Errorf("collecting metrics for %s", tk.ID())
continue
}
data, err := typeurl.MarshalAny(metrics)
if err != nil {
log.G(ctx).WithError(err).Errorf("marshal metrics for %s", tk.ID())
continue
}
r.Metrics = append(r.Metrics, &types.Metric{
ID: tk.ID(),
Timestamp: collected,
Data: data,
})
}
}
func (s *Service) writeContent(ctx context.Context, mediaType, ref string, r io.Reader) (*types.Descriptor, error) { func (s *Service) writeContent(ctx context.Context, mediaType, ref string, r io.Reader) (*types.Descriptor, error) {
writer, err := s.store.Writer(ctx, ref, 0, "") writer, err := s.store.Writer(ctx, ref, 0, "")
if err != nil { if err != nil {

18
task.go
View File

@ -118,6 +118,12 @@ type Task interface {
Update(context.Context, ...UpdateTaskOpts) error Update(context.Context, ...UpdateTaskOpts) error
// LoadProcess loads a previously created exec'd process // LoadProcess loads a previously created exec'd process
LoadProcess(context.Context, string, IOAttach) (Process, error) LoadProcess(context.Context, string, IOAttach) (Process, error)
// Metrics returns task metrics for runtime specific metrics
//
// The metric types are generic to containerd and change depending on the runtime
// For the built in Linux runtime, github.com/containerd/cgroups.Metrics
// are returned in protobuf format
Metrics(context.Context) (*types.Metric, error)
} }
var _ = (Task)(&task{}) var _ = (Task)(&task{})
@ -472,6 +478,18 @@ func (t *task) LoadProcess(ctx context.Context, id string, ioAttach IOAttach) (P
}, nil }, nil
} }
func (t *task) Metrics(ctx context.Context) (*types.Metric, error) {
response, err := t.client.TaskService().Metrics(ctx, &tasks.MetricsRequest{
Filters: []string{
"id==" + t.id,
},
})
if err != nil {
return nil, errdefs.FromGRPC(err)
}
return response.Metrics[0], nil
}
func (t *task) checkpointTask(ctx context.Context, index *v1.Index, request *tasks.CheckpointTaskRequest) error { func (t *task) checkpointTask(ctx context.Context, index *v1.Index, request *tasks.CheckpointTaskRequest) error {
response, err := t.client.TaskService().Checkpoint(ctx, request) response, err := t.client.TaskService().Checkpoint(ctx, request)
if err != nil { if err != nil {

View File

@ -1,7 +1,7 @@
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
github.com/containerd/go-runc b3c048c028ddd789c6f9510c597f8b9c62f25359 github.com/containerd/go-runc b3c048c028ddd789c6f9510c597f8b9c62f25359
github.com/containerd/console 76d18fd1d66972718ab2284449591db0b3cdb4de github.com/containerd/console 76d18fd1d66972718ab2284449591db0b3cdb4de
github.com/containerd/cgroups e6d1aa8c71c6103624b2c6e6f4be0863b67027f1 github.com/containerd/cgroups 5933ab4dc4f7caa3a73a1dc141bd11f42b5c9163
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87 github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f

View File

@ -92,6 +92,11 @@ processes, err := control.Processes(cgroups.Devices, recursive)
stats, err := control.Stat() stats, err := control.Stat()
``` ```
By adding `cgroups.IgnoreNotExist` all non-existent files will be ignored, e.g. swap memory stats without swap enabled
```go
stats, err := control.Stat(cgroups.IgnoreNotExist)
```
### Move process across cgroups ### Move process across cgroups
This allows you to take processes from one cgroup and move them to another. This allows you to take processes from one cgroup and move them to another.

View File

@ -56,8 +56,8 @@ func (b *blkioController) Update(path string, resources *specs.LinuxResources) e
return b.Create(path, resources) return b.Create(path, resources)
} }
func (b *blkioController) Stat(path string, stats *Stats) error { func (b *blkioController) Stat(path string, stats *Metrics) error {
stats.Blkio = &BlkioStat{} stats.Blkio = &BlkIOStat{}
settings := []blkioStatSettings{ settings := []blkioStatSettings{
{ {
name: "throttle.io_serviced", name: "throttle.io_serviced",
@ -119,7 +119,7 @@ func (b *blkioController) Stat(path string, stats *Stats) error {
return nil return nil
} }
func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]BlkioEntry) error { func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*BlkIOEntry) error {
f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name))) f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name)))
if err != nil { if err != nil {
return err return err
@ -131,7 +131,7 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str
return err return err
} }
// format: dev type amount // format: dev type amount
fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine) fields := strings.FieldsFunc(sc.Text(), splitBlkIOStatLine)
if len(fields) < 3 { if len(fields) < 3 {
if len(fields) == 2 && fields[0] == "Total" { if len(fields) == 2 && fields[0] == "Total" {
// skip total line // skip total line
@ -158,7 +158,7 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str
if err != nil { if err != nil {
return err return err
} }
*entry = append(*entry, BlkioEntry{ *entry = append(*entry, &BlkIOEntry{
Device: devices[deviceKey{major, minor}], Device: devices[deviceKey{major, minor}],
Major: major, Major: major,
Minor: minor, Minor: minor,
@ -235,7 +235,7 @@ type blkioSettings struct {
type blkioStatSettings struct { type blkioStatSettings struct {
name string name string
entry *[]BlkioEntry entry *[]*BlkIOEntry
} }
func uintf(v interface{}) []byte { func uintf(v interface{}) []byte {
@ -257,7 +257,7 @@ func throttleddev(v interface{}) []byte {
return []byte(fmt.Sprintf("%d:%d %d", td.Major, td.Minor, td.Rate)) return []byte(fmt.Sprintf("%d:%d %d", td.Major, td.Minor, td.Rate))
} }
func splitBlkioStatLine(r rune) bool { func splitBlkIOStatLine(r rune) bool {
return r == ' ' || r == ':' return r == ' ' || r == ':'
} }

View File

@ -154,8 +154,8 @@ func (c *cgroup) Delete() error {
return nil return nil
} }
// Stat returns the current stats for the cgroup // Stat returns the current metrics for the cgroup
func (c *cgroup) Stat(handlers ...ErrorHandler) (*Stats, error) { func (c *cgroup) Stat(handlers ...ErrorHandler) (*Metrics, error) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
if c.err != nil { if c.err != nil {
@ -165,9 +165,14 @@ func (c *cgroup) Stat(handlers ...ErrorHandler) (*Stats, error) {
handlers = append(handlers, errPassthrough) handlers = append(handlers, errPassthrough)
} }
var ( var (
stats = &Stats{} stats = &Metrics{
wg = &sync.WaitGroup{} CPU: &CPUStat{
errs = make(chan error, len(c.subsystems)) Throttling: &Throttle{},
Usage: &CPUUsage{},
},
}
wg = &sync.WaitGroup{}
errs = make(chan error, len(c.subsystems))
) )
for _, s := range c.subsystems { for _, s := range c.subsystems {
if ss, ok := s.(stater); ok { if ss, ok := s.(stater); ok {

View File

@ -40,7 +40,7 @@ type Cgroup interface {
// subsystems are moved one at a time // subsystems are moved one at a time
MoveTo(Cgroup) error MoveTo(Cgroup) error
// Stat returns the stats for all subsystems in the cgroup // Stat returns the stats for all subsystems in the cgroup
Stat(...ErrorHandler) (*Stats, error) Stat(...ErrorHandler) (*Metrics, error)
// Update updates all the subsystems with the provided resource changes // Update updates all the subsystems with the provided resource changes
Update(resources *specs.LinuxResources) error Update(resources *specs.LinuxResources) error
// Processes returns all the processes in a select subsystem for the cgroup // Processes returns all the processes in a select subsystem for the cgroup

View File

@ -84,20 +84,13 @@ func (c *cpuController) Update(path string, resources *specs.LinuxResources) err
return c.Create(path, resources) return c.Create(path, resources)
} }
func (c *cpuController) Stat(path string, stats *Stats) error { func (c *cpuController) Stat(path string, stats *Metrics) error {
f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat")) f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat"))
if err != nil { if err != nil {
return err return err
} }
defer f.Close() defer f.Close()
// get or create the cpu field because cpuacct can also set values on this struct // get or create the cpu field because cpuacct can also set values on this struct
stats.cpuMu.Lock()
cpu := stats.Cpu
if cpu == nil {
cpu = &CpuStat{}
stats.Cpu = cpu
}
stats.cpuMu.Unlock()
sc := bufio.NewScanner(f) sc := bufio.NewScanner(f)
for sc.Scan() { for sc.Scan() {
if err := sc.Err(); err != nil { if err := sc.Err(); err != nil {
@ -109,11 +102,11 @@ func (c *cpuController) Stat(path string, stats *Stats) error {
} }
switch key { switch key {
case "nr_periods": case "nr_periods":
cpu.Throttling.Periods = v stats.CPU.Throttling.Periods = v
case "nr_throttled": case "nr_throttled":
cpu.Throttling.ThrottledPeriods = v stats.CPU.Throttling.ThrottledPeriods = v
case "throttled_time": case "throttled_time":
cpu.Throttling.ThrottledTime = v stats.CPU.Throttling.ThrottledTime = v
} }
} }
return nil return nil

View File

@ -30,7 +30,7 @@ func (c *cpuacctController) Path(path string) string {
return filepath.Join(c.root, path) return filepath.Join(c.root, path)
} }
func (c *cpuacctController) Stat(path string, stats *Stats) error { func (c *cpuacctController) Stat(path string, stats *Metrics) error {
user, kernel, err := c.getUsage(path) user, kernel, err := c.getUsage(path)
if err != nil { if err != nil {
return err return err
@ -43,17 +43,10 @@ func (c *cpuacctController) Stat(path string, stats *Stats) error {
if err != nil { if err != nil {
return err return err
} }
stats.cpuMu.Lock() stats.CPU.Usage.Total = total
cpu := stats.Cpu stats.CPU.Usage.User = user
if cpu == nil { stats.CPU.Usage.Kernel = kernel
cpu = &CpuStat{} stats.CPU.Usage.PerCPU = percpu
stats.Cpu = cpu
}
stats.cpuMu.Unlock()
cpu.Usage.Total = total
cpu.Usage.User = user
cpu.Usage.Kernel = kernel
cpu.Usage.PerCpu = percpu
return nil return nil
} }

View File

@ -51,20 +51,21 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources)
return nil return nil
} }
func (h *hugetlbController) Stat(path string, stats *Stats) error { func (h *hugetlbController) Stat(path string, stats *Metrics) error {
stats.Hugetlb = make(map[string]HugetlbStat)
for _, size := range h.sizes { for _, size := range h.sizes {
s, err := h.readSizeStat(path, size) s, err := h.readSizeStat(path, size)
if err != nil { if err != nil {
return err return err
} }
stats.Hugetlb[size] = s stats.Hugetlb = append(stats.Hugetlb, s)
} }
return nil return nil
} }
func (h *hugetlbController) readSizeStat(path, size string) (HugetlbStat, error) { func (h *hugetlbController) readSizeStat(path, size string) (*HugetlbStat, error) {
var s HugetlbStat s := HugetlbStat{
Pagesize: size,
}
for _, t := range []struct { for _, t := range []struct {
name string name string
value *uint64 value *uint64
@ -84,9 +85,9 @@ func (h *hugetlbController) readSizeStat(path, size string) (HugetlbStat, error)
} { } {
v, err := readUint(filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", size, t.name}, "."))) v, err := readUint(filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", size, t.name}, ".")))
if err != nil { if err != nil {
return s, err return nil, err
} }
*t.value = v *t.value = v
} }
return s, nil return &s, nil
} }

View File

@ -81,13 +81,18 @@ func (m *memoryController) Update(path string, resources *specs.LinuxResources)
return m.set(path, settings) return m.set(path, settings)
} }
func (m *memoryController) Stat(path string, stats *Stats) error { func (m *memoryController) Stat(path string, stats *Metrics) error {
f, err := os.Open(filepath.Join(m.Path(path), "memory.stat")) f, err := os.Open(filepath.Join(m.Path(path), "memory.stat"))
if err != nil { if err != nil {
return err return err
} }
defer f.Close() defer f.Close()
stats.Memory = &MemoryStat{} stats.Memory = &MemoryStat{
Usage: &MemoryEntry{},
Swap: &MemoryEntry{},
Kernel: &MemoryEntry{},
KernelTCP: &MemoryEntry{},
}
if err := m.parseStats(f, stats.Memory); err != nil { if err := m.parseStats(f, stats.Memory); err != nil {
return err return err
} }
@ -97,19 +102,19 @@ func (m *memoryController) Stat(path string, stats *Stats) error {
}{ }{
{ {
module: "", module: "",
entry: &stats.Memory.Usage, entry: stats.Memory.Usage,
}, },
{ {
module: "memsw", module: "memsw",
entry: &stats.Memory.Swap, entry: stats.Memory.Swap,
}, },
{ {
module: "kmem", module: "kmem",
entry: &stats.Memory.Kernel, entry: stats.Memory.Kernel,
}, },
{ {
module: "kmem.tcp", module: "kmem.tcp",
entry: &stats.Memory.KernelTCP, entry: stats.Memory.KernelTCP,
}, },
} { } {
for _, tt := range []struct { for _, tt := range []struct {

3851
vendor/github.com/containerd/cgroups/metrics.pb.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

111
vendor/github.com/containerd/cgroups/metrics.proto generated vendored Normal file
View File

@ -0,0 +1,111 @@
syntax = "proto3";
package io.containerd.cgroups.v1;
import "gogoproto/gogo.proto";
message Metrics {
repeated HugetlbStat hugetlb = 1;
PidsStat pids = 2;
CPUStat cpu = 3 [(gogoproto.customname) = "CPU"];
MemoryStat memory = 4;
BlkIOStat blkio = 5;
}
message HugetlbStat {
uint64 usage = 1;
uint64 max = 2;
uint64 failcnt = 3;
string pagesize = 4;
}
message PidsStat {
uint64 current = 1;
uint64 limit = 2;
}
message CPUStat {
CPUUsage usage = 1;
Throttle throttling = 2;
}
message CPUUsage {
// values in nanoseconds
uint64 total = 1;
uint64 kernel = 2;
uint64 user = 3;
repeated uint64 per_cpu = 4 [(gogoproto.customname) = "PerCPU"];
}
message Throttle {
uint64 periods = 1;
uint64 throttled_periods = 2;
uint64 throttled_time = 3;
}
message MemoryStat {
uint64 cache = 1;
uint64 rss = 2 [(gogoproto.customname) = "RSS"];
uint64 rss_huge = 3 [(gogoproto.customname) = "RSSHuge"];
uint64 mapped_file = 4;
uint64 dirty = 5;
uint64 writeback = 6;
uint64 pg_pg_in = 7;
uint64 pg_pg_out = 8;
uint64 pg_fault = 9;
uint64 pg_maj_fault = 10;
uint64 inactive_anon = 11;
uint64 active_anon = 12;
uint64 inactive_file = 13;
uint64 active_file = 14;
uint64 unevictable = 15;
uint64 hierarchical_memory_limit = 16;
uint64 hierarchical_swap_limit = 17;
uint64 total_cache = 18;
uint64 total_rss = 19 [(gogoproto.customname) = "TotalRSS"];
uint64 total_rss_huge = 20 [(gogoproto.customname) = "TotalRSSHuge"];
uint64 total_mapped_file = 21;
uint64 total_dirty = 22;
uint64 total_writeback = 23;
uint64 total_pg_pg_in = 24;
uint64 total_pg_pg_out = 25;
uint64 total_pg_fault = 26;
uint64 total_pg_maj_fault = 27;
uint64 total_inactive_anon = 28;
uint64 total_active_anon = 29;
uint64 total_inactive_file = 30;
uint64 total_active_file = 31;
uint64 total_unevictable = 32;
MemoryEntry usage = 33;
MemoryEntry swap = 34;
MemoryEntry kernel = 35;
MemoryEntry kernel_tcp = 36 [(gogoproto.customname) = "KernelTCP"];
}
message MemoryEntry {
uint64 limit = 1;
uint64 usage = 2;
uint64 max = 3;
uint64 failcnt = 4;
}
message BlkIOStat {
repeated BlkIOEntry io_service_bytes_recursive = 1;
repeated BlkIOEntry io_serviced_recursive = 2;
repeated BlkIOEntry io_queued_recursive = 3;
repeated BlkIOEntry io_service_time_recursive = 4;
repeated BlkIOEntry io_wait_time_recursive = 5;
repeated BlkIOEntry io_merged_recursive = 6;
repeated BlkIOEntry io_time_recursive = 7;
repeated BlkIOEntry sectors_recursive = 8;
}
message BlkIOEntry {
string op = 1;
string device = 2;
uint64 major = 3;
uint64 minor = 4;
uint64 value = 5;
}

View File

@ -46,7 +46,7 @@ func (p *pidsController) Update(path string, resources *specs.LinuxResources) er
return p.Create(path, resources) return p.Create(path, resources)
} }
func (p *pidsController) Stat(path string, stats *Stats) error { func (p *pidsController) Stat(path string, stats *Metrics) error {
current, err := readUint(filepath.Join(p.Path(path), "pids.current")) current, err := readUint(filepath.Join(p.Path(path), "pids.current"))
if err != nil { if err != nil {
return err return err

View File

@ -1,109 +0,0 @@
package cgroups
import "sync"
type Stats struct {
cpuMu sync.Mutex
Hugetlb map[string]HugetlbStat
Pids *PidsStat
Cpu *CpuStat
Memory *MemoryStat
Blkio *BlkioStat
}
type HugetlbStat struct {
Usage uint64
Max uint64
Failcnt uint64
}
type PidsStat struct {
Current uint64
Limit uint64
}
type CpuStat struct {
Usage CpuUsage
Throttling Throttle
}
type CpuUsage struct {
// Units: nanoseconds.
Total uint64
PerCpu []uint64
Kernel uint64
User uint64
}
type Throttle struct {
Periods uint64
ThrottledPeriods uint64
ThrottledTime uint64
}
type MemoryStat struct {
Cache uint64
RSS uint64
RSSHuge uint64
MappedFile uint64
Dirty uint64
Writeback uint64
PgPgIn uint64
PgPgOut uint64
PgFault uint64
PgMajFault uint64
InactiveAnon uint64
ActiveAnon uint64
InactiveFile uint64
ActiveFile uint64
Unevictable uint64
HierarchicalMemoryLimit uint64
HierarchicalSwapLimit uint64
TotalCache uint64
TotalRSS uint64
TotalRSSHuge uint64
TotalMappedFile uint64
TotalDirty uint64
TotalWriteback uint64
TotalPgPgIn uint64
TotalPgPgOut uint64
TotalPgFault uint64
TotalPgMajFault uint64
TotalInactiveAnon uint64
TotalActiveAnon uint64
TotalInactiveFile uint64
TotalActiveFile uint64
TotalUnevictable uint64
Usage MemoryEntry
Swap MemoryEntry
Kernel MemoryEntry
KernelTCP MemoryEntry
}
type MemoryEntry struct {
Limit uint64
Usage uint64
Max uint64
Failcnt uint64
}
type BlkioStat struct {
IoServiceBytesRecursive []BlkioEntry
IoServicedRecursive []BlkioEntry
IoQueuedRecursive []BlkioEntry
IoServiceTimeRecursive []BlkioEntry
IoWaitTimeRecursive []BlkioEntry
IoMergedRecursive []BlkioEntry
IoTimeRecursive []BlkioEntry
SectorsRecursive []BlkioEntry
}
type BlkioEntry struct {
Op string
Device string
Major uint64
Minor uint64
Value uint64
}

View File

@ -67,7 +67,7 @@ type deleter interface {
type stater interface { type stater interface {
Subsystem Subsystem
Stat(path string, stats *Stats) error Stat(path string, stats *Metrics) error
} }
type updater interface { type updater interface {

View File

@ -43,19 +43,13 @@ func Slice(slice, name string) Path {
} }
func NewSystemd(root string) (*SystemdController, error) { func NewSystemd(root string) (*SystemdController, error) {
conn, err := systemdDbus.New()
if err != nil {
return nil, err
}
return &SystemdController{ return &SystemdController{
root: root, root: root,
conn: conn,
}, nil }, nil
} }
type SystemdController struct { type SystemdController struct {
mu sync.Mutex mu sync.Mutex
conn *systemdDbus.Conn
root string root string
} }
@ -64,6 +58,11 @@ func (s *SystemdController) Name() Name {
} }
func (s *SystemdController) Create(path string, resources *specs.LinuxResources) error { func (s *SystemdController) Create(path string, resources *specs.LinuxResources) error {
conn, err := systemdDbus.New()
if err != nil {
return err
}
defer conn.Close()
slice, name := splitName(path) slice, name := splitName(path)
properties := []systemdDbus.Property{ properties := []systemdDbus.Property{
systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)), systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)),
@ -74,14 +73,29 @@ func (s *SystemdController) Create(path string, resources *specs.LinuxResources)
newProperty("CPUAccounting", true), newProperty("CPUAccounting", true),
newProperty("BlockIOAccounting", true), newProperty("BlockIOAccounting", true),
} }
_, err := s.conn.StartTransientUnit(name, "replace", properties, nil) ch := make(chan string)
return err _, err = conn.StartTransientUnit(name, "replace", properties, ch)
if err != nil {
return err
}
<-ch
return nil
} }
func (s *SystemdController) Delete(path string) error { func (s *SystemdController) Delete(path string) error {
conn, err := systemdDbus.New()
if err != nil {
return err
}
defer conn.Close()
_, name := splitName(path) _, name := splitName(path)
_, err := s.conn.StopUnit(name, "replace", nil) ch := make(chan string)
return err _, err = conn.StopUnit(name, "replace", ch)
if err != nil {
return err
}
<-ch
return nil
} }
func newProperty(name string, units interface{}) systemdDbus.Property { func newProperty(name string, units interface{}) systemdDbus.Property {

View File

@ -270,6 +270,10 @@ func (t *task) Process(ctx context.Context, id string) (p runtime.Process, err e
return p, err return p, err
} }
func (t *task) Metrics(ctx context.Context) (interface{}, error) {
return nil, errors.Wrap(errdefs.ErrUnavailable, "not supported")
}
func (t *task) newProcess(ctx context.Context, id string, conf *hcsshim.ProcessConfig, pset *pipeSet) (*process, error) { func (t *task) newProcess(ctx context.Context, id string, conf *hcsshim.ProcessConfig, pset *pipeSet) (*process, error) {
var ( var (
err error err error