summaryrefslogtreecommitdiffhomepage
path: root/pkg/metric
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/metric')
-rw-r--r--pkg/metric/BUILD38
-rw-r--r--pkg/metric/metric.proto101
-rw-r--r--pkg/metric/metric_go_proto/metric.pb.go732
-rw-r--r--pkg/metric/metric_state_autogen.go3
-rw-r--r--pkg/metric/metric_test.go499
5 files changed, 735 insertions, 638 deletions
diff --git a/pkg/metric/BUILD b/pkg/metric/BUILD
deleted file mode 100644
index c08792751..000000000
--- a/pkg/metric/BUILD
+++ /dev/null
@@ -1,38 +0,0 @@
-load("//tools:defs.bzl", "go_library", "go_test", "proto_library")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "metric",
- srcs = [
- "metric.go",
- ],
- visibility = ["//:sandbox"],
- deps = [
- ":metric_go_proto",
- "//pkg/eventchannel",
- "//pkg/log",
- "//pkg/sync",
- "@org_golang_google_protobuf//types/known/timestamppb",
- ],
-)
-
-proto_library(
- name = "metric",
- srcs = ["metric.proto"],
- visibility = ["//:sandbox"],
- deps = [
- "@com_google_protobuf//:timestamp_proto",
- ],
-)
-
-go_test(
- name = "metric_test",
- srcs = ["metric_test.go"],
- library = ":metric",
- deps = [
- ":metric_go_proto",
- "//pkg/eventchannel",
- "@org_golang_google_protobuf//proto:go_default_library",
- ],
-)
diff --git a/pkg/metric/metric.proto b/pkg/metric/metric.proto
deleted file mode 100644
index d466b6904..000000000
--- a/pkg/metric/metric.proto
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package gvisor;
-
-import "google/protobuf/timestamp.proto";
-
-// MetricMetadata contains all of the metadata describing a single metric.
-message MetricMetadata {
- // name is the unique name of the metric, usually in a "directory" format
- // (e.g., /foo/count).
- string name = 1;
-
- // description is a human-readable description of the metric.
- string description = 2;
-
- // cumulative indicates that this metric is never decremented.
- bool cumulative = 3;
-
- // sync indicates that values from the final metric event should be
- // synchronized to the backing monitoring system at exit.
- //
- // If sync is false, values are only sent to the monitoring system
- // periodically. There is no guarantee that values will ever be received by
- // the monitoring system.
- bool sync = 4;
-
- enum Type { TYPE_UINT64 = 0; }
-
- // type is the type of the metric value.
- Type type = 5;
-
- enum Units {
- UNITS_NONE = 0;
- UNITS_NANOSECONDS = 1;
- }
-
- // units is the units of the metric value.
- Units units = 6;
-
- message Field {
- string field_name = 1;
- repeated string allowed_values = 2;
- }
-
- // fields contains the metric fields. Currently a metric can have at most
- // one field.
- repeated Field fields = 7;
-}
-
-// MetricRegistration contains the metadata for all metrics that will be in
-// future MetricUpdates.
-message MetricRegistration {
- repeated MetricMetadata metrics = 1;
- repeated string stages = 2;
-}
-
-// MetricValue the value of a metric at a single point in time.
-message MetricValue {
- // name is the unique name of the metric, as in MetricMetadata.
- string name = 1;
-
- // value is the value of the metric at a single point in time. The field set
- // depends on the type of the metric.
- oneof value {
- uint64 uint64_value = 2;
- }
-
- repeated string field_values = 4;
-}
-
-// StageTiming represents a new stage that's been reached by the Sentry.
-message StageTiming {
- string stage = 1;
- google.protobuf.Timestamp started = 2;
- google.protobuf.Timestamp ended = 3;
-}
-
-// MetricUpdate contains new values for multiple distinct metrics.
-//
-// Metrics whose values have not changed are not included.
-message MetricUpdate {
- repeated MetricValue metrics = 1;
- // Timing information of initialization stages reached since last update.
- // The first MetricUpdate will include multiple entries, since metric
- // initialization happens relatively late in the Sentry startup process.
- repeated StageTiming stage_timing = 2;
-}
diff --git a/pkg/metric/metric_go_proto/metric.pb.go b/pkg/metric/metric_go_proto/metric.pb.go
new file mode 100644
index 000000000..7d327e3a0
--- /dev/null
+++ b/pkg/metric/metric_go_proto/metric.pb.go
@@ -0,0 +1,732 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.25.0
+// protoc v3.13.0
+// source: pkg/metric/metric.proto
+
+package gvisor
+
+import (
+ proto "github.com/golang/protobuf/proto"
+ timestamp "github.com/golang/protobuf/ptypes/timestamp"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type MetricMetadata_Type int32
+
+const (
+ MetricMetadata_TYPE_UINT64 MetricMetadata_Type = 0
+)
+
+// Enum value maps for MetricMetadata_Type.
+var (
+ MetricMetadata_Type_name = map[int32]string{
+ 0: "TYPE_UINT64",
+ }
+ MetricMetadata_Type_value = map[string]int32{
+ "TYPE_UINT64": 0,
+ }
+)
+
+func (x MetricMetadata_Type) Enum() *MetricMetadata_Type {
+ p := new(MetricMetadata_Type)
+ *p = x
+ return p
+}
+
+func (x MetricMetadata_Type) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (MetricMetadata_Type) Descriptor() protoreflect.EnumDescriptor {
+ return file_pkg_metric_metric_proto_enumTypes[0].Descriptor()
+}
+
+func (MetricMetadata_Type) Type() protoreflect.EnumType {
+ return &file_pkg_metric_metric_proto_enumTypes[0]
+}
+
+func (x MetricMetadata_Type) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use MetricMetadata_Type.Descriptor instead.
+func (MetricMetadata_Type) EnumDescriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{0, 0}
+}
+
+type MetricMetadata_Units int32
+
+const (
+ MetricMetadata_UNITS_NONE MetricMetadata_Units = 0
+ MetricMetadata_UNITS_NANOSECONDS MetricMetadata_Units = 1
+)
+
+// Enum value maps for MetricMetadata_Units.
+var (
+ MetricMetadata_Units_name = map[int32]string{
+ 0: "UNITS_NONE",
+ 1: "UNITS_NANOSECONDS",
+ }
+ MetricMetadata_Units_value = map[string]int32{
+ "UNITS_NONE": 0,
+ "UNITS_NANOSECONDS": 1,
+ }
+)
+
+func (x MetricMetadata_Units) Enum() *MetricMetadata_Units {
+ p := new(MetricMetadata_Units)
+ *p = x
+ return p
+}
+
+func (x MetricMetadata_Units) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (MetricMetadata_Units) Descriptor() protoreflect.EnumDescriptor {
+ return file_pkg_metric_metric_proto_enumTypes[1].Descriptor()
+}
+
+func (MetricMetadata_Units) Type() protoreflect.EnumType {
+ return &file_pkg_metric_metric_proto_enumTypes[1]
+}
+
+func (x MetricMetadata_Units) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use MetricMetadata_Units.Descriptor instead.
+func (MetricMetadata_Units) EnumDescriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{0, 1}
+}
+
+type MetricMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ Cumulative bool `protobuf:"varint,3,opt,name=cumulative,proto3" json:"cumulative,omitempty"`
+ Sync bool `protobuf:"varint,4,opt,name=sync,proto3" json:"sync,omitempty"`
+ Type MetricMetadata_Type `protobuf:"varint,5,opt,name=type,proto3,enum=gvisor.MetricMetadata_Type" json:"type,omitempty"`
+ Units MetricMetadata_Units `protobuf:"varint,6,opt,name=units,proto3,enum=gvisor.MetricMetadata_Units" json:"units,omitempty"`
+ Fields []*MetricMetadata_Field `protobuf:"bytes,7,rep,name=fields,proto3" json:"fields,omitempty"`
+}
+
+func (x *MetricMetadata) Reset() {
+ *x = MetricMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_pkg_metric_metric_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetricMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricMetadata) ProtoMessage() {}
+
+func (x *MetricMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_pkg_metric_metric_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricMetadata.ProtoReflect.Descriptor instead.
+func (*MetricMetadata) Descriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *MetricMetadata) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *MetricMetadata) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *MetricMetadata) GetCumulative() bool {
+ if x != nil {
+ return x.Cumulative
+ }
+ return false
+}
+
+func (x *MetricMetadata) GetSync() bool {
+ if x != nil {
+ return x.Sync
+ }
+ return false
+}
+
+func (x *MetricMetadata) GetType() MetricMetadata_Type {
+ if x != nil {
+ return x.Type
+ }
+ return MetricMetadata_TYPE_UINT64
+}
+
+func (x *MetricMetadata) GetUnits() MetricMetadata_Units {
+ if x != nil {
+ return x.Units
+ }
+ return MetricMetadata_UNITS_NONE
+}
+
+func (x *MetricMetadata) GetFields() []*MetricMetadata_Field {
+ if x != nil {
+ return x.Fields
+ }
+ return nil
+}
+
+type MetricRegistration struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Metrics []*MetricMetadata `protobuf:"bytes,1,rep,name=metrics,proto3" json:"metrics,omitempty"`
+ Stages []string `protobuf:"bytes,2,rep,name=stages,proto3" json:"stages,omitempty"`
+}
+
+func (x *MetricRegistration) Reset() {
+ *x = MetricRegistration{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_pkg_metric_metric_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetricRegistration) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricRegistration) ProtoMessage() {}
+
+func (x *MetricRegistration) ProtoReflect() protoreflect.Message {
+ mi := &file_pkg_metric_metric_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricRegistration.ProtoReflect.Descriptor instead.
+func (*MetricRegistration) Descriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *MetricRegistration) GetMetrics() []*MetricMetadata {
+ if x != nil {
+ return x.Metrics
+ }
+ return nil
+}
+
+func (x *MetricRegistration) GetStages() []string {
+ if x != nil {
+ return x.Stages
+ }
+ return nil
+}
+
+type MetricValue struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ // Types that are assignable to Value:
+ // *MetricValue_Uint64Value
+ Value isMetricValue_Value `protobuf_oneof:"value"`
+ FieldValues []string `protobuf:"bytes,4,rep,name=field_values,json=fieldValues,proto3" json:"field_values,omitempty"`
+}
+
+func (x *MetricValue) Reset() {
+ *x = MetricValue{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_pkg_metric_metric_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetricValue) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricValue) ProtoMessage() {}
+
+func (x *MetricValue) ProtoReflect() protoreflect.Message {
+ mi := &file_pkg_metric_metric_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricValue.ProtoReflect.Descriptor instead.
+func (*MetricValue) Descriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *MetricValue) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (m *MetricValue) GetValue() isMetricValue_Value {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+func (x *MetricValue) GetUint64Value() uint64 {
+ if x, ok := x.GetValue().(*MetricValue_Uint64Value); ok {
+ return x.Uint64Value
+ }
+ return 0
+}
+
+func (x *MetricValue) GetFieldValues() []string {
+ if x != nil {
+ return x.FieldValues
+ }
+ return nil
+}
+
+type isMetricValue_Value interface {
+ isMetricValue_Value()
+}
+
+type MetricValue_Uint64Value struct {
+ Uint64Value uint64 `protobuf:"varint,2,opt,name=uint64_value,json=uint64Value,proto3,oneof"`
+}
+
+func (*MetricValue_Uint64Value) isMetricValue_Value() {}
+
+type StageTiming struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Stage string `protobuf:"bytes,1,opt,name=stage,proto3" json:"stage,omitempty"`
+ Started *timestamp.Timestamp `protobuf:"bytes,2,opt,name=started,proto3" json:"started,omitempty"`
+ Ended *timestamp.Timestamp `protobuf:"bytes,3,opt,name=ended,proto3" json:"ended,omitempty"`
+}
+
+func (x *StageTiming) Reset() {
+ *x = StageTiming{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_pkg_metric_metric_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StageTiming) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StageTiming) ProtoMessage() {}
+
+func (x *StageTiming) ProtoReflect() protoreflect.Message {
+ mi := &file_pkg_metric_metric_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StageTiming.ProtoReflect.Descriptor instead.
+func (*StageTiming) Descriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *StageTiming) GetStage() string {
+ if x != nil {
+ return x.Stage
+ }
+ return ""
+}
+
+func (x *StageTiming) GetStarted() *timestamp.Timestamp {
+ if x != nil {
+ return x.Started
+ }
+ return nil
+}
+
+func (x *StageTiming) GetEnded() *timestamp.Timestamp {
+ if x != nil {
+ return x.Ended
+ }
+ return nil
+}
+
+type MetricUpdate struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Metrics []*MetricValue `protobuf:"bytes,1,rep,name=metrics,proto3" json:"metrics,omitempty"`
+ StageTiming []*StageTiming `protobuf:"bytes,2,rep,name=stage_timing,json=stageTiming,proto3" json:"stage_timing,omitempty"`
+}
+
+func (x *MetricUpdate) Reset() {
+ *x = MetricUpdate{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_pkg_metric_metric_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetricUpdate) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricUpdate) ProtoMessage() {}
+
+func (x *MetricUpdate) ProtoReflect() protoreflect.Message {
+ mi := &file_pkg_metric_metric_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricUpdate.ProtoReflect.Descriptor instead.
+func (*MetricUpdate) Descriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *MetricUpdate) GetMetrics() []*MetricValue {
+ if x != nil {
+ return x.Metrics
+ }
+ return nil
+}
+
+func (x *MetricUpdate) GetStageTiming() []*StageTiming {
+ if x != nil {
+ return x.StageTiming
+ }
+ return nil
+}
+
+type MetricMetadata_Field struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ FieldName string `protobuf:"bytes,1,opt,name=field_name,json=fieldName,proto3" json:"field_name,omitempty"`
+ AllowedValues []string `protobuf:"bytes,2,rep,name=allowed_values,json=allowedValues,proto3" json:"allowed_values,omitempty"`
+}
+
+func (x *MetricMetadata_Field) Reset() {
+ *x = MetricMetadata_Field{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_pkg_metric_metric_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetricMetadata_Field) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricMetadata_Field) ProtoMessage() {}
+
+func (x *MetricMetadata_Field) ProtoReflect() protoreflect.Message {
+ mi := &file_pkg_metric_metric_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricMetadata_Field.ProtoReflect.Descriptor instead.
+func (*MetricMetadata_Field) Descriptor() ([]byte, []int) {
+ return file_pkg_metric_metric_proto_rawDescGZIP(), []int{0, 0}
+}
+
+func (x *MetricMetadata_Field) GetFieldName() string {
+ if x != nil {
+ return x.FieldName
+ }
+ return ""
+}
+
+func (x *MetricMetadata_Field) GetAllowedValues() []string {
+ if x != nil {
+ return x.AllowedValues
+ }
+ return nil
+}
+
+var File_pkg_metric_metric_proto protoreflect.FileDescriptor
+
+var file_pkg_metric_metric_proto_rawDesc = []byte{
+ 0x0a, 0x17, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x67, 0x76, 0x69, 0x73, 0x6f,
+ 0x72, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+ 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x22, 0xad, 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63,
+ 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x0a, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73,
+ 0x79, 0x6e, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x12,
+ 0x2f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e,
+ 0x67, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
+ 0x12, 0x32, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x1c, 0x2e, 0x67, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x52, 0x05, 0x75,
+ 0x6e, 0x69, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x4d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65,
+ 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x4d, 0x0a, 0x05, 0x46, 0x69,
+ 0x65, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61,
+ 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f,
+ 0x77, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x17, 0x0a, 0x04, 0x54, 0x79, 0x70,
+ 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34,
+ 0x10, 0x00, 0x22, 0x2e, 0x0a, 0x05, 0x55, 0x6e, 0x69, 0x74, 0x73, 0x12, 0x0e, 0x0a, 0x0a, 0x55,
+ 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x55,
+ 0x4e, 0x49, 0x54, 0x53, 0x5f, 0x4e, 0x41, 0x4e, 0x4f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x53,
+ 0x10, 0x01, 0x22, 0x5e, 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x67, 0x69,
+ 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x76, 0x69, 0x73,
+ 0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74,
+ 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x67,
+ 0x65, 0x73, 0x22, 0x72, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x75,
+ 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69,
+ 0x65, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09,
+ 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x07, 0x0a,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x67, 0x65,
+ 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x07,
+ 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74,
+ 0x65, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x65,
+ 0x6e, 0x64, 0x65, 0x64, 0x22, 0x75, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x55, 0x70,
+ 0x64, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x4d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72,
+ 0x69, 0x63, 0x73, 0x12, 0x36, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x69, 0x6d,
+ 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x76, 0x69, 0x73,
+ 0x6f, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x0b,
+ 0x73, 0x74, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_pkg_metric_metric_proto_rawDescOnce sync.Once
+ file_pkg_metric_metric_proto_rawDescData = file_pkg_metric_metric_proto_rawDesc
+)
+
+func file_pkg_metric_metric_proto_rawDescGZIP() []byte {
+ file_pkg_metric_metric_proto_rawDescOnce.Do(func() {
+ file_pkg_metric_metric_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_metric_metric_proto_rawDescData)
+ })
+ return file_pkg_metric_metric_proto_rawDescData
+}
+
+var file_pkg_metric_metric_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_pkg_metric_metric_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_pkg_metric_metric_proto_goTypes = []interface{}{
+ (MetricMetadata_Type)(0), // 0: gvisor.MetricMetadata.Type
+ (MetricMetadata_Units)(0), // 1: gvisor.MetricMetadata.Units
+ (*MetricMetadata)(nil), // 2: gvisor.MetricMetadata
+ (*MetricRegistration)(nil), // 3: gvisor.MetricRegistration
+ (*MetricValue)(nil), // 4: gvisor.MetricValue
+ (*StageTiming)(nil), // 5: gvisor.StageTiming
+ (*MetricUpdate)(nil), // 6: gvisor.MetricUpdate
+ (*MetricMetadata_Field)(nil), // 7: gvisor.MetricMetadata.Field
+ (*timestamp.Timestamp)(nil), // 8: google.protobuf.Timestamp
+}
+var file_pkg_metric_metric_proto_depIdxs = []int32{
+ 0, // 0: gvisor.MetricMetadata.type:type_name -> gvisor.MetricMetadata.Type
+ 1, // 1: gvisor.MetricMetadata.units:type_name -> gvisor.MetricMetadata.Units
+ 7, // 2: gvisor.MetricMetadata.fields:type_name -> gvisor.MetricMetadata.Field
+ 2, // 3: gvisor.MetricRegistration.metrics:type_name -> gvisor.MetricMetadata
+ 8, // 4: gvisor.StageTiming.started:type_name -> google.protobuf.Timestamp
+ 8, // 5: gvisor.StageTiming.ended:type_name -> google.protobuf.Timestamp
+ 4, // 6: gvisor.MetricUpdate.metrics:type_name -> gvisor.MetricValue
+ 5, // 7: gvisor.MetricUpdate.stage_timing:type_name -> gvisor.StageTiming
+ 8, // [8:8] is the sub-list for method output_type
+ 8, // [8:8] is the sub-list for method input_type
+ 8, // [8:8] is the sub-list for extension type_name
+ 8, // [8:8] is the sub-list for extension extendee
+ 0, // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_pkg_metric_metric_proto_init() }
+func file_pkg_metric_metric_proto_init() {
+ if File_pkg_metric_metric_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_pkg_metric_metric_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetricMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_pkg_metric_metric_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetricRegistration); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_pkg_metric_metric_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetricValue); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_pkg_metric_metric_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*StageTiming); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_pkg_metric_metric_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetricUpdate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_pkg_metric_metric_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetricMetadata_Field); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_pkg_metric_metric_proto_msgTypes[2].OneofWrappers = []interface{}{
+ (*MetricValue_Uint64Value)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_pkg_metric_metric_proto_rawDesc,
+ NumEnums: 2,
+ NumMessages: 6,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_pkg_metric_metric_proto_goTypes,
+ DependencyIndexes: file_pkg_metric_metric_proto_depIdxs,
+ EnumInfos: file_pkg_metric_metric_proto_enumTypes,
+ MessageInfos: file_pkg_metric_metric_proto_msgTypes,
+ }.Build()
+ File_pkg_metric_metric_proto = out.File
+ file_pkg_metric_metric_proto_rawDesc = nil
+ file_pkg_metric_metric_proto_goTypes = nil
+ file_pkg_metric_metric_proto_depIdxs = nil
+}
diff --git a/pkg/metric/metric_state_autogen.go b/pkg/metric/metric_state_autogen.go
new file mode 100644
index 000000000..36e5ed81b
--- /dev/null
+++ b/pkg/metric/metric_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package metric
diff --git a/pkg/metric/metric_test.go b/pkg/metric/metric_test.go
deleted file mode 100644
index 0654bdf07..000000000
--- a/pkg/metric/metric_test.go
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright 2018 The gVisor Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package metric
-
-import (
- "testing"
- "time"
-
- "google.golang.org/protobuf/proto"
- "gvisor.dev/gvisor/pkg/eventchannel"
- pb "gvisor.dev/gvisor/pkg/metric/metric_go_proto"
-)
-
-// sliceEmitter implements eventchannel.Emitter by appending all messages to a
-// slice.
-type sliceEmitter []proto.Message
-
-// Emit implements eventchannel.Emitter.Emit.
-func (s *sliceEmitter) Emit(msg proto.Message) (bool, error) {
- *s = append(*s, msg)
- return false, nil
-}
-
-// Emit implements eventchannel.Emitter.Close.
-func (s *sliceEmitter) Close() error {
- return nil
-}
-
-// Reset clears all events in s.
-func (s *sliceEmitter) Reset() {
- *s = nil
-}
-
-// emitter is the eventchannel.Emitter used for all tests. Package eventchannel
-// doesn't allow removing Emitters, so we must use one global emitter for all
-// test cases.
-var emitter sliceEmitter
-
-func init() {
- reset()
-
- eventchannel.AddEmitter(&emitter)
-}
-
-// reset clears all global state in the metric package.
-func reset() {
- initialized = false
- allMetrics = makeMetricSet()
- emitter.Reset()
-}
-
-const (
- fooDescription = "Foo!"
- barDescription = "Bar Baz"
- counterDescription = "Counter"
-)
-
-func TestInitialize(t *testing.T) {
- defer reset()
-
- _, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- _, err = NewUint64Metric("/bar", true, pb.MetricMetadata_UNITS_NANOSECONDS, barDescription)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- if err := Initialize(); err != nil {
- t.Fatalf("Initialize(): %s", err)
- }
-
- if len(emitter) != 1 {
- t.Fatalf("Initialize emitted %d events want 1", len(emitter))
- }
-
- mr, ok := emitter[0].(*pb.MetricRegistration)
- if !ok {
- t.Fatalf("emitter %v got %T want pb.MetricRegistration", emitter[0], emitter[0])
- }
-
- if len(mr.Metrics) != 2 {
- t.Errorf("MetricRegistration got %d metrics want 2", len(mr.Metrics))
- }
-
- foundFoo := false
- foundBar := false
- for _, m := range mr.Metrics {
- if m.Type != pb.MetricMetadata_TYPE_UINT64 {
- t.Errorf("Metadata %+v Type got %v want pb.MetricMetadata_TYPE_UINT64", m, m.Type)
- }
- if !m.Cumulative {
- t.Errorf("Metadata %+v Cumulative got false want true", m)
- }
-
- switch m.Name {
- case "/foo":
- foundFoo = true
- if m.Description != fooDescription {
- t.Errorf("/foo %+v Description got %q want %q", m, m.Description, fooDescription)
- }
- if m.Sync {
- t.Errorf("/foo %+v Sync got true want false", m)
- }
- if m.Units != pb.MetricMetadata_UNITS_NONE {
- t.Errorf("/foo %+v Units got %v want %v", m, m.Units, pb.MetricMetadata_UNITS_NONE)
- }
- case "/bar":
- foundBar = true
- if m.Description != barDescription {
- t.Errorf("/bar %+v Description got %q want %q", m, m.Description, barDescription)
- }
- if !m.Sync {
- t.Errorf("/bar %+v Sync got true want false", m)
- }
- if m.Units != pb.MetricMetadata_UNITS_NANOSECONDS {
- t.Errorf("/bar %+v Units got %v want %v", m, m.Units, pb.MetricMetadata_UNITS_NANOSECONDS)
- }
- }
- }
-
- if !foundFoo {
- t.Errorf("/foo not found: %+v", emitter)
- }
- if !foundBar {
- t.Errorf("/bar not found: %+v", emitter)
- }
-}
-
-func TestDisable(t *testing.T) {
- defer reset()
-
- _, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- _, err = NewUint64Metric("/bar", true, pb.MetricMetadata_UNITS_NONE, barDescription)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- if err := Disable(); err != nil {
- t.Fatalf("Disable(): %s", err)
- }
-
- if len(emitter) != 1 {
- t.Fatalf("Initialize emitted %d events want 1", len(emitter))
- }
-
- mr, ok := emitter[0].(*pb.MetricRegistration)
- if !ok {
- t.Fatalf("emitter %v got %T want pb.MetricRegistration", emitter[0], emitter[0])
- }
-
- if len(mr.Metrics) != 0 {
- t.Errorf("MetricRegistration got %d metrics want 0", len(mr.Metrics))
- }
-}
-
-func TestEmitMetricUpdate(t *testing.T) {
- defer reset()
-
- foo, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- _, err = NewUint64Metric("/bar", true, pb.MetricMetadata_UNITS_NONE, barDescription)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- if err := Initialize(); err != nil {
- t.Fatalf("Initialize(): %s", err)
- }
-
- // Don't care about the registration metrics.
- emitter.Reset()
- EmitMetricUpdate()
-
- if len(emitter) != 1 {
- t.Fatalf("EmitMetricUpdate emitted %d events want 1", len(emitter))
- }
-
- update, ok := emitter[0].(*pb.MetricUpdate)
- if !ok {
- t.Fatalf("emitter %v got %T want pb.MetricUpdate", emitter[0], emitter[0])
- }
-
- if len(update.Metrics) != 2 {
- t.Errorf("MetricUpdate got %d metrics want 2", len(update.Metrics))
- }
-
- // Both are included for their initial values.
- foundFoo := false
- foundBar := false
- for _, m := range update.Metrics {
- switch m.Name {
- case "/foo":
- foundFoo = true
- case "/bar":
- foundBar = true
- }
- uv, ok := m.Value.(*pb.MetricValue_Uint64Value)
- if !ok {
- t.Errorf("%+v: value %v got %T want pb.MetricValue_Uint64Value", m, m.Value, m.Value)
- continue
- }
- if uv.Uint64Value != 0 {
- t.Errorf("%v: Value got %v want 0", m, uv.Uint64Value)
- }
- }
-
- if !foundFoo {
- t.Errorf("/foo not found: %+v", emitter)
- }
- if !foundBar {
- t.Errorf("/bar not found: %+v", emitter)
- }
-
- // Increment foo. Only it is included in the next update.
- foo.Increment()
-
- emitter.Reset()
- EmitMetricUpdate()
-
- if len(emitter) != 1 {
- t.Fatalf("EmitMetricUpdate emitted %d events want 1", len(emitter))
- }
-
- update, ok = emitter[0].(*pb.MetricUpdate)
- if !ok {
- t.Fatalf("emitter %v got %T want pb.MetricUpdate", emitter[0], emitter[0])
- }
-
- if len(update.Metrics) != 1 {
- t.Errorf("MetricUpdate got %d metrics want 1", len(update.Metrics))
- }
-
- m := update.Metrics[0]
-
- if m.Name != "/foo" {
- t.Errorf("Metric %+v name got %q want '/foo'", m, m.Name)
- }
-
- uv, ok := m.Value.(*pb.MetricValue_Uint64Value)
- if !ok {
- t.Errorf("%+v: value %v got %T want pb.MetricValue_Uint64Value", m, m.Value, m.Value)
- }
- if uv.Uint64Value != 1 {
- t.Errorf("%v: Value got %v want 1", m, uv.Uint64Value)
- }
-}
-
-func TestEmitMetricUpdateWithFields(t *testing.T) {
- defer reset()
-
- field := Field{
- name: "weirdness_type",
- allowedValues: []string{"weird1", "weird2"}}
-
- counter, err := NewUint64Metric("/weirdness", false, pb.MetricMetadata_UNITS_NONE, counterDescription, field)
- if err != nil {
- t.Fatalf("NewUint64Metric got err %v want nil", err)
- }
-
- if err := Initialize(); err != nil {
- t.Fatalf("Initialize(): %s", err)
- }
-
- // Don't care about the registration metrics.
- emitter.Reset()
- EmitMetricUpdate()
-
- // For metrics with fields, we do not emit data unless the value is
- // incremented.
- if len(emitter) != 0 {
- t.Fatalf("EmitMetricUpdate emitted %d events want 0", len(emitter))
- }
-
- counter.IncrementBy(4, "weird1")
- counter.Increment("weird2")
-
- emitter.Reset()
- EmitMetricUpdate()
-
- if len(emitter) != 1 {
- t.Fatalf("EmitMetricUpdate emitted %d events want 1", len(emitter))
- }
-
- update, ok := emitter[0].(*pb.MetricUpdate)
- if !ok {
- t.Fatalf("emitter %v got %T want pb.MetricUpdate", emitter[0], emitter[0])
- }
-
- if len(update.Metrics) != 2 {
- t.Errorf("MetricUpdate got %d metrics want 2", len(update.Metrics))
- }
-
- foundWeird1 := false
- foundWeird2 := false
- for i := 0; i < len(update.Metrics); i++ {
- m := update.Metrics[i]
-
- if m.Name != "/weirdness" {
- t.Errorf("Metric %+v name got %q want '/weirdness'", m, m.Name)
- }
- if len(m.FieldValues) != 1 {
- t.Errorf("MetricUpdate got %d fields want 1", len(m.FieldValues))
- }
-
- switch m.FieldValues[0] {
- case "weird1":
- uv, ok := m.Value.(*pb.MetricValue_Uint64Value)
- if !ok {
- t.Errorf("%+v: value %v got %T want pb.MetricValue_Uint64Value", m, m.Value, m.Value)
- }
- if uv.Uint64Value != 4 {
- t.Errorf("%v: Value got %v want 4", m, uv.Uint64Value)
- }
- foundWeird1 = true
- case "weird2":
- uv, ok := m.Value.(*pb.MetricValue_Uint64Value)
- if !ok {
- t.Errorf("%+v: value %v got %T want pb.MetricValue_Uint64Value", m, m.Value, m.Value)
- }
- if uv.Uint64Value != 1 {
- t.Errorf("%v: Value got %v want 1", m, uv.Uint64Value)
- }
- foundWeird2 = true
- }
- }
-
- if !foundWeird1 {
- t.Errorf("Field value weird1 not found: %+v", emitter)
- }
- if !foundWeird2 {
- t.Errorf("Field value weird2 not found: %+v", emitter)
- }
-}
-
-func TestMetricUpdateStageTiming(t *testing.T) {
- defer reset()
-
- expectedTimings := map[InitStage]struct{ min, max time.Duration }{}
- measureStage := func(stage InitStage, body func()) {
- stageStarted := time.Now()
- endStage := StartStage(stage)
- bodyStarted := time.Now()
- body()
- bodyEnded := time.Now()
- endStage()
- stageEnded := time.Now()
-
- expectedTimings[stage] = struct{ min, max time.Duration }{
- min: bodyEnded.Sub(bodyStarted),
- max: stageEnded.Sub(stageStarted),
- }
- }
- checkStage := func(got *pb.StageTiming, want InitStage) {
- if InitStage(got.GetStage()) != want {
- t.Errorf("%v: got stage %q expected %q", got, got.GetStage(), want)
- }
- timingBounds, found := expectedTimings[want]
- if !found {
- t.Fatalf("invalid init stage name %q", want)
- }
- started := got.Started.AsTime()
- ended := got.Ended.AsTime()
- duration := ended.Sub(started)
- if duration < timingBounds.min {
- t.Errorf("stage %v: lasted %v, expected at least %v", want, duration, timingBounds.min)
- } else if duration > timingBounds.max {
- t.Errorf("stage %v: lasted %v, expected no more than %v", want, duration, timingBounds.max)
- }
- }
-
- // Test that it's legit to go through stages before metric registration.
- measureStage("before_first_update_1", func() {
- time.Sleep(100 * time.Millisecond)
- })
- measureStage("before_first_update_2", func() {
- time.Sleep(100 * time.Millisecond)
- })
-
- fooMetric, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
- if err != nil {
- t.Fatalf("Cannot register /foo: %v", err)
- }
- emitter.Reset()
- Initialize()
- EmitMetricUpdate()
-
- // We should have gotten the metric registration and the first MetricUpdate.
- if len(emitter) != 2 {
- t.Fatalf("emitter has %d messages (%v), expected %d", len(emitter), emitter, 2)
- }
-
- if registration, ok := emitter[0].(*pb.MetricRegistration); !ok {
- t.Errorf("first message is not MetricRegistration: %T / %v", emitter[0], emitter[0])
- } else if len(registration.Stages) != len(allStages) {
- t.Errorf("MetricRegistration has %d stages (%v), expected %d (%v)", len(registration.Stages), registration.Stages, len(allStages), allStages)
- } else {
- for i := 0; i < len(allStages); i++ {
- if InitStage(registration.Stages[i]) != allStages[i] {
- t.Errorf("MetricRegistration.Stages[%d]: got %q want %q", i, registration.Stages[i], allStages[i])
- }
- }
- }
-
- if firstUpdate, ok := emitter[1].(*pb.MetricUpdate); !ok {
- t.Errorf("second message is not MetricUpdate: %T / %v", emitter[1], emitter[1])
- } else if len(firstUpdate.StageTiming) != 2 {
- t.Errorf("MetricUpdate has %d stage timings (%v), expected %d", len(firstUpdate.StageTiming), firstUpdate.StageTiming, 2)
- } else {
- checkStage(firstUpdate.StageTiming[0], "before_first_update_1")
- checkStage(firstUpdate.StageTiming[1], "before_first_update_2")
- }
-
- // Ensure re-emitting doesn't cause another event to be sent.
- emitter.Reset()
- EmitMetricUpdate()
- if len(emitter) != 0 {
- t.Fatalf("EmitMetricUpdate emitted %d events want %d", len(emitter), 0)
- }
-
- // Generate monitoring data, we should get an event with no stages.
- fooMetric.Increment()
- emitter.Reset()
- EmitMetricUpdate()
- if len(emitter) != 1 {
- t.Fatalf("EmitMetricUpdate emitted %d events want %d", len(emitter), 1)
- } else if update, ok := emitter[0].(*pb.MetricUpdate); !ok {
- t.Errorf("message is not MetricUpdate: %T / %v", emitter[1], emitter[1])
- } else if len(update.StageTiming) != 0 {
- t.Errorf("unexpected stage timing information: %v", update.StageTiming)
- }
-
- // Now generate new stages.
- measureStage("foo_stage_1", func() {
- time.Sleep(100 * time.Millisecond)
- })
- measureStage("foo_stage_2", func() {
- time.Sleep(100 * time.Millisecond)
- })
- emitter.Reset()
- EmitMetricUpdate()
- if len(emitter) != 1 {
- t.Fatalf("EmitMetricUpdate emitted %d events want %d", len(emitter), 1)
- } else if update, ok := emitter[0].(*pb.MetricUpdate); !ok {
- t.Errorf("message is not MetricUpdate: %T / %v", emitter[1], emitter[1])
- } else if len(update.Metrics) != 0 {
- t.Errorf("MetricUpdate has %d metric value changes (%v), expected %d", len(update.Metrics), update.Metrics, 0)
- } else if len(update.StageTiming) != 2 {
- t.Errorf("MetricUpdate has %d stages (%v), expected %d", len(update.StageTiming), update.StageTiming, 2)
- } else {
- checkStage(update.StageTiming[0], "foo_stage_1")
- checkStage(update.StageTiming[1], "foo_stage_2")
- }
-
- // Now try generating data for both metrics and stages.
- fooMetric.Increment()
- measureStage("last_stage_1", func() {
- time.Sleep(100 * time.Millisecond)
- })
- measureStage("last_stage_2", func() {
- time.Sleep(100 * time.Millisecond)
- })
- fooMetric.Increment()
- emitter.Reset()
- EmitMetricUpdate()
- if len(emitter) != 1 {
- t.Fatalf("EmitMetricUpdate emitted %d events want %d", len(emitter), 1)
- } else if update, ok := emitter[0].(*pb.MetricUpdate); !ok {
- t.Errorf("message is not MetricUpdate: %T / %v", emitter[1], emitter[1])
- } else if len(update.Metrics) != 1 {
- t.Errorf("MetricUpdate has %d metric value changes (%v), expected %d", len(update.Metrics), update.Metrics, 1)
- } else if len(update.StageTiming) != 2 {
- t.Errorf("MetricUpdate has %d stages (%v), expected %d", len(update.StageTiming), update.StageTiming, 2)
- } else {
- checkStage(update.StageTiming[0], "last_stage_1")
- checkStage(update.StageTiming[1], "last_stage_2")
- }
-}