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:
Etienne Perot
2024-06-26 17:41:24 -07:00
committed by gVisor bot
parent 89ae593e2a
commit abde965590
15 changed files with 302 additions and 106 deletions
+16 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+4 -1
View File
@@ -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",
],
)
+67 -13
View File
@@ -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.
+8 -2
View File
@@ -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 {
+9 -1
View File
@@ -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()
}
+8 -2
View File
@@ -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 {
+28 -6
View File
@@ -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",
+18 -17
View File
@@ -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})
)
+5 -1
View File
@@ -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.
+10 -2
View File
@@ -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)
}