mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Metrics: Refactor uint64 metric constructor, allow non-cumulative gauges.
This turns the uint64 metric constructor arguments into a struct, making it more explicit as to what each part means. It also allows the creation of non-cumulative uint64 (gauge) metrics, and adds methods to decrement or set them. PiperOrigin-RevId: 647134245
This commit is contained in:
committed by
gVisor bot
parent
89ae593e2a
commit
abde965590
@@ -48,11 +48,21 @@ func (m *FakeUint64Metric) Value(fieldValues ...*FieldValue) uint64 {
|
||||
//go:nosplit
|
||||
func (m *FakeUint64Metric) Increment(fieldValues ...*FieldValue) {}
|
||||
|
||||
// Decrement on a FakeUint64Metric does nothing.
|
||||
//
|
||||
//go:nosplit
|
||||
func (m *FakeUint64Metric) Decrement(fieldValues ...*FieldValue) {}
|
||||
|
||||
// IncrementBy on a FakeUint64Metric does nothing.
|
||||
//
|
||||
//go:nosplit
|
||||
func (m *FakeUint64Metric) IncrementBy(v uint64, fieldValues ...*FieldValue) {}
|
||||
|
||||
// Set on a FakeUint64Metric does nothing.
|
||||
//
|
||||
//go:nosplit
|
||||
func (m *FakeUint64Metric) Set(v uint64, fieldValues ...*FieldValue) {}
|
||||
|
||||
// AddSample on a FakeUint64Metric does nothing.
|
||||
//
|
||||
//go:nosplit
|
||||
@@ -76,12 +86,12 @@ func (o FakeTimedOperation) Finish(extraFields ...*FieldValue) {}
|
||||
type FakeMetricBuilder struct{}
|
||||
|
||||
// NewUint64Metric creates a fake Uint64 metric.
|
||||
func (b *FakeMetricBuilder) NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*FakeUint64Metric, error) {
|
||||
func (b *FakeMetricBuilder) NewUint64Metric(name string, metadata Uint64Metadata) (*FakeUint64Metric, error) {
|
||||
return &FakeUint64Metric{}, nil
|
||||
}
|
||||
|
||||
// MustCreateNewUint64Metric creates a fake Uint64 metric.
|
||||
func (b *FakeMetricBuilder) MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *FakeUint64Metric {
|
||||
func (b *FakeMetricBuilder) MustCreateNewUint64Metric(name string, metadata Uint64Metadata) *FakeUint64Metric {
|
||||
return &FakeUint64Metric{}
|
||||
}
|
||||
|
||||
@@ -111,8 +121,8 @@ type RealMetricBuilder struct{}
|
||||
|
||||
// NewUint64Metric calls the generic metric.NewUint64Metric to produce a real
|
||||
// Uint64 metric.
|
||||
func (b *RealMetricBuilder) NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*Uint64Metric, error) {
|
||||
m, err := NewUint64Metric(name, sync, units, description, fields...)
|
||||
func (b *RealMetricBuilder) NewUint64Metric(name string, metadata Uint64Metadata) (*Uint64Metric, error) {
|
||||
m, err := NewUint64Metric(name, metadata)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
@@ -122,8 +132,8 @@ func (b *RealMetricBuilder) NewUint64Metric(name string, sync bool, units pb.Met
|
||||
|
||||
// MustCreateNewUint64Metric creates a real Uint64 metric or panics if unable to
|
||||
// do so.
|
||||
func (b *RealMetricBuilder) MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *Uint64Metric {
|
||||
m, err := b.NewUint64Metric(name, sync, pb.MetricMetadata_UNITS_NONE, description, fields...)
|
||||
func (b *RealMetricBuilder) MustCreateNewUint64Metric(name string, metadata Uint64Metadata) *Uint64Metric {
|
||||
m, err := b.NewUint64Metric(name, metadata)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Unable to create metric %q: %s", name, err))
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ import (
|
||||
func TestProfilingMetricsDisabled(t *testing.T) {
|
||||
defer resetTest()
|
||||
|
||||
_, err := SentryProfiling.NewUint64Metric("/counterM", false, pb.MetricMetadata_UNITS_NONE, "One uint64 metric")
|
||||
_, err := SentryProfiling.NewUint64Metric("/counterM", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "one uint64 metric",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ import (
|
||||
func TestProfilingMetricsEnabled(t *testing.T) {
|
||||
defer resetTest()
|
||||
|
||||
_, err := SentryProfiling.NewUint64Metric("/counterM", false, pb.MetricMetadata_UNITS_NONE, "One uint64 metric")
|
||||
_, err := SentryProfiling.NewUint64Metric("/counterM", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "one uint64 metric",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
|
||||
+75
-42
@@ -74,21 +74,37 @@ var (
|
||||
// WeirdnessMetric is a metric with fields created to track the number
|
||||
// of weird occurrences such as time fallback, partial_result, vsyscall
|
||||
// count, watchdog startup timeouts and stuck tasks.
|
||||
WeirdnessMetric = MustCreateNewUint64Metric("/weirdness", true /* sync */, "Increment for weird occurrences of problems such as time fallback, partial result, vsyscalls invoked in the sandbox, watchdog startup timeouts and stuck tasks.",
|
||||
NewField("weirdness_type",
|
||||
&WeirdnessTypeTimeFallback,
|
||||
&WeirdnessTypePartialResult,
|
||||
&WeirdnessTypeVsyscallCount,
|
||||
&WeirdnessTypeWatchdogStuckStartup,
|
||||
&WeirdnessTypeWatchdogStuckTasks,
|
||||
))
|
||||
WeirdnessMetric = MustCreateNewUint64Metric(
|
||||
"/weirdness",
|
||||
Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Sync: true,
|
||||
Description: "Increment for weird occurrences of problems such as time fallback, partial result, vsyscalls invoked in the sandbox, watchdog startup timeouts and stuck tasks.",
|
||||
Fields: []Field{
|
||||
NewField("weirdness_type",
|
||||
&WeirdnessTypeTimeFallback,
|
||||
&WeirdnessTypePartialResult,
|
||||
&WeirdnessTypeVsyscallCount,
|
||||
&WeirdnessTypeWatchdogStuckStartup,
|
||||
&WeirdnessTypeWatchdogStuckTasks,
|
||||
),
|
||||
},
|
||||
})
|
||||
|
||||
// SuspiciousOperationsMetric is a metric with fields created to detect
|
||||
// operations such as opening an executable file to write from a gofer.
|
||||
SuspiciousOperationsMetric = MustCreateNewUint64Metric("/suspicious_operations", true /* sync */, "Increment for suspicious operations such as opening an executable file to write from a gofer.",
|
||||
NewField("operation_type",
|
||||
&SuspiciousOperationsTypeOpenedWriteExecuteFile,
|
||||
))
|
||||
SuspiciousOperationsMetric = MustCreateNewUint64Metric(
|
||||
"/suspicious_operations",
|
||||
Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Sync: true,
|
||||
Description: "Increment for suspicious operations such as opening an executable file to write from a gofer.",
|
||||
Fields: []Field{
|
||||
NewField("operation_type",
|
||||
&SuspiciousOperationsTypeOpenedWriteExecuteFile,
|
||||
),
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
// InitStage is the name of a Sentry initialization stage.
|
||||
@@ -206,6 +222,15 @@ func Disable() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Uint64Metadata is the metadata for a uint64 metric.
|
||||
type Uint64Metadata struct {
|
||||
Cumulative bool
|
||||
Sync bool
|
||||
Unit pb.MetricMetadata_Units
|
||||
Description string
|
||||
Fields []Field
|
||||
}
|
||||
|
||||
type customUint64Metric struct {
|
||||
// metadata describes the metric. It is immutable.
|
||||
metadata *pb.MetricMetadata
|
||||
@@ -510,7 +535,7 @@ func verifyName(name string) error {
|
||||
// - name must be globally unique.
|
||||
// - Initialize/Disable have not been called.
|
||||
// - value is expected to accept exactly len(fields) arguments.
|
||||
func RegisterCustomUint64Metric(name string, cumulative, sync bool, units pb.MetricMetadata_Units, description string, value func(...*FieldValue) uint64, fields ...Field) error {
|
||||
func RegisterCustomUint64Metric(name string, metadata Uint64Metadata, value func(...*FieldValue) uint64) error {
|
||||
if initialized.Load() {
|
||||
return ErrInitializationDone
|
||||
}
|
||||
@@ -523,7 +548,7 @@ func RegisterCustomUint64Metric(name string, cumulative, sync bool, units pb.Met
|
||||
}
|
||||
|
||||
promType := prometheus.TypeGauge
|
||||
if cumulative {
|
||||
if metadata.Cumulative {
|
||||
promType = prometheus.TypeCounter
|
||||
}
|
||||
|
||||
@@ -531,27 +556,27 @@ func RegisterCustomUint64Metric(name string, cumulative, sync bool, units pb.Met
|
||||
metadata: &pb.MetricMetadata{
|
||||
Name: name,
|
||||
PrometheusName: nameToPrometheusName(name),
|
||||
Description: description,
|
||||
Cumulative: cumulative,
|
||||
Sync: sync,
|
||||
Description: metadata.Description,
|
||||
Cumulative: metadata.Cumulative,
|
||||
Sync: metadata.Sync,
|
||||
Type: pb.MetricMetadata_TYPE_UINT64,
|
||||
Units: units,
|
||||
Units: metadata.Unit,
|
||||
},
|
||||
prometheusMetric: &prometheus.Metric{
|
||||
Name: nameToPrometheusName(name),
|
||||
Help: description,
|
||||
Help: metadata.Description,
|
||||
Type: promType,
|
||||
},
|
||||
fields: fields,
|
||||
fields: metadata.Fields,
|
||||
value: value,
|
||||
}
|
||||
|
||||
// Metrics can exist without fields.
|
||||
if l := len(fields); l > 1 {
|
||||
if l := len(metadata.Fields); l > 1 {
|
||||
return fmt.Errorf("%d fields provided, must be <= 1", l)
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
for _, field := range metadata.Fields {
|
||||
allMetrics.uint64Metrics[name].metadata.Fields = append(allMetrics.uint64Metrics[name].metadata.Fields, field.toProto())
|
||||
}
|
||||
return nil
|
||||
@@ -559,8 +584,8 @@ func RegisterCustomUint64Metric(name string, cumulative, sync bool, units pb.Met
|
||||
|
||||
// MustRegisterCustomUint64Metric calls RegisterCustomUint64Metric for metrics
|
||||
// without fields and panics if it returns an error.
|
||||
func MustRegisterCustomUint64Metric(name string, cumulative, sync bool, description string, value func(...*FieldValue) uint64, fields ...Field) {
|
||||
if err := RegisterCustomUint64Metric(name, cumulative, sync, pb.MetricMetadata_UNITS_NONE, description, value, fields...); err != nil {
|
||||
func MustRegisterCustomUint64Metric(name string, metadata Uint64Metadata, value func(...*FieldValue) uint64) {
|
||||
if err := RegisterCustomUint64Metric(name, metadata, value); err != nil {
|
||||
panic(fmt.Sprintf("Unable to register metric %q: %s", name, err))
|
||||
}
|
||||
}
|
||||
@@ -569,11 +594,11 @@ func MustRegisterCustomUint64Metric(name string, cumulative, sync bool, descript
|
||||
// name.
|
||||
//
|
||||
// Metrics must be statically defined (i.e., at init).
|
||||
func NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*Uint64Metric, error) {
|
||||
func NewUint64Metric(name string, metadata Uint64Metadata) (*Uint64Metric, error) {
|
||||
if err := verifyName(name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := newFieldMapper(fields...)
|
||||
f, err := newFieldMapper(metadata.Fields...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -582,7 +607,7 @@ func NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, desc
|
||||
fieldMapper: f,
|
||||
fields: make([]atomicbitops.Uint64, f.numKeys()),
|
||||
}
|
||||
if err := RegisterCustomUint64Metric(name, true /* cumulative */, sync, units, description, m.Value, fields...); err != nil {
|
||||
if err := RegisterCustomUint64Metric(name, metadata, m.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cm := allMetrics.uint64Metrics[name]
|
||||
@@ -593,18 +618,8 @@ func NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, desc
|
||||
|
||||
// MustCreateNewUint64Metric calls NewUint64Metric and panics if it returns
|
||||
// an error.
|
||||
func MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *Uint64Metric {
|
||||
m, err := NewUint64Metric(name, sync, pb.MetricMetadata_UNITS_NONE, description, fields...)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Unable to create metric %q: %s", name, err))
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// MustCreateNewUint64NanosecondsMetric calls NewUint64Metric and panics if it
|
||||
// returns an error.
|
||||
func MustCreateNewUint64NanosecondsMetric(name string, sync bool, description string) *Uint64Metric {
|
||||
m, err := NewUint64Metric(name, sync, pb.MetricMetadata_UNITS_NANOSECONDS, description)
|
||||
func MustCreateNewUint64Metric(name string, metadata Uint64Metadata) *Uint64Metric {
|
||||
m, err := NewUint64Metric(name, metadata)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Unable to create metric %q: %s", name, err))
|
||||
}
|
||||
@@ -646,16 +661,25 @@ func (m *Uint64Metric) forEachNonZero(f func(fieldValues []*FieldValue, value ui
|
||||
}
|
||||
}
|
||||
|
||||
// Increment increments the metric field by 1.
|
||||
// Increment increments the metric by 1.
|
||||
// This must be called with the correct number of field values or it will panic.
|
||||
//
|
||||
//go:nosplit
|
||||
func (m *Uint64Metric) Increment(fieldValues ...*FieldValue) {
|
||||
key := m.fieldMapper.lookupConcat(fieldValues, nil)
|
||||
m.fields[key].Add(1)
|
||||
m.IncrementBy(1, fieldValues...)
|
||||
}
|
||||
|
||||
// Decrement decrements the metric by 1.
|
||||
// This must be called with the correct number of field values or it will panic.
|
||||
//
|
||||
//go:nosplit
|
||||
func (m *Uint64Metric) Decrement(fieldValues ...*FieldValue) {
|
||||
m.IncrementBy(0xFFFFFFFFFFFFFFFF, fieldValues...)
|
||||
}
|
||||
|
||||
// IncrementBy increments the metric by v.
|
||||
// It is also possible to use this function to decrement the metric by using
|
||||
// a two's-complement int64 representation of the negative number to add.
|
||||
// This must be called with the correct number of field values or it will panic.
|
||||
//
|
||||
//go:nosplit
|
||||
@@ -664,6 +688,15 @@ func (m *Uint64Metric) IncrementBy(v uint64, fieldValues ...*FieldValue) {
|
||||
m.fields[key].Add(v)
|
||||
}
|
||||
|
||||
// Set sets the metric to v.
|
||||
// This must be called with the correct number of field values or it will panic.
|
||||
//
|
||||
//go:nosplit
|
||||
func (m *Uint64Metric) Set(v uint64, fieldValues ...*FieldValue) {
|
||||
key := m.fieldMapper.lookupConcat(fieldValues, nil)
|
||||
m.fields[key].Store(v)
|
||||
}
|
||||
|
||||
// Bucketer is an interface to bucket values into finite, distinct buckets.
|
||||
type Bucketer interface {
|
||||
// NumFiniteBuckets is the number of finite buckets in the distribution.
|
||||
|
||||
+41
-10
@@ -100,12 +100,20 @@ func TestVerifyName(t *testing.T) {
|
||||
func TestInitialize(t *testing.T) {
|
||||
defer resetTest()
|
||||
|
||||
_, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
|
||||
_, err := NewUint64Metric("/foo", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: fooDescription,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
|
||||
_, err = NewUint64Metric("/bar", true, pb.MetricMetadata_UNITS_NANOSECONDS, barDescription)
|
||||
_, err = NewUint64Metric("/bar", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Sync: true,
|
||||
Description: barDescription,
|
||||
Unit: pb.MetricMetadata_UNITS_NANOSECONDS,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
@@ -170,7 +178,7 @@ func TestInitialize(t *testing.T) {
|
||||
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)
|
||||
t.Errorf("/bar %+v Sync got false want true", m)
|
||||
}
|
||||
if m.Units != pb.MetricMetadata_UNITS_NANOSECONDS {
|
||||
t.Errorf("/bar %+v Units got %v want %v", m, m.Units, pb.MetricMetadata_UNITS_NANOSECONDS)
|
||||
@@ -211,12 +219,18 @@ func TestInitialize(t *testing.T) {
|
||||
func TestDisable(t *testing.T) {
|
||||
defer resetTest()
|
||||
|
||||
_, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
|
||||
_, err := NewUint64Metric("/foo", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: fooDescription,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
|
||||
_, err = NewUint64Metric("/bar", true, pb.MetricMetadata_UNITS_NONE, barDescription)
|
||||
_, err = NewUint64Metric("/bar", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: barDescription,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
@@ -247,12 +261,18 @@ func TestDisable(t *testing.T) {
|
||||
func TestEmitMetricUpdate(t *testing.T) {
|
||||
defer resetTest()
|
||||
|
||||
foo, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
|
||||
foo, err := NewUint64Metric("/foo", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: fooDescription,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
|
||||
_, err = NewUint64Metric("/bar", true, pb.MetricMetadata_UNITS_NONE, barDescription)
|
||||
_, err = NewUint64Metric("/bar", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: barDescription,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
@@ -453,7 +473,11 @@ func TestEmitMetricUpdateWithFields(t *testing.T) {
|
||||
)
|
||||
field := NewField("weirdness_type", &weird1, &weird2)
|
||||
|
||||
counter, err := NewUint64Metric("/weirdness", false, pb.MetricMetadata_UNITS_NONE, counterDescription, field)
|
||||
counter, err := NewUint64Metric("/weirdness", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: counterDescription,
|
||||
Fields: []Field{field},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err %v want nil", err)
|
||||
}
|
||||
@@ -581,7 +605,10 @@ func TestMetricUpdateStageTiming(t *testing.T) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
})
|
||||
|
||||
fooMetric, err := NewUint64Metric("/foo", false, pb.MetricMetadata_UNITS_NONE, fooDescription)
|
||||
fooMetric, err := NewUint64Metric("/foo", Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: fooDescription,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot register /foo: %v", err)
|
||||
}
|
||||
@@ -1093,7 +1120,11 @@ func TestMetricProfiling(t *testing.T) {
|
||||
|
||||
metrics := make([]*Uint64Metric, numMetrics)
|
||||
for i, m := range test.metricNames {
|
||||
newMetric, err := NewUint64Metric(m, true, pb.MetricMetadata_UNITS_NANOSECONDS, fooDescription)
|
||||
newMetric, err := NewUint64Metric(m, Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Sync: true,
|
||||
Description: fooDescription,
|
||||
})
|
||||
metrics[i] = newMetric
|
||||
if err != nil {
|
||||
t.Fatalf("NewUint64Metric got err '%v' want nil", err)
|
||||
|
||||
@@ -8,5 +8,8 @@ go_library(
|
||||
name = "fsmetric",
|
||||
srcs = ["fsmetric.go"],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = ["//pkg/metric"],
|
||||
deps = [
|
||||
"//pkg/metric",
|
||||
"//pkg/metric:metric_go_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/metric"
|
||||
metricpb "gvisor.dev/gvisor/pkg/metric/metric_go_proto"
|
||||
)
|
||||
|
||||
// RecordWaitTime enables the ReadWait, GoferReadWait9P, GoferReadWaitHost, and
|
||||
@@ -31,27 +32,80 @@ var RecordWaitTime = false
|
||||
|
||||
// Metrics that apply to all filesystems.
|
||||
var (
|
||||
Opens = metric.MustCreateNewUint64Metric("/fs/opens", false /* sync */, "Number of file opens.")
|
||||
Reads = metric.MustCreateNewUint64Metric("/fs/reads", false /* sync */, "Number of file reads.")
|
||||
ReadWait = metric.MustCreateNewUint64NanosecondsMetric("/fs/read_wait", false /* sync */, "Time waiting on file reads, in nanoseconds.")
|
||||
Opens = metric.MustCreateNewUint64Metric("/fs/opens",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of file opens.",
|
||||
})
|
||||
Reads = metric.MustCreateNewUint64Metric("/fs/reads", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of file reads.",
|
||||
})
|
||||
ReadWait = metric.MustCreateNewUint64Metric("/fs/read_wait", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Time waiting on file reads, in nanoseconds.",
|
||||
Unit: metricpb.MetricMetadata_UNITS_NANOSECONDS,
|
||||
})
|
||||
)
|
||||
|
||||
// Metrics that only apply to fs/gofer and fsimpl/gofer.
|
||||
var (
|
||||
GoferOpens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p", false /* sync */, "Number of times a file was opened from a gofer and did not have a host file descriptor.")
|
||||
GoferOpensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host", false /* sync */, "Number of times a file was opened from a gofer and did have a host file descriptor.")
|
||||
GoferReads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p", false /* sync */, "Number of 9P file reads from a gofer.")
|
||||
GoferReadWait9P = metric.MustCreateNewUint64NanosecondsMetric("/gofer/read_wait_9p", false /* sync */, "Time waiting on 9P file reads from a gofer, in nanoseconds.")
|
||||
GoferReadsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host", false /* sync */, "Number of host file reads from a gofer.")
|
||||
GoferReadWaitHost = metric.MustCreateNewUint64NanosecondsMetric("/gofer/read_wait_host", false /* sync */, "Time waiting on host file reads from a gofer, in nanoseconds.")
|
||||
GoferOpens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of times a file was opened from a gofer and did not have a host file descriptor.",
|
||||
})
|
||||
GoferOpensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of times a file was opened from a gofer and did have a host file descriptor.",
|
||||
})
|
||||
GoferReads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of 9P file reads from a gofer.",
|
||||
})
|
||||
GoferReadWait9P = metric.MustCreateNewUint64Metric("/gofer/read_wait_9p", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Time waiting on 9P file reads from a gofer, in nanoseconds.",
|
||||
Unit: metricpb.MetricMetadata_UNITS_NANOSECONDS,
|
||||
})
|
||||
GoferReadsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of host file reads from a gofer.",
|
||||
})
|
||||
GoferReadWaitHost = metric.MustCreateNewUint64Metric("/gofer/read_wait_host",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Time waiting on host file reads from a gofer, in nanoseconds.",
|
||||
Unit: metricpb.MetricMetadata_UNITS_NANOSECONDS,
|
||||
})
|
||||
)
|
||||
|
||||
// Metrics that only apply to fs/tmpfs and fsimpl/tmpfs.
|
||||
var (
|
||||
TmpfsOpensRO = metric.MustCreateNewUint64Metric("/in_memory_file/opens_ro", false /* sync */, "Number of times an in-memory file was opened in read-only mode.")
|
||||
TmpfsOpensW = metric.MustCreateNewUint64Metric("/in_memory_file/opens_w", false /* sync */, "Number of times an in-memory file was opened in write mode.")
|
||||
TmpfsReads = metric.MustCreateNewUint64Metric("/in_memory_file/reads", false /* sync */, "Number of in-memory file reads.")
|
||||
TmpfsReadWait = metric.MustCreateNewUint64NanosecondsMetric("/in_memory_file/read_wait", false /* sync */, "Time waiting on in-memory file reads, in nanoseconds.")
|
||||
TmpfsOpensRO = metric.MustCreateNewUint64Metric("/in_memory_file/opens_ro",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of times an in-memory file was opened in read-only mode.",
|
||||
})
|
||||
TmpfsOpensW = metric.MustCreateNewUint64Metric("/in_memory_file/opens_w",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of times an in-memory file was opened in write mode.",
|
||||
})
|
||||
TmpfsReads = metric.MustCreateNewUint64Metric("/in_memory_file/reads",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Number of in-memory file reads.",
|
||||
})
|
||||
TmpfsReadWait = metric.MustCreateNewUint64Metric("/in_memory_file/read_wait",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Time waiting on in-memory file reads, in nanoseconds.",
|
||||
Unit: metricpb.MetricMetadata_UNITS_NANOSECONDS,
|
||||
})
|
||||
)
|
||||
|
||||
// StartReadWait indicates the beginning of a file read.
|
||||
|
||||
@@ -28,8 +28,14 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sync"
|
||||
)
|
||||
|
||||
var totalTicks = metric.MustCreateNewUint64Metric("/memory_events/ticks", false /*sync*/, "Total number of memory event periods that have elapsed since startup.")
|
||||
var totalEvents = metric.MustCreateNewUint64Metric("/memory_events/events", false /*sync*/, "Total number of memory events emitted.")
|
||||
var totalTicks = metric.MustCreateNewUint64Metric("/memory_events/ticks", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Total number of memory event periods that have elapsed since startup.",
|
||||
})
|
||||
var totalEvents = metric.MustCreateNewUint64Metric("/memory_events/events", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Total number of memory events emitted.",
|
||||
})
|
||||
|
||||
// MemoryEvents describes the configuration for the global memory event emitter.
|
||||
type MemoryEvents struct {
|
||||
|
||||
@@ -392,7 +392,15 @@ func RegisterSyscallTable(s *SyscallTable) {
|
||||
unimplementedSyscallNumbers[i] = []*metric.FieldValue{s}
|
||||
}
|
||||
allowedValues[len(allowedValues)-1] = outOfRangeSyscallNumber[0]
|
||||
unimplementedSyscallCounter = metric.MustCreateNewUint64Metric("/unimplemented_syscalls", true, "Number of times the application tried to call an unimplemented syscall, broken down by syscall number", metric.NewField("sysno", allowedValues...))
|
||||
unimplementedSyscallCounter = metric.MustCreateNewUint64Metric("/unimplemented_syscalls",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Sync: true,
|
||||
Description: "Number of times the application tried to call an unimplemented syscall, broken down by syscall number",
|
||||
Fields: []metric.Field{
|
||||
metric.NewField("sysno", allowedValues...),
|
||||
},
|
||||
})
|
||||
})
|
||||
s.Init()
|
||||
}
|
||||
|
||||
@@ -617,12 +617,18 @@ var (
|
||||
// syscallCounter is a metric that tracks how many syscalls the sentry has
|
||||
// executed.
|
||||
syscallCounter = metric.SentryProfiling.MustCreateNewUint64Metric(
|
||||
"/task/syscalls", false, "The number of syscalls the sentry has executed for the user.")
|
||||
"/task/syscalls", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of syscalls the sentry has executed for the user.",
|
||||
})
|
||||
|
||||
// faultCounter is a metric that tracks how many faults the sentry has had to
|
||||
// handle.
|
||||
faultCounter = metric.SentryProfiling.MustCreateNewUint64Metric(
|
||||
"/task/faults", false, "The number of faults the sentry has handled.")
|
||||
"/task/faults", metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of faults the sentry has handled.",
|
||||
})
|
||||
)
|
||||
|
||||
func (t *Task) savePtraceTracer() *Task {
|
||||
|
||||
@@ -115,28 +115,50 @@ var (
|
||||
// hostExitCounter is a metric that tracks how many times the sentry
|
||||
// performed a host to guest world switch.
|
||||
hostExitCounter = KVMProfiling.MustCreateNewUint64Metric(
|
||||
"/kvm/host_exits", false, "The number of times the sentry performed a host to guest world switch.")
|
||||
"/kvm/host_exits",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of times the sentry performed a host to guest world switch.",
|
||||
})
|
||||
|
||||
// userExitCounter is a metric that tracks how many times the sentry has
|
||||
// had an exit from userspace. Analogous to vCPU.userExits.
|
||||
userExitCounter = KVMProfiling.MustCreateNewUint64Metric(
|
||||
"/kvm/user_exits", false, "The number of times the sentry has had an exit from userspace.")
|
||||
"/kvm/user_exits",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of times the sentry has had an exit from userspace.",
|
||||
})
|
||||
|
||||
// interruptCounter is a metric that tracks how many times execution returned
|
||||
// to the KVM host to handle a pending signal.
|
||||
interruptCounter = KVMProfiling.MustCreateNewUint64Metric(
|
||||
"/kvm/interrupts", false, "The number of times the signal handler was invoked.")
|
||||
"/kvm/interrupts",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of times the signal handler was invoked.",
|
||||
})
|
||||
|
||||
// mmapCallCounter is a metric that tracks how many times the function
|
||||
// seccompMmapSyscall has been called.
|
||||
mmapCallCounter = KVMProfiling.MustCreateNewUint64Metric(
|
||||
"/kvm/mmap_calls", false, "The number of times seccompMmapSyscall has been called.")
|
||||
"/kvm/mmap_calls",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of times seccompMmapSyscall has been called.",
|
||||
})
|
||||
|
||||
// getVCPUCounter is a metric that tracks how many times different paths of
|
||||
// machine.Get() are triggered.
|
||||
getVCPUCounter = KVMProfiling.MustCreateNewUint64Metric(
|
||||
"/kvm/get_vcpu", false, "The number of times that machine.Get() was called, split by path the function took.",
|
||||
metric.NewField("acquisition_type", &getVCPUAcquisitionFastReused, &getVCPUAcquisitionReused, &getVCPUAcquisitionUnused, &getVCPUAcquisitionStolen))
|
||||
"/kvm/get_vcpu",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "The number of times that machine.Get() was called, split by path the function took.",
|
||||
Fields: []metric.Field{
|
||||
metric.NewField("acquisition_type", &getVCPUAcquisitionFastReused, &getVCPUAcquisitionReused, &getVCPUAcquisitionUnused, &getVCPUAcquisitionStolen),
|
||||
},
|
||||
})
|
||||
|
||||
// asInvalidateDuration are durations of calling addressSpace.invalidate().
|
||||
asInvalidateDuration = KVMProfiling.MustCreateNewTimerMetric("/kvm/address_space_invalidate",
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/metric"
|
||||
)
|
||||
|
||||
// This file contains all logic related to context switch latency metrics.
|
||||
@@ -569,23 +570,23 @@ func sentryOnStubOn(s *fastPathState) {
|
||||
|
||||
// Profiling metrics intended for debugging purposes.
|
||||
var (
|
||||
numTimesSentryFastPathDisabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesSentryFastPathDisabled", false, "")
|
||||
numTimesSentryFastPathEnabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesSentryFastPathEnabled", false, "")
|
||||
numTimesStubFastPathDisabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesStubFastPathDisabled", false, "")
|
||||
numTimesStubFastPathEnabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesStubFastPathEnabled", false, "")
|
||||
numTimesStubKicked = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesStubKicked", false, "")
|
||||
numTimesSentryFastPathDisabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesSentryFastPathDisabled", metric.Uint64Metadata{Cumulative: true})
|
||||
numTimesSentryFastPathEnabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesSentryFastPathEnabled", metric.Uint64Metadata{Cumulative: true})
|
||||
numTimesStubFastPathDisabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesStubFastPathDisabled", metric.Uint64Metadata{Cumulative: true})
|
||||
numTimesStubFastPathEnabled = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesStubFastPathEnabled", metric.Uint64Metadata{Cumulative: true})
|
||||
numTimesStubKicked = SystrapProfiling.MustCreateNewUint64Metric("/systrap/numTimesStubKicked", metric.Uint64Metadata{Cumulative: true})
|
||||
|
||||
stubLatWithin1kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin1kUS", false, "")
|
||||
stubLatWithin5kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin5kUS", false, "")
|
||||
stubLatWithin10kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin10kUS", false, "")
|
||||
stubLatWithin20kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin20kUS", false, "")
|
||||
stubLatWithin40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin40kUS", false, "")
|
||||
stubLatGreater40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatGreater40kUS", false, "")
|
||||
stubLatWithin1kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin1kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
stubLatWithin5kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin5kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
stubLatWithin10kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin10kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
stubLatWithin20kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin20kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
stubLatWithin40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatWithin40kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
stubLatGreater40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/stubLatGreater40kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
|
||||
sentryLatWithin1kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin1kUS", false, "")
|
||||
sentryLatWithin5kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin5kUS", false, "")
|
||||
sentryLatWithin10kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin10kUS", false, "")
|
||||
sentryLatWithin20kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin20kUS", false, "")
|
||||
sentryLatWithin40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin40kUS", false, "")
|
||||
sentryLatGreater40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatGreater40kUS", false, "")
|
||||
sentryLatWithin1kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin1kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
sentryLatWithin5kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin5kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
sentryLatWithin10kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin10kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
sentryLatWithin20kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin20kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
sentryLatWithin40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatWithin40kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
sentryLatGreater40kUS = SystrapProfiling.MustCreateNewUint64Metric("/systrap/sentryLatGreater40kUS", metric.Uint64Metadata{Cumulative: true})
|
||||
)
|
||||
|
||||
@@ -33,7 +33,11 @@ var (
|
||||
sessions = make(map[string]*State)
|
||||
)
|
||||
|
||||
var sessionCounter = metric.MustCreateNewUint64Metric("/trace/sessions_created", false /* sync */, "Counts the number of trace sessions created.")
|
||||
var sessionCounter = metric.MustCreateNewUint64Metric("/trace/sessions_created",
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: "Counts the number of trace sessions created.",
|
||||
})
|
||||
|
||||
// SessionConfig describes a new session configuration. A session consists of a
|
||||
// set of points to be enabled and sinks where the points are sent to.
|
||||
|
||||
@@ -80,13 +80,21 @@ func statCounterValue(cm *tcpip.StatCounter) func(...*metric.FieldValue) uint64
|
||||
|
||||
func mustCreateMetric(name, description string) *tcpip.StatCounter {
|
||||
var cm tcpip.StatCounter
|
||||
metric.MustRegisterCustomUint64Metric(name, true /* cumulative */, false /* sync */, description, statCounterValue(&cm))
|
||||
metric.MustRegisterCustomUint64Metric(name,
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Description: description,
|
||||
}, statCounterValue(&cm))
|
||||
return &cm
|
||||
}
|
||||
|
||||
func mustCreateGauge(name, description string) *tcpip.StatCounter {
|
||||
var cm tcpip.StatCounter
|
||||
metric.MustRegisterCustomUint64Metric(name, false /* cumulative */, false /* sync */, description, statCounterValue(&cm))
|
||||
metric.MustRegisterCustomUint64Metric(name,
|
||||
metric.Uint64Metadata{
|
||||
Cumulative: false,
|
||||
Description: description,
|
||||
}, statCounterValue(&cm))
|
||||
return &cm
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,11 @@ func TestMetricsvizCLI(t *testing.T) {
|
||||
t.Fatalf("Failed to find metricsviz_cli: %v", err)
|
||||
}
|
||||
const testMetricName = "/metricsviz_cli_test/counter"
|
||||
testMetric := metric.MustCreateNewUint64Metric(testMetricName, true, fmt.Sprintf("test counter for %s", t.Name()))
|
||||
testMetric := metric.MustCreateNewUint64Metric(testMetricName, metric.Uint64Metadata{
|
||||
Cumulative: true,
|
||||
Sync: true,
|
||||
Description: fmt.Sprintf("test counter for %s", t.Name()),
|
||||
})
|
||||
if err := metric.Initialize(); err != nil {
|
||||
t.Fatalf("Failed to initialize metrics: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user